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-20 11:13 PM
Don't people use the RXNE flag to indicate the last bit out finished?
2017-08-21 12:45 AM
uint8_t dSPIN_Write_Byte(uint8_t byte)
{ /* Buffer used for transmission */ uint8_t aTxBuffer[] = {0x00}; /* Buffer used for reception */ uint8_t aRxBuffer[] = {0xF};aTxBuffer[0] = byte;
HAL_GPIO_WritePin(dSPIN_nSS_Port, dSPIN_nSS_Pin, 0); HAL_Delay(0.000003); //3000nsif(HAL_SPI_TransmitReceive(&dSPIN_SPI, (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, 1, 250) != HAL_OK)
{ }while (__HAL_SPI_GET_FLAG(&dSPIN_SPI, SPI_FLAG_BSY) != 0);
HAL_GPIO_WritePin(dSPIN_nSS_Port, dSPIN_nSS_Pin, 1);
HAL_Delay(0.0008);
return aRxBuffer[0];
}2017-08-21 11:25 AM
>>>Don't people use the RXNE flag to indicate the last bit out finished?
That's what i thought could work in a
MOSI-MISO loopback l
ast bit of transmit detect
in some modes other then master MOSI only but apparently it's not needed since this
works in
master MOSI only
:SPI3->DR = count; //Write SPI transmit reg with counter value
while((SPI3->SR & SPI_SR_RXNE) == 0) {} //Test RXNE flag is 1GPIOC->BSRR |= GPIO_BSRR_BS_11; //Set PC11 high, strobe signal startGPIOC->BSRR |= GPIO_BSRR_BR_11; //Set PC11 low, strobe signal enddummy = SPI3->DR; //Dummy read SPI RD to clear RXNE flagNote:
CPOL=0 and CPHA=0 , data captured on rising CLK edge.
CLK rate lowest, then PC11 strobe are 2us late after last rising CLK edge
.
CLK rate highest, then PC11 strobe are ca 2uS late after
last falling CLK edge.
Why? Havent investigated and frankly i dont care, wasted
way
to much time
on this crappy/buggy ST SPI design.
But it seams to be enough time for various HC shift registers other CMOS
shifters needs longer/delayed strobe times which can be fixed by adding
software as usual.
>>>
aRxBuffer, 1, 250) != HAL_OK)
Sorry dont use HAL only direct register but
parts of your code is blocking by nature.
Noticed ST seams to have 'redesigned' the SPI module in the upcoming H7, about time!
2017-08-21 02:20 PM
The peripheral is synchronous and symmetrical, same clock moving data in/out, with selectable phase
Don't do this (ie RMW)
GPIOC->BSRR |= GPIO_BSRR_BS_11; //Set PC11 high, strobe signal start
GPIOC->BSRR |= GPIO_BSRR_BR_11; //Set PC11 low, strobe signal endJust write the register, it uses combinational logic to set or clear the specific bits you write into the BSRR
ie equivalent to GPIOC->ODR = (GPIOC->ODR | BSRRL) & ~BSRRH in a single atomic action
GPIOC->BSRR = (1 << 11); // Set bit 11
GPIOC->BSRR = (1 << (11 + 16)); // Clear bit 11
The USART and SPI have design complexity that an undergrad IC design major should be able to implement using 1990's schematic capture tools, and they didn't really understand practical uses cases for chip select. Definitely needed someone on the design team who had a better grip of logic, writing software drivers and actually using an assortment of SPI parts. They went to town on the I2C peripheral, but I'm not sure it helped the software implementation
2017-08-21 02:31 PM
>>The peripheral is synchronous and symmetrical, same clock moving data in/out, with selectable phase
The problem with BSY according to errata is that it loses synchronicity with bus clock, BSY can become
sporadic therefore ST recommends TXE, RXNE as detectors. Seams ST uninterested to fix it.
>>Don't do this (ie RMW)
>>GPIOC->BSRR = (1 << (11+16)); //Set bit 11
But...
GPIOC->BSRR = (1 << 27); //Clear bit 11.. is clearer.
Instead, can i do?:
GPIOC->BSRR = GPIO_BSRR_BS_11;//Set PC11 high
GPIOC->BSRR = GPIO_BSRR_BR_11; //Set PC11 lowIt gives the same disassembly and timing as your suggestion.
And for those who wonder about the difference in timing.
This makes PC11 c:a 1.5uS late and 0.7uS wide. 10 instructions
GPIOC->BSRR |= GPIO_BSRR_BS_11; //Set PC11 highGPIOC->BSRR |= GPIO_BSRR_BR_11; //Set PC11 lowThis makes PC11 c:a 1.2uS late and 0.45uS wide. 6 instructions
GPIOC->BSRR = (1 << 11); // Set bit 11GPIOC->BSRR = (1 << (11 + 16)); // Clear bit 11Disclaimer:! I have an old uncalibrated shabby scope and no compiler optimization!
Back in c:a 1986-90+'ish we had 68HC11F1 who had splendid auto address, auto CS toggle SPI
well working bug free and superb documentation, ST designers should read that manual
to get inspiration.
2017-08-21 06:51 PM
>>
Seams ST uninterested to fix it.
I think it is a stance of not creating dozens of stepping to have to special case, and not having people with legacy golden firmware images suddenly not behaving in a constant/predictable way from one order of chips to another.
2017-08-22 11:19 AM
>>>I think it is a stance of not creating dozens of stepping to have to special case, and not having
>>>people with legacy golden firmware images suddenly not behaving in a constant/predictable >>>way from one order of chips to another.It might be so, but perhaps a bit of a contradiction since customers are recommended to use RXNE
instead of BSY so if they fix BSY it would still be compatible and transparent with ST suggested
RXNE etc workarounds.
I bet it's about economics and not firmware, ST screwed it up so they thought it's cheaper to use
RXNE then to fix BSY logic and that makes perfect sense out of an economic situation.
If i would be the ST top head boss of MCU design i would indeed make the same decision.
So did ST ever fix I2C logic or should i just go soft pin toggling instead? Pherhaps they fixed in H7?
2017-08-25 09:35 AM
>
while((SPI3->SR & SPI_SR_BSY) == 1) //Test until Busy flag is 0
Um, SPI_SR_BSY is 0x80, not 0x01.
2017-08-26 03:15 AM
Good Loordy yes!