Jump to content
43oh

Recommended Posts

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

Link to post
Share on other sites

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.    

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...