cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F767 and SPI communication without DMA

Pilous Droip
Senior
Posted on May 30, 2018 at 08:34

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.
20 REPLIES 20
T J
Lead
Posted on May 30, 2018 at 09:21

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;

}
Posted on May 30, 2018 at 09:44

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);

0690X0000060BQFQA2.png

Pilous Droip
Senior
Posted on May 30, 2018 at 11:52

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. 

0690X0000060L12QAE.png

And yes, I can resend instruction, but is this solution good?

stm322399
Senior
Posted on May 30, 2018 at 11:59

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.

Posted on May 30, 2018 at 10:33

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.

Posted on May 30, 2018 at 12:42

 ,

 ,

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))
Posted on May 30, 2018 at 12:50

Read out and check/post the SPI registers content.

JW

Posted on May 30, 2018 at 13:00

Register I check every time. 

🙂

And here is actual settings:

CR1 - register

  • BR = 0x06
  • CPOL = 0x01
  • MSTR = 0x01
  • SPE = 0x01
  • SSI = 0x01
  • SSM = 0x01
  • others are sets to zero

CR2 - register

  • DS = 0x07
  • FRXTH = 0x01
  • others are sets to zero

CRCPR = 0x07 /*polygon I don't use */

I2SPR -> I2SDIV = 0x02

SR

  • RXNE = 0x01   /* here I see a problem ....*/
  • TXNE = 0x01
  • others 

    are sets to zero

Others bit, register are set to zero.

Posted on May 30, 2018 at 13:01

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;

}