grahamf72 169 Posted May 23, 2014 Share Posted May 23, 2014 I'm just getting started with my Stellaris LP, and am porting my msp430 library for my ILI9341 based display over to the Stellaris. I got it working, but am encountering performance issues. I'm using Energia 12. The ILI9341 is very demanding on the SPI bus. To test the performance I created a simple benchmark that involved filling the display a couple of times. On the MSP430, I was able to get good performance by putting SPI.setClockDivider(1) after SPI.begin(). With this setting, the MSP430F5529 at 25MHz was able to complete my benchmark in 1608mS. Then I ported it to the Stellaris, and instead of getting the faster performance I was expecting, the same benchmark took 73682 mS or about 45 times slower! I discovered in the SPI library, that instead of getting the default speed of 4MHz by starting with 16MHz and then dividing by 4, the SPI library sets the SPI speed to 8MHz. So setting the divisor to 1, should make it still at 8MHz, which I'd expect to be slower than the MSP430, but not by as much as I'm seeing. So then I took out the call to setClockDivider and it sped up substantially. It now ran my benchmark in 1926mS, still slower than the MSP430, but now with acceptable performance. I then tried it with setClockDivider(2) and this was the big surprise, it was now actually faster than without a divider set! But it was still slower than the MSP430. I tried changing the line ROM_SSIConfigSetExpClk in the SPI library to use a 16MHz clock instead of 8MHz, and this improved the performance to the point where it was now slightly faster than the MSP430, and once again the big surprise was that setting a divider of 2 was quicker than having no divider. Once again though, setting a divider of 1 slows everything down to a crawl. So it seems to me there is a bug in the SPI library for the Stellaris. Setting a divider of 1 should have it run at the full SPI clock speed, not much slower. Also, it seems strange that a divider of 2 should be faster than not setting a divider. I must admit I'm still in the early stages of learning the Stellaris, so I don't quite completely know what is happening in the library. Is there a way of configuring the SPI so that it runs at 16MHz or higher? Because it seems that 16MHz with a divisor of 2 means it is only running at 8MHz currently. For those interested, here is a table with the various benchmark times for various configurations. As would be expected, the MSP430 speed scales nicely with the processor speed. Stellaris 8 & Stellaris 16 refer to the SPI frequency set in the SPI.cpp file. 8 is Energia's default as-shipped value. Divider F5529 @ 25 F5529 @ 16 Stellaris8 Stellaris16 None 2487 3183 1926 1551 1 1608 2573 73682 30449 2 1737 2780 1883 1532 4 1989 3183 2408 1883 Quote Link to post Share on other sites
Rei Vilo 695 Posted May 24, 2014 Share Posted May 24, 2014 Hi! This is a known issue. Please refer to TM4C123 and TM4C129: Improve SPI Speed #365 at http://github.com/energia/Energia/issues/365 Quote Link to post Share on other sites
grahamf72 169 Posted May 25, 2014 Author Share Posted May 25, 2014 I finally managed to track down the register documentation for the Stellaris processor (for some reason i couldn't find it on Ti's site), and it all makes sense now. The SPI clock frequency is set by 2 registers - CPSDVSR (Clock Prescaler) & SCR (Serial Clock Rate) by the formula SSI Clock = System Clock / (CPSDVSR * (1 + SCR)) Energia's setClockDivider just sets the Clock Prescaler register. According to the spec's of this register it must be an even number between 2 & 254. The LSB is ignored. Consequently by calling the routine with a divisor of 1, it was actually storing 0 and hence seems to go to some error state - the doc's don't say what happens when this is set to 0. Another limitation is that it won't allow any frequency above 25Mhz for the SPI. Unfortunately it is not possible to achieve the 25MHz maximum SPI speed with a system clock of 80MHz. The following are some of the valid combinations of registers and resulting frequency CPSDVSR SCR FREQ CPSDVSR SCR FREQ 2 1 20MHz 4 0 20MHz 2 2 13MHz 4 1 10MHz 2 3 10MHz 4 3 5MHz 2 4 8MHz 4 4 4MHz 2 7 5MHz 4 9 2MHz 2 9 4MHz 4 19 1MHz 2 15 2.5MHz 2 19 2MHz The function ROM_SSIConfigSetExpClock sets the registers in such a way that you get the frequency closest to the frequency set in that function. Because setting it 16MHz (as suggested in your comment on the github page) is actually impossible, it actually sets the speed to 20MHz. I'd suggest an improvement would be in the config to set the CPSDVSR to 2, and the SCR to 9 to get the default 4Mhz clock. Then in setClockDivider change the SCR rather than the CPSDVSR. reaper7, spirilis and sumotoy 3 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.