2017-08-20 06:58 PM
Surely this issue has been beaten to death already?
SPI3:
Are there any known 'end of byte/word transmit' function (soft/hardware)working on SPI3 in master mode? Actually in 'any' mode, im just doing
simple plain periodic (plenty of dead time in between transmits, not
constant that would hold BSY low) transmit with no interference (i hope)
of NSS/SSI crap, only GPIO pin as strobe for external shift register.
I cant detect any SPI BSY being set during transmission as it should be!
Is there any specific setup flow and init of SPI logic needed?
SPI3->DR = ledbuff; //Write SPI transmit reg
while((SPI3->SR & SPI_SR_TXE) == 0) //Test until TXE flag is 1{}while((SPI3->SR & SPI_SR_BSY) == 1) //Test until Busy flag is 0{}
According to errata for rev A of F446 and rev11 for F429 there are complexbugs in SPI module and equal complex suggestions for workarounds thatapparently dont work ,BSY mentioned.Is there a workaround that one could use RXNE (MISO-MOSI loopback)
or something else as a detector?
Contemplating use USART instead since it works out of the box by detecting
TC flag unfortunately USART's in synchronous mode is much slower then SPI.2017-08-26 07:58 AM
That == 1 is not the right test for the bit mask chosen, != 0 would work
2017-08-27 02:55 PM
Sorry to say but that (not equal to zero) is as stone dead as my ==1
//Test until Busy flag is 0
>>>Um, SPI_SR_BSY is 0x80, not 0x01.
Hum, what's this 0x80? It's address?
Then this ST manufactured code also wrong?
while((RCC->CR & RCC_CR_PLLRDY) == 0) {}2017-08-27 06:31 PM
Right, had completely forgot , thanks Clive and Vangelis!
Late night edit:
Went back to SPI and spoked around a bit more why
while((SPI3->SR & SPI_SR_BSY) !=0) {} //Test BSY if it's 1, if 0 then exit test.
didnt work and pondered if there is some kind of delay issues with BSY
(errata talks about sync issues with internal buses) or the cpu is to quickto test BSY and sure enough 12 nop's is what it took to detect BSY.
asm('nop; '); // nop instruction as delay
asm('nop; '); // nop instruction as delayasm('nop; '); //nop instruction as delayasm('nop; '); //nop instruction as delayasm('nop; '); // nop instruction as delayasm('nop; '); // nop instruction as delayasm('nop; '); // nop instruction as delayasm('nop; '); // nop instruction as delayasm('nop; '); // nop instruction as delayasm('nop; '); // nop instruction as delayasm('nop; '); // nop instruction as delayasm('nop; '); // nop instruction as delaywhile((SPI3->SR & SPI_SR_BSY) !=0) {} //Test BSY if it's 1, if 0 then exit test.or 2 dummy reads/writes to 'something' also works such as
GPIOC->BSRR = GPIO_BSRR_BR_11; //Set PC11 low, used as delayGPIOC->BSRR = GPIO_BSRR_BR_11; //Set PC11 low, used as delaywhile((SPI3->SR & SPI_SR_BSY) !=0) {} //Test BSY if it's 1, if 0 then exit test.
I noted that detecting BSY is 'SPI clock rate sensitive' nop's bails out if rate
to high while dummy's obviously longer and behaves more like detectingNRXE.Perhaps also why Williams HAL code above works, loads of delays checking
HALs dependencies etc, etc what not's.
2017-08-27 06:51 PM
You're doing a bit wise AND so 0x40 & 0x80 = 0, so a comparison with 0 or not 0 will work
0x80 & 0x80 = 0x80
It is a bit in a register, ie bit 7, or (1 << 7)
2017-08-27 06:52 PM
Hi Mikas!
'while((SPI3->SR & SPI_SR_BSY) == 1) //Test until Busy flag is 0
{}'
At the above code (SPI3->SR & SPI_SR_BSY) is not a logical argument but an arithmetic value.
This means, if this value is not equal to another arithmetic value like 1 the logic ((SPI3->SR & SPI_SR_BSY) == 1) will never be true because 0x0080 or 0x0000 (SR register ANDed with 0x0080) is never equal to one!
In the above comparison (SPI3->SR & SPI_SR_BSY) is an intermediate value stored in a register usualy R0 or R1.
'Then this ST manufactured code also wrong?
while((RCC->CR & RCC_CR_PLLRDY) == 0) {}'This code is not wrong because the intermediate arithmetic value (RCC->CR & RCC_CR_PLLRDY) may be equal to zero when the flag at register RCC_CR is zero.
Regards
vf