AnsweredAssumed Answered

STM32F746 - SPI sends twice problem

Question asked by M G on Jul 11, 2018
Latest reply on Jul 12, 2018 by waclawek.jan

Dear Community

I want to send 32 bits by SPI using the 16bit mode twice. I’ve setup the 16bit SPI using the LL Driver concept (please have a look for my attached code) and observed via scope that each 16 bits are send twice thus I am not able to reconstruct a 32 value from this because I've received 64bits. In my example I want to send 0x1234 and 0xABCD but ive I scope the SPI bus then I get 0x1234 0x1234 0xABCD 0xABCD - see atteched scope screen).

I’ve already noticed the “data packing” problem described here (https://community.st.com/thread/34357-stm32f4-to-stm32f7-port-spi-wrong-clk-signal) which reduced the number of SHORTs send by the SPI from 4 to 2 for each interrupt. I would be glad if I could get some suggestions what else I might change to make the SPI to just send 16bits of data for each interrupt.

[CODE]

 

//**********************SPI*************************************
  #define SPIx                           SPI2//SPI2
  #define SPIx_CLK                       LL_APB1_GRP1_PERIPH_SPI2 //RCC_APB1Periph_SPI2 // RCC_APB1Periph_SPI2
  #define SPIx_CLK_INIT                  LL_APB1_GRP1_EnableClock //RCC_APB1PeriphClockCmd //  RCC_APB1PeriphClockCmd
  #define SPIx_IRQn                      SPI2_IRQn // _IRQn //2
  #define SPIx_IRQHANDLER                SPI2_IRQHandler // SPI2_IRQHandler //2
  #define SPIx_SCK_PIN                   LL_GPIO_PIN_13 // GPIO_Pin_13 // GPIO_Pin_1
  #define SPIx_SCK_GPIO_PORT             GPIOB // GPIOB // GPIOI
  #define SPIx_SCK_GPIO_CLK              LL_AHB1_GRP1_PERIPH_GPIOB //RCC_AHB1Periph_GPIOB // RCC_AHB1Periph_GPIOI
  #define SPIx_SCK_SOURCE                LL_GPIO_AF_5  //GPIO_PinSource13 // GPIO_PinSource1
  #define SPIx_SCK_AF                    LL_GPIO_MODE_ALTERNATE // GPIO_AF_SPI2 // GPIO_AF_SPI2
  #define SPIx_MISO_PIN                  LL_GPIO_PIN_14 //GPIO_Pin_14 // GPIO_Pin_2   // is actually MOSI
  #define SPIx_MISO_GPIO_PORT            GPIOB //GPIOB // GPIOI
  #define SPIx_MISO_GPIO_CLK             LL_AHB1_GRP1_PERIPH_GPIOB //RCC_AHB1Periph_GPIOB // RCC_AHB1Periph_GPIOI
  #define SPIx_MISO_SOURCE               LL_GPIO_AF_5 //  GPIO_PinSource2
  #define SPIx_MISO_AF                   LL_GPIO_MODE_ALTERNATE //GPIO_AF_SPI2 //  GPIO_AF_SPI2
  #define SPIx_MOSI_PIN                  LL_GPIO_PIN_15 //GPIO_Pin_15 // GPIO_Pin_3   //is actually MISO !!
  #define SPIx_MOSI_GPIO_PORT            GPIOB // GPIOB // GPIOI
  #define SPIx_MOSI_GPIO_CLK             LL_AHB1_GRP1_PERIPH_GPIOB //RCC_AHB1Periph_GPIOB // RCC_AHB1Periph_GPIOI
  #define SPIx_MOSI_SOURCE               LL_GPIO_AF_5 // GPIO_PinSource15 // GPIO_PinSource3
  #define SPIx_MOSI_AF                   LL_GPIO_MODE_ALTERNATE //GPIO_AF_SPI2 // GPIO_AF_SPI2
 
 #define SPIx_CS_PIN                    LL_GPIO_PIN_12 // GPIO_Pin_12
  #define SPIx_CS_GPIO_PORT              GPIOB //GPIOB
  #define SPIx_CS_GPIO_CLK               LL_AHB1_GRP1_PERIPH_GPIOB //RCC_AHB1Periph_GPIOB
  #define SPIx_CS_SOURCE                 LL_GPIO_AF_5 //GPIO_PinSource12
  #define SPIx_CS_AF                     LL_GPIO_MODE_ALTERNATE //GPIO_AF_SPI2
 
 
void Init_SPI(void)
{
  //Enables GPIO clock and configures the SPI1 pins ********************/
  // Enable the peripheral clock of GPIOA */
 volatile unsigned int CR1values;
 LL_SPI_InitTypeDef SPI_InitStructure;
 
  //LL_AHB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
 SPIx_CLK_INIT ( SPIx_CLK  );
 LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
 
 
  // Configure SCK Pin connected to pin 10 of CN7 connector
  LL_GPIO_SetPinMode(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN , SPIx_SCK_AF);
  LL_GPIO_SetAFPin_8_15(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN , SPIx_SCK_SOURCE);
  LL_GPIO_SetPinSpeed(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN , LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinPull(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN , LL_GPIO_PULL_DOWN);
  /* Configure MISO Pin connected to pin 12 of CN7 connector */
  LL_GPIO_SetPinMode(SPIx_MISO_GPIO_PORT , SPIx_MISO_PIN, SPIx_MISO_AF);
  LL_GPIO_SetAFPin_8_15(SPIx_MISO_GPIO_PORT , SPIx_MISO_PIN , SPIx_MISO_SOURCE);
  LL_GPIO_SetPinSpeed(SPIx_MISO_GPIO_PORT , SPIx_MISO_PIN , LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinPull(SPIx_MISO_GPIO_PORT ,SPIx_MISO_PIN , LL_GPIO_PULL_DOWN);
  /* Configure MOSI Pin connected to pin 14 of CN7 connector */
  LL_GPIO_SetPinMode(SPIx_MOSI_GPIO_PORT,  SPIx_MOSI_PIN,  SPIx_MOSI_AF);
  LL_GPIO_SetAFPin_8_15(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN,  SPIx_MOSI_SOURCE);
  LL_GPIO_SetPinSpeed(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN, LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinPull(SPIx_MOSI_GPIO_PORT,  SPIx_MOSI_PIN, LL_GPIO_PULL_DOWN);
 // Configure CS PIN
  LL_GPIO_SetPinMode(SPIx_CS_GPIO_PORT,  SPIx_CS_PIN,  SPIx_CS_AF);
  LL_GPIO_SetAFPin_8_15(SPIx_CS_GPIO_PORT, SPIx_CS_PIN,  SPIx_CS_SOURCE);
  LL_GPIO_SetPinSpeed(SPIx_CS_GPIO_PORT,  SPIx_CS_PIN, LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinPull(SPIx_CS_GPIO_PORT,  SPIx_CS_PIN, LL_GPIO_PULL_DOWN);
  NVIC_SetPriority(SPIx_IRQn, SPI_Prio);
  NVIC_EnableIRQ(SPIx_IRQn);
  LL_SPI_DeInit(SPIx);
//https://community.st.com/thread/34357-stm32f4-to-stm32f7-port-spi-wrong-clk-signal
// @ Fehrenbacher.Christi on Dec 13, 2016 8:33 AM
//Hello Christian,
//
//Jan is right. On the F303, there is the same feature and if you just write SPIx.DR = data, the compiler will assume that you want to write 16 bits to DR (because DR is 16 bits, even if data is an 8 bits variable). The trick here is to force an 8-bit write to DR, like this:
//*(__IO uint8_t *) ((uint32_t)SPIx + (uint32_t)0x0C) = data; // Replace SPIx with the actual SPI you are using
//
//Have a nice day,
//Carl
  SPI_InitStructure.TransferDirection = LL_SPI_FULL_DUPLEX; //   SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.DataWidth =  LL_SPI_DATAWIDTH_8BIT; // SPI_DataSize_16b;
  SPI_InitStructure.ClockPolarity =  LL_SPI_POLARITY_LOW; // SPI_CPOL_Low;// High;// High;
  SPI_InitStructure.ClockPhase =  LL_SPI_PHASE_1EDGE; // SPI_CPHA = SPI_CPHA_1Edge; //2
  SPI_InitStructure.NSS  =  LL_SPI_NSS_SOFT;
  SPI_InitStructure.BaudRate  = LL_SPI_BAUDRATEPRESCALER_DIV64; // SPI_BaudRatePrescaler_8;// 256  ;// SPI_BaudRatePrescaler_32;
  SPI_InitStructure.BitOrder  =  LL_SPI_MSB_FIRST;
  SPI_InitStructure.CRCCalculation  =  LL_SPI_CRCCALCULATION_DISABLE; //Disable
  SPI_InitStructure.CRCPoly  = 1;
 SPI_InitStructure.Mode = LL_SPI_MODE_MASTER; // SPI_Mode_Master;
 
  LL_SPI_Init(SPIx, &SPI_InitStructure);
  LL_SPI_SetRxFIFOThreshold(SPIx, LL_SPI_RX_FIFO_TH_QUARTER);
 
          
 LL_SPI_EnableIT_RXNE(SPIx);
 LL_SPI_Enable(SPIx);
}
volatile unsigned short MaTxBuffer;
volatile unsigned short MaRxBuffer;
volatile bool Send ; //= false;
volatile bool SPIreceive;
volatile bool Check;
void  SPIx_IRQHANDLER(void)
{
  volatile unsigned short FlippedTxBuffer;
  if(LL_SPI_IsActiveFlag_RXNE(SPIx))
  {
  MaRxBuffer =  LL_SPI_ReceiveData16(SPIx);
  LL_SPI_DisableIT_RXNE(SPIx);
  SPIreceive = false; 
 }
  // Check RXNE flag value in ISR register
  if(LL_SPI_IsActiveFlag_TXE(SPIx))
  {
  LL_SPI_DisableIT_TXE(SPIx);
  FlippedTxBuffer =  (MaTxBuffer >> 8) & 0xFF;
  FlippedTxBuffer += (MaTxBuffer & 0xFF) << 8;
  SPIx->DR = FlippedTxBuffer;
    Send = false;
  }
}
 
void Send_a_2Bytes(unsigned short The2Bytes) {
 
 SPIreceive = true;
 Send = true;
 MaTxBuffer = The2Bytes;
  LL_SPI_EnableIT_RXNE(SPIx);
  LL_SPI_EnableIT_TXE(SPIx);
 while(SPIreceive) {};
 while(SPIx->SR & (1 << 7)); // while until SR BSY is cleared
}
 CS_L();
 Send_a_2Bytes(0x1234);
 Send_a_2Bytes(0xABCD);
 CS_H();
[\CODE]

Attachments

Outcomes