I'm working with the DK-LM3S9B96 dev kit, doing some performance testing to qualify our expected usage of a similar MCU. (dev kit contains the Stellaris LM3S9B96)
I am running into an unexpected limitation with the SSI.
I have configured the MCU to run with a system clock of 80MHz.
Then configured SSI0 to run at a clock frequency of 40MHz (the max speed possible using the 80MHz system clock).
With these tweaks to the QuickStart application that was provided with the dev kit, I am unable to properly read the SPI Flash on the board. Using CCS debugger, I can see that the data I expect to read in is shifted by 1 bit. (NOTE: If I configure the SSI0 to run at 20MHz and 10MHz, the SPI Flash reads work fine.) I should also point out that this dev kit QuickStart app is configuring the SSI in Freescale mode with SPO=0 and SPH=0.
It seems like the max speed of 40MHz might work well for output-only interfaces (for examples a SPI DAC)... but for devices that need to be read, I'm sensing that it may be impossible to meet the setup/hold times.
Can someone confirm this, or explain what I'm missing? Thanks.
Chris,
I'm looking into this. Can you tell me specifically what lines you modified in what files when setting up the SSI to run at 20Mhz?
- Ken
Here is a summary of the changes I've made.
1) To increase system clock to 80MHz, I changed the SysCtlClockSet() call in main() in qs-checkout.c as follows:
SysCtlClockSet(SYSCTL_SYSDIV_3 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); 2) The increase to 80MHz broke the SDRAM interface, but I tracked that down to a problem with the EPI clock divider at this higher speed and fixed that by changing the SDRAMInit() call in main() in qs-checkout.c as follows: SDRAMInit(1, (EPI_SDRAM_CORE_FREQ_50_100 | EPI_SDRAM_FULL_POWER | EPI_SDRAM_SIZE_64MBIT), 1024); 3) To change the SSI clock rate, I changed the SSIConfigSetExpClk() call in SSIFlashInit() in drivers/ssiflash.c as follows: SSIConfigSetExpClk(SFLASH_SSI_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 40000000, 8); In the above changes, the result is a 40MHz SPI clock rate, which does not appear to work. To try the lower rates, I just changed the 40000000 parameter in the 3rd change above. Now, my testing is using the Winbond SPI Flash that is provided on the Dev Kit. I've used an oscilloscope to verify the clock frequency and to observe the MISO and MOSI signals relative to that clock. Also, to focus on a predictable result, I used the debugger to do the following: a) Set a breakpoint at the call to SSIFlashInstructionWrite() in SSIFlashRead() in drivers/ssiflash.c b) Set a breakpoint at the return in the SSIFlashRead() function. c) Reload app d) Run to first breakpoint e) Setup scope to look at the CLK, MOSI, MISO f) Run to second breakpoint to perform read and capture it on the scope. The read being performed is the first 8-bytes of the Flash, looking for file-system information, so it should always be producing the same thing. And when it gets garbage, the application (if allowed to continue without breakpoints set) does not find any image files when selecting the touch-screen option to view images. If you have this same dev kit available, this should be a relatively quick thing to test and confirm (or deny) the results that I'm getting. Thanks!
SysCtlClockSet(SYSCTL_SYSDIV_3 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
2) The increase to 80MHz broke the SDRAM interface, but I tracked that down to a problem with the EPI clock divider at this higher speed and fixed that by changing the SDRAMInit() call in main() in qs-checkout.c as follows:
SDRAMInit(1, (EPI_SDRAM_CORE_FREQ_50_100 | EPI_SDRAM_FULL_POWER | EPI_SDRAM_SIZE_64MBIT), 1024); 3) To change the SSI clock rate, I changed the SSIConfigSetExpClk() call in SSIFlashInit() in drivers/ssiflash.c as follows: SSIConfigSetExpClk(SFLASH_SSI_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 40000000, 8); In the above changes, the result is a 40MHz SPI clock rate, which does not appear to work. To try the lower rates, I just changed the 40000000 parameter in the 3rd change above. Now, my testing is using the Winbond SPI Flash that is provided on the Dev Kit. I've used an oscilloscope to verify the clock frequency and to observe the MISO and MOSI signals relative to that clock. Also, to focus on a predictable result, I used the debugger to do the following: a) Set a breakpoint at the call to SSIFlashInstructionWrite() in SSIFlashRead() in drivers/ssiflash.c b) Set a breakpoint at the return in the SSIFlashRead() function. c) Reload app d) Run to first breakpoint e) Setup scope to look at the CLK, MOSI, MISO f) Run to second breakpoint to perform read and capture it on the scope. The read being performed is the first 8-bytes of the Flash, looking for file-system information, so it should always be producing the same thing. And when it gets garbage, the application (if allowed to continue without breakpoints set) does not find any image files when selecting the touch-screen option to view images. If you have this same dev kit available, this should be a relatively quick thing to test and confirm (or deny) the results that I'm getting. Thanks!
SDRAMInit(1, (EPI_SDRAM_CORE_FREQ_50_100 | EPI_SDRAM_FULL_POWER | EPI_SDRAM_SIZE_64MBIT), 1024);
3) To change the SSI clock rate, I changed the SSIConfigSetExpClk() call in SSIFlashInit() in drivers/ssiflash.c as follows:
SSIConfigSetExpClk(SFLASH_SSI_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 40000000, 8); In the above changes, the result is a 40MHz SPI clock rate, which does not appear to work. To try the lower rates, I just changed the 40000000 parameter in the 3rd change above. Now, my testing is using the Winbond SPI Flash that is provided on the Dev Kit. I've used an oscilloscope to verify the clock frequency and to observe the MISO and MOSI signals relative to that clock. Also, to focus on a predictable result, I used the debugger to do the following: a) Set a breakpoint at the call to SSIFlashInstructionWrite() in SSIFlashRead() in drivers/ssiflash.c b) Set a breakpoint at the return in the SSIFlashRead() function. c) Reload app d) Run to first breakpoint e) Setup scope to look at the CLK, MOSI, MISO f) Run to second breakpoint to perform read and capture it on the scope. The read being performed is the first 8-bytes of the Flash, looking for file-system information, so it should always be producing the same thing. And when it gets garbage, the application (if allowed to continue without breakpoints set) does not find any image files when selecting the touch-screen option to view images. If you have this same dev kit available, this should be a relatively quick thing to test and confirm (or deny) the results that I'm getting. Thanks!
SSIConfigSetExpClk(SFLASH_SSI_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 40000000, 8);
In the above changes, the result is a 40MHz SPI clock rate, which does not appear to work. To try the lower rates, I just changed the 40000000 parameter in the 3rd change above.
Now, my testing is using the Winbond SPI Flash that is provided on the Dev Kit. I've used an oscilloscope to verify the clock frequency and to observe the MISO and MOSI signals relative to that clock. Also, to focus on a predictable result, I used the debugger to do the following:
a) Set a breakpoint at the call to SSIFlashInstructionWrite() in SSIFlashRead() in drivers/ssiflash.c
b) Set a breakpoint at the return in the SSIFlashRead() function.
c) Reload app
d) Run to first breakpoint
e) Setup scope to look at the CLK, MOSI, MISO
f) Run to second breakpoint to perform read and capture it on the scope.
The read being performed is the first 8-bytes of the Flash, looking for file-system information, so it should always be producing the same thing. And when it gets garbage, the application (if allowed to continue without breakpoints set) does not find any image files when selecting the touch-screen option to view images.
If you have this same dev kit available, this should be a relatively quick thing to test and confirm (or deny) the results that I'm getting.
Thanks!
I will try to repro this. One setting you have wrong for 80Mhz is the following.
Chris DumsSysCtlClockSet(SYSCTL_SYSDIV_3 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
You need to be using SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ)
Please make sure you are working with the latest StellarisWare release from the TI website.
Ken,
Good catch. I was using the SYSCTL_SYSDIV_2_5 setting when doing my 80MHz testing.
Since then, I've been experimenting with other system clock rates, so what I provided above is just a copy-paste problem... I copied what is in my current code and neglected to change it to the 80MHz setting.
-Chris
I'm sorry to hijack this thread. But I think I am experiencing the same problem in my applications. Devices used lm3s1960 and lm3s3748. When using the SSI at maximum speed it is difficult to clock in correct data that is not one bit shifted.
Test setup 1: lm3s3748a0, crystal 8Mhz, PLL set-up and confirmed to run at 40Mhz. SPI device on SSI port 0 (master mode), AD7691 ADC. SPI device on SSI port 1 (master mode), ET1100 EtherCAT slave. Both devices operating in SPO=1 SPH=1, SSIclk set at 20Mhz (div =2). AD7691 is working fine, ET1100 has SSIRx bits offset by one, SSITx bits are fine (confirmed in device memory).
It looks like the 3748 is sampling SSIRx too early. Timing is checked by a logic analyser and digital scope. Both devices and 3784 have clean signals with low rise and fall times, no ringing. The AD7691 sets up its SDO signal early (but within SPI spec) and the ET1100 late (approx 8-11ns after SSIClk edge, well within SPI spec).
Test setup 2: lm3s3748a0, crystal 8Mhz, PLL set-up and confirmed to run at 40Mhz. Both devices operating in SPO=1 SPH=1, SSIclk set at 10Mhz (div =4). AD7691 is working fine, ET1100 is working fine too.
Test setup 3: lm3s3748a0, crystal 8Mhz, PLL set-up and confirmed to run at 20Mhz. Both devices operating in SPO=1 SPH=1, SSIclk set at 10Mhz (div =2). AD7691 is working fine, ET1100 has SSIRx bits offset by one.
Setup 2 and 3 are intended to find out if there is a prblem with the SSIclk frequency or the divisor. It seems to be the divisor that is giving the problems. I have further tested with other divisor settings. All are OK except div = 2.
If the ET1100 is sending 0b10101010 the byte received is 0bx1010101. Sequences of multiple bytes carry the last bit of a byte into the first of the next byte. It doesn't matter if the bits are continuous or there is a deliberate delay between each byte.
-Arthur
I am continuing to investigate this. I have reproduced what you are seeing. I have also confirmed operation if the system clock is running at 50Mhz (SYSCTL_SYSDIV_4) and the SSI clock is set to 25Mhz so it is not the fact that the SPI clock is 1/2 of sysclk that is the problem but something also related to frequency.
Ken
Here's a random thought for you. The dev kit that I have has silicon rev B1 on it (I assume, if you have this dev kit, it has the same rev since we just purchased ours). In looking at the errata for B1, there is problem regarding the use of the internal Flash at greater than 50MHz system clock. There is no indication why, but presumably some internal timing problem which was apparently addressed in later revs. I realize the Flash and the SSI are different peripherals, so this is a stretch, but maybe that timing issue was more pervasive that just Flash timing. I'd be curious to know if the SSI behavior above 50MHz system clock is different with newer revs of silicon.
Chris
This issue is not related to what was caused the errata for B1. Also later revisions of the device that fix the Flash errata still show the issues with SSI frequency above 25Mhz (sysclk 50Mhz). This is being further investigated internally and I will let you know when I have more information.
Hello Ken,
We need to start moving forward with this SSI interface on our end. I can only assume that the internal investigation will likely confirm the 25MHz limitation and proceed to characterize the actual limitation. Do you have a feel for where this is heading? If you're on the verge of a break-through and 40MHz will work with a non-obvious register setting, then I'll wait. But otherwise, we need to re-do our SSI bandwidth estimates with the slower rate and figure out how to accomodate the 2x reduction. (We'll probably still need to run sys-clock at 80MHz for general processing speed reasons, so our SSI will drop to 20MHz. I do realize we could drop sys-clock to 50MHz and subsequently boost the SSI from 20MHz to 25MHz, but right now I don't have a feel for where the greater need will be.)
Hi Chris,
IC Design has confirmed that due to a limitation with the I/O of the SSI module, the maximum speed for the SSI interface when operating as a master is 1/2 the system clock, but no greater than 25 MHz. The data sheet will be updated to reflect this change. I'm sorry for the inconvenience.
Regards,
Sue
Has anyone gotten SSI in master mode to read correctly at 25MHz (max) without the data being shifted by 1 bit? I set up my system clock to run at 50MHz. Testing SSI at 12.5MHz read back is fine.
Wow... just ran into this same problem... 2 YEARS later. LM3S9D92 dev kit. The datasheet for this part was NOT updated. Um... thanks. Perhaps you should get on that data sheet corrected now.
We selected this part BECAUSE of the supposed 40 MHz SPI speed. I really hope we can meet timing constraints at 25 MHz.
Hi Ryan,
I'm sorry for your frustration, but I wanted to point out that this limitation is clearly detailed in the current data sheet as shown below:
I'm more than 90% sure this information has been included in the data sheet since it was first published.
Sue,
It would have also be really great to include that critical information in the Electrical Characteristics section, where all the other timing constraints are also displayed. Without reading that entire note, one would reasonably believe that table 26.14 would mean that the Stellaris would be able to read SSI input at SysClk/2.
This asymmetry in usable read/write speeds is non-intuitive, since we now know from our own experience that the Stellaris can write at 40 MHz but for some reason receives a bit-shifted response at anything faster than 20 MHz. We have not been able to successfully receive data at 25 MHz, though our slave device can read/write at 40 MHz and the received waveform timing is clean.
We lucked out that the write to slave is the bottleneck for our particular application, but in the future I'm going to be much more nervous about selecting TI parts. Just my feedback on the issue.
I agree these specs are not as clear as they could be, but S1 does provide that crucial piece of information. 40 ns is the minimum SSIClk cycle time and thus 25 MHz is the max frequency.