cancel
Showing results for 
Search instead for 
Did you mean: 

SPI in Master Mode with NSS Hard Output

suresh
Associate II
Posted on July 07, 2017 at 20:42

Hello, I interfaced STM3210E-EVAL with external RF Slave chip and trying to place a data in a slave register.

Ex data: 

Slave register address is 0xC0 and placing two bytes of data (0x00 and 0x12). For this I  configured SPI-1 as follows:

hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH; //SPI_POLARITY_LOW;

hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; //SPI_PHASE_1EDGE;

hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 10;

bool SendSPIData(void)

{

rte = false;

aTxBuffer[0]= 0xC0; //RegisterAddr;

aTxBuffer[1]= 0x00;

aTxBuffer[2]= 0x12;

if(HAL_SPI_Transmit(&hspi1, (uint8_t*)aTxBuffer, 3, CBUS_ACK_TIMEOUT)!= HAL_OK)

       rte = false;

else

{

     rte = true;

     break;

  }

return rte;

}

Issues with this coding I am seeing: 

1. Couldn't able to toggle SS line as slave chip vendor suggested from High to low when clock and data present.

2. There is a long gap in between each byte transmission

Slave chip requires SPI data lines toggle as shown in following picture:

Appreciates any help on this.

0690X00000603vxQAA.jpg

#stm32f1-spi #spi-driver
2 REPLIES 2
T J
Lead
Posted on July 08, 2017 at 04:17

I am not sure why, but I have to manually pull /CS down before the TX and after the Tx has finished totally, pull /CS back up.

I hacked this for you;

void SPI_2::write(uint8_t sendSPIByte){

    while( !(    hspi2.Instance->SR  & SPI_FLAG_TXE));

    Drop CS

        *((__IO uint8_t *)&hspi2.Instance->DR) =  sendSPIByte;        

        while( !(    hspi2.Instance->SR  & SPI_FLAG_TXE));

        while(  (    hspi2.Instance->SR  & SPI_FLAG_BSY));

   Raise CS

}

uint8_t SPI_2::read(uint8_t sendSPIByte){

        while( !(    hspi2.Instance->SR  & SPI_FLAG_TXE));

    Drop CS 

    *((__IO uint8_t *)&hspi2.Instance->DR) =  TxSPIByte;                // force the SPI to transceive 8 bit

        while( !(    hspi2.Instance->SR  & SPI_FLAG_TXE));

        while(  (    hspi2.Instance->SR  & SPI_FLAG_BSY));

   Raise CS

        while(  (    hspi2.Instance->SR  & SPI_FLAG_RXNE))

                RxSPIByte1 = hspi2.Instance->DR;

    

 return RxSPIByte1;

}
Posted on July 08, 2017 at 12:41

1. Couldn't able to toggle SS line as slave chip vendor suggested from High to low when clock and data present.

There's no hardware in STM32 which does this automatically. In newer models there's a 'toggle' mode which would frame each byte/word - this is not what you want and you don't have that in the ancient STM32F1xx you are using anyway.

So you have to do that 'manually', setting the NSS pin to GPIO output and setting it as needed before transmission and after the transmission has been completed (and setting NSS in SPI to soft and inactive).

2. There is a long gap in between each byte transmission

I don't know what incarnation of HAL_SPI_Transmit() you use, but I looked at the one in CubeF4 v1.16 and it has a timeout management, which in case of compiler optimizations off may take up quite a bit of processor cycles; now given your rather high SPI clock (hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;) this may in such setup seem to be 'long'.

JW