2018-05-29 11:34 PM
Hello friends,
I try SPI communication, and I have a problem. I only send data.... But how to receive it?
Connection is:
1. one master - one slave
2. Full duplex
Initialize:
LL_SPI_InitTypeDef SPI_InitStruct;
LL_GPIO_InitTypeDef GPIO_InitStruct;LL_SPI_Disable(SPI1);
LL_AHB1_GRP1_EnableClockLL_AHB1_GRP1_PERIPH_GPIOA);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
/* SPI2 GPIO Configuration */
GPIO_InitStruct.Pin = LL_GPIO_PIN_5; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_5; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_7; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_5; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_6; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_5; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_4; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_5; LL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* SPI1 parameter configuration*/
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH; SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; SPI_InitStruct.NSS = LL_SPI_NSS_HARD_OUTPUT; SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV64; SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; SPI_InitStruct.CRCPoly = 7; LL_SPI_Init(SPI1, &SPI_InitStruct);LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA);
LL_SPI_EnableNSSPulseMgt(SPI1);LL_SPI_SetRxFIFOThreshold(SPI1, LL_SPI_RX_FIFO_TH_QUARTER);
/* Configure SPI1 transfer interrupts */
/* Enable RXNE Interrupt */ LL_SPI_EnableIT_RXNE(SPI1);LL_SPI_Enable(SPI1);
And function to write/read....
int32_t read_from_reg(SPI_TypeDef *SPI, uint8_t data, uint8_t *SPI_Data_receive)
{ LL_SPI_TransmitData8(SPI, data); while (!LL_SPI_IsActiveFlag_TXE(SPI)); while (!LL_SPI_IsActiveFlag_RXNE(SPI)); while (LL_SPI_IsActiveFlag_BSY(SPI)); *SPI_Data_receive = LL_SPI_ReceiveData8(SPI);return 0;
}And I sent one byte and I don't receive anything. Any idea, how to receive some data from register?
#nucleo-f767zi #stm32f7-spi Note: this post was migrated and contained many threaded conversations, some content may be missing.2018-05-30 12:21 AM
I don't use the LL chips, but my running code runs along these lines.
int32_t read_from_reg(SPI_TypeDef *SPI, uint8_t data, uint8_t *SPI_Data_receive)
{ LL_SPI_TransmitData8(SPI, data); // issue 8 clocks to send command while (!LL_SPI_IsActiveFlag_TXE(SPI)); // wait while not empty while (LL_SPI_IsActiveFlag_BSY(SPI)); // wait while busy,//now byte has been clocked out
while (!LL_SPI_IsActiveFlag_RXNE(SPI)) // you should read & dump all bytes in the Rxregister now
read SPI_DR;
*SPI_Data_receive = LL_SPI_ReceiveData8(SPI); // issue new 8 clocks to read data
return 0;
}2018-05-30 02:44 AM
I modificated it, and no change ......
How it have to have look:And here is how it look now:
read_from_reg(SPI1, 0xF0, read);
2018-05-30 02:52 AM
I try everything.
>:(
For example, when I send 0xAB so chip must return his ID in 24bits.
So I send 0xAB and receive nothing. And clock doesn't generate signal.
And yes, I can resend instruction, but is this solution good?
2018-05-30 02:59 AM
If I am right, NSS pulsed mode will drive CE high between byte, and this is not what your target device expects. Try without.
Recently I ran with HW NSS correctly by pulling-up the NSS pin, I suspect that its drived by SPI as ope drain.
Good luck.
2018-05-30 03:33 AM
you only show 8 clock cycles..
What instruction is it ? 8 bit ?
that has to be transmitted,
then you want to receive 8 bits ?
you must transmit again, to receive those 8 bits.
2018-05-30 05:42 AM
,
,
I modificated NSSPulse to disable, and now SPI is dead.
Actual settings:
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX,
,
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER,,
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT,,
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH,,
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE,,
SPI_InitStruct.NSS = LL_SPI_NSS_HARD_OUTPUT,,
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV128,,
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST,,
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE,,
SPI_InitStruct.CRCPoly = 7,,
LL_SPI_Init(SPI, &,SPI_InitStruct),LL_SPI_SetStandard(LL_SPI_PROTOCOL_MOTOROLA),
,
LL_SPI_DisableNSSPulseMgt(SPI),LL_SPI_SetRxFIFOThreshold(SPI, LL_SPI_RX_FIFO_TH_QUARTER),
LL_SPI_Enable(SPI),
Read FCNT
void TM_SPI_Read(SPI_TypeDef* SPIx, uint8_t* dataIn, uint8_t dummy, uint8_t count)
,
{,
/* Check if SPI is enabled */,
SPI_CHECK_ENABLED(SPIx),/* Wait for previous transmissions to complete if DMA TX enabled for SPI */
,
SPI_WAIT_TX(SPIx),while (count--) {
,
/* Wait busy */,
SPI_WAIT_TX(SPIx),/* Fill output buffer with data */
,
SPIx->,DR = dummy,/* Wait for SPI to end everything */
,
SPI_WAIT_RX(SPIx),/* Save data to buffer */
,
*dataIn++ = SPIx->,DR,,
},
}other definitions:
♯ define SPI_CHECK_ENABLED(SPIx) , , , , , , ,if (!((SPIx)->,CR1 &, SPI_CR1_SPE)) {return,}
♯ define SPI_WAIT_TX(SPIx) while ((SPIx->,SR &, SPI_SR_TXE) == 0 || (SPIx->,SR &, SPI_SR_BSY))
,
♯ define SPI_WAIT_RX(SPIx) while ((SPIx->,SR &, SPI_SR_RXNE) == 0 || (SPIx->,SR &, SPI_SR_BSY))2018-05-30 05:50 AM
Read out and check/post the SPI registers content.
JW
2018-05-30 06:00 AM
Register I check every time.
:)
And here is actual settings:
CR1 - register
CR2 - register
CRCPR = 0x07 /*polygon I don't use */
I2SPR -> I2SDIV = 0x02
SR
others
are sets to zero
Others bit, register are set to zero.
2018-05-30 06:01 AM
you need to send 8 bits and receive 24 bits ID, Is that your quest ?
I can only see 8 clock cycles... where are the other 24 cycles ?
lcdDataRead(void) {
Clear_SPI1_nSS_Out(); SPI.transfer(RA8876_SPI_DATAREAD); ru8 data = SPI.transfer_receive( 0xff); <- here send a null to receive a byte, you have to do this 3 times.This is blocking code. Set_SPI1_nSS_Out(); return data;unsigned char SPI_t::transfer_receive(unsigned short data) {
char RxSPI;
// Clear_SPI1_nSS_Out(); while (!(hspi1.Instance->SR & SPI_FLAG_TXE)) // if the SPI port is still sending something, we have to wait:(
;// send the data
*((__IO uint8_t *)&hspi1.Instance->DR) = data; // force the SPI to transceive 8 bit
while (!(hspi1.Instance->SR & SPI_FLAG_TXE)) // wait for buffer to unload ; while ((hspi1.Instance->SR & SPI_FLAG_BSY)) // wait for data to leave pin ; while ((hspi1.Instance->SR & SPI_FLAG_RXNE)) // read all the bytes, we only want the last one RxSPI = hspi1.Instance->DR; // receive 1 or more bytes discard all but the last one. // Set_SPI1_nSS_Out(); return RxSPI;}