This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi All,
I'm back with more questions about setting up the SCI BAUD rate.
In the last episode, I was getting irrational BAUD rates due to the fact that I had the SYSCLK running at 50MHz, but thought it was 40MHz. Correcting that error helped straighten things out, but there still seems to be a kink.
With SYSCLK running at 40MHz (confirmed, reconfirmed, and double checked after that), the BRR value still won't reconcile with the BAUD rate measured at the output.
Here's the path I followed: (SCI code borrowed from Driverlib example code, "Example_F2802xSci_FFDLB.c" on TIREX)
Set SYSCLK to 40MHz:
Using a TMS320F28020 (spec'd at 40MHz) in my target (prototype assembly).
Setting the PLL to multiply by 8 and divide by 2:
// // Setup the PLL for x8 /2 which will yield 40Mhz = 10Mhz * 8 / 2 // PLL_setup(myPll, PLL_Multiplier_8, PLL_DivideSelect_ClkIn_by_2); // 10MHz x (8/2) = 40MHz
With a scope on XCLKOUT, and setting the prescaler to divide by 1 (to match SYSCLK's 40MHz):
// // Setup the clock out prescaler to check SYSCLK frequency at XCLKOUT // CLK_setClkOutPreScaler(myClk, CLK_ClkOutPreScaler_SysClkOut_by_1); // Div by 1 = SYSCLKOUT
Here's the scope image:
So far, so good...
Set LSPCLK to 40MHz using common code function:
Here's where things get weird.
Using the following function, shouldn't LSPCLK run at 40MHz:
// // Setup the LOSPCP to produce 40MHz LSPCLK // CLK_setLowSpdPreScaler(myClk, CLK_LowSpdPreScaler_SysClkOut_by_1);
BUT, when applying a value to BRR, the measure BAUD rate doesn't match what the calculation says it should be. You may want more detail about how I arrived at that, but for now let's focus on the above function.
The value that should be applied to LOSPCP as a result of the above function is zero:
//! \brief Enumeration to define the low speed clock prescaler, which sets the clock frequency //! typedef enum { CLK_LowSpdPreScaler_SysClkOut_by_1=(0 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/1 CLK_LowSpdPreScaler_SysClkOut_by_2=(1 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/2 CLK_LowSpdPreScaler_SysClkOut_by_4=(2 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/4 CLK_LowSpdPreScaler_SysClkOut_by_6=(3 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/6 CLK_LowSpdPreScaler_SysClkOut_by_8=(4 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/8 CLK_LowSpdPreScaler_SysClkOut_by_10=(5 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/10 CLK_LowSpdPreScaler_SysClkOut_by_12=(6 << 0), //!< Denotes Low Speed Clock = SYSCLKOUT/12 CLK_LowSpdPreScaler_SysClkOut_by_14=(7 << 0) //!< Denotes Low Speed Clock = SYSCLKOUT/14 } CLK_LowSpdPreScaler_e;
However, it is instead 0x0002:
By locating the source code for that function, which is found in the TI install directory at this path:
C:\ti\C2000Ware_4_01_00_00\device_support\f2802x\common\source\clk.c
// // CLK_setLowSpdPreScaler - // void CLK_setLowSpdPreScaler(CLK_Handle clkHandle, const CLK_LowSpdPreScaler_e preScaler) { CLK_Obj *clk = (CLK_Obj *)clkHandle; ENABLE_PROTECTED_REGISTER_WRITE_MODE; // // set the bits // clk->LOSPCP |= preScaler; DISABLE_PROTECTED_REGISTER_WRITE_MODE; return; }
The function is OR'ing the prescaler value coming in as the second parameter of the function. Since the default reset value is 0x0002, it would follow that this function could never set LOSPCP to zero or any other value that doesn't include having bit 1 high. Shouldn't the 'or-equals' statement:
// // set the bits // clk->LOSPCP |= preScaler;
be changed to 'equals':
// // set the bits // clk->LOSPCP = preScaler;
or at least 'and-equals':
// // set the bits // clk->LOSPCP &= preScaler;
Question #1:
Is this function correct as it stands, and I am misunderstanding what's going on?
Moving on...
If I change the line of code that calls the function from this:
// // Setup the LOSPCP to produce 40MHz LSPCLK // CLK_setLowSpdPreScaler(myClk, CLK_LowSpdPreScaler_SysClkOut_by_1);
to this:
// // Setup the LOSPCP to produce 40MHz LSPCLK // EALLOW; myClk->LOSPCP = CLK_LowSpdPreScaler_SysClkOut_by_1; EDIS;
then LOSPCP does achieve the value zero, which should setup LSPCLK to be running at 40MHz.
With this configuration, the calculation for BRR works correctly.
Please help me understand.
Thanks,
robin
Hi Robin,
Is this function correct as it stands, and I am misunderstanding what's going on?
Thank you for identifying this. I will ask our software team to make the modification as you pointed out.
Best Regards,
Marlyn