cancel
Showing results for 
Search instead for 
Did you mean: 

9bit SPI

tre2020067
Associate II
Posted on October 17, 2011 at 21:30

can i but 9 bits in the SPI Tx buffer configured in 8bit mode and have it still clock out all 9 bits???

17 REPLIES 17
Posted on October 26, 2011 at 16:21

I'd use the core cycle counter, it would have a resolution of 72 MHz (13.89 ns).

Standard conversion of period into frequency

1/150e-9 = 6.667 MHz

Figure also 1 MHz = 1000 ns, thus 1000 / 150 = 6.667

Minimum Period translates to Maximum Frequency, ie smaller period, higher frequency.

The SYSTICK interrupt can be set at any period, within the limit of the hardware. If it's too high you'll just saturate the processor. Personally I'd be looking a 1 KHz (1ms) or 10 KHz (100us) for a SYSTICK driven ticker.

As Erik points out pure software spin loops don't always compile or run in a predictable way. That why you'd want to reference some kind of free running timer.

start = current; // current is a volatile time base

while((current - start) < 1000);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
tre2020067
Associate II
Posted on November 05, 2011 at 08:06

thank you clive1 and erik!

 im going to use the systick timer since its the easiest of the timers to use.

i ran across a systick delay routine and i was wondering how to exactly set the reload value.

the example routine had a reload  value of 9000.

can someone clarify what units of time are entered into the delay and whats going on as far as calculating a delay?

void SysTick_Configuration()

{

  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//SYSTICK?????AHB?1/8

  SysTick_SetReload(9000);//SYSTICK????

  SysTick_CounterCmd(SysTick_Counter_Enable);//??SYSTICK??

  SysTick_ITConfig(ENABLE);

}

void Delay(vu32 nTime)

{

    

  SysTick_CounterCmd(SysTick_Counter_Enable);//??SysTick???

 

  TimingDelay = nTime;

  while(TimingDelay != 0);

 

  SysTick_CounterCmd(SysTick_Counter_Disable);//??SysTick???

 

  SysTick_CounterCmd(SysTick_Counter_Clear);//??SysTick???

}

 

void SysTickHandler(void)

{

    while(TimingDelay!=0)  

    TimingDelay--;

}

Delay(1000);

Posted on November 05, 2011 at 13:45

Well 9000 is for a 1 ms tick, ie (72000000 / 😎 / 9000 = 1000, a frequency of 1 KHz assuming a 72 MHz processor speed.

Personally I wouldn't be enabling disabling SysTick as it is a useful timebase for performing other tasks.

volatile unsigned int ticker; // incremented in systick

void delayms(unsigned int delay) // delay milliseconds, accuracy +/- 1 ms

{

  unsigned int start;

  start = ticker;

  while((ticker-start) < delay);

}

If you want better accuracy, a faster tick can be used. The error here comes for where you catch the counter, ie immediately before/after a tick.

If you want accurate placement, you could also shift out the bits to the GPIO on the SysTick interrupt itself. ie keep a variable of bits to be shifted, and another with the data pattern.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
tre2020067
Associate II
Posted on November 10, 2011 at 07:25

thankyou clive1 for the elxplanation. its been awhile since ive  used that formulas lol.

im having problems phase lock looping the clock so im going to have to calculate a routine based on this.

it seems the stack points to some random address after it returns from waiting for the pll to stablize.

tre2020067
Associate II
Posted on January 09, 2012 at 09:04

I just wanted to update this thread. i WAS able to get the lcd working. i used a bit bang routine and the driver file provided! Thank you Clive1 for the help!

tre2020067
Associate II
Posted on January 09, 2012 at 09:05

also thankyou Erik! 😉

jhegedus
Associate II
Posted on July 26, 2016 at 21:35

I realize this is an old thread, but I came across this problem myself with an HX8340B LCD screen that uses 9-bit (The 9th bit being the data/command bit as the LCD doesn't have a hardwired pin for making the distinction).  I came up with a method that worked out ok by sort of tricking the controller a bit.

I setup the SPI to send only 8-bit, but sent two 8-bit frames that were shifted around a bit to give the necessary 9 bits at the beginning.

So, I setup a send variable, uint8_t data[2].  From there, I shifted the data to send to the screen (Regardless of data/command) over by one bit to the right.  Then, depending on whether it was a command or not, I added the necessary bit in that MSB position (Leaving it 0 or adding in a 1).  In the second variable of the data array, I then took the LSB of the data/command and shifted it left 7 positions so it was now the MSB of the second variable.  This way, when you send [0] and [1] back to back, the LCD saw the necessary 9 bits first and acted accordingly.

I'm not sure if it will work in all situations, but the screen's working just fine using this technique.

Anyhow, again, I know this is old, but someone else might find this of use at some point in time.  At least until they allow 9-bit SPI frames out of the box.

Hope this makes sense; it may sound a little confusing.  🙂

Posted on July 26, 2016 at 22:47

I'm cool with that, people will likely find it still via Google, and it's On Topic...

Other methods could be to use TIM+DMA to GPIO->BSRR and create a pattern buffer for multiple pins doing CLK/DATA.

Since 2011 ST has added to the STM32 family, there are some now supporting more flexible SPI bit sizes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..