AnsweredAssumed Answered

F4Discovery SPI troubles

Question asked by padbury.chris on Jul 5, 2012
Latest reply on Mar 19, 2013 by rocketdawg

I am trying to use SPI with very little success. I tries to use NSS but gave up and am bit bashing the Chip Select. Even then, I am seeing issues so have had to add delays (Delay_us). I'm not receiving any response from the LTC2492 that is connected to the SPI and wonder where I am going wrong

#include "stm32f4_discovery.h"

/* LTC2492 configurations are of form binary 101xxxxx10000yyy    yyy=anything
   CH0 xxxxx = 10000    CH1 xxxxx=10001    CH2 xxxxx=11000    CH3 xxxxx=11001
*/
#define    LTC_Internal_Temperature_select    45248    //binary 1011000011000000
#define    LTC_CH0_select    45184    //binary 1011000010000000
#define    LTC_CH1_select    45440    //binary 1011000110000000
#define    LTC_CH2_select    47232    //binary 1011100010000000
#define    LTC_CH3_select    47488    //binary 1011100110000000
#define    dummy_bits_for_SPI    43690    //binary 1010101010101010

 

void Delay(int ms);
void Delay_us(int us);
 
/**************************************************************************************/
 
void RCC_Configuration(void)
{
  /* --------------------------- System Clocks Configuration -----------------*/
  /* USART1 clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
 
  /* GPIOB clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  /* GPIOE clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
}
 
/**************************************************************************************/
 
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  /*-------------------------- GPIO Configuration ----------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  /* Connect USART pins to AF */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // USART1_TX
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); // USART1_RX

  //   Configure Port E : Pins 7-15 as outputs
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOE, &GPIO_InitStructure);

  //   Configure Port B : Pin 12 as output  //FOR SPI CHip Select Function
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}
 
/**************************************************************************************/

void SPI2_Configuration(void)
{
 // Configure SPI
 SPI_InitTypeDef  SPI_InitStructure;
 GPIO_InitTypeDef GPIO_InitStructure;
   
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
 SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;             //DATASIZE
 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;      //SPI clock idle state is LOW
 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;    // controls which edge of the CLK is used , falling edge = SPI_CPHA_2Edge;
 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//Hard;//Soft;
 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
 SPI_InitStructure.SPI_CRCPolynomial = 7;
 SPI_Init(SPI2, &SPI_InitStructure);
 SPI_Cmd(SPI2, ENABLE);           /* Enable the SPI  */  
 //SPI_Cmd(SPI2, DISABLE);           /* Enable the SPI  */ 
 // Configure SPI -  CLK PB13, MISO PB14, MOSI PB15     no SPI2_NSS?????
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

 //RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI1, ENABLE);
}

 

 
void USART1_Configuration(void)
{
    USART_InitTypeDef USART_InitStructure;
 
  /* USARTx configuration ------------------------------------------------------*/
  /* USARTx configured as follow:
        - BaudRate = 9600 baud
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
  */
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
 
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 
  USART_Init(USART1, &USART_InitStructure);
 
  USART_Cmd(USART1, ENABLE);
}
 
/**************************************************************************************/
 
int main(void)
{
 char Received_From_device[500] = "";        // Maximum data from device of 500 bytes
 //char character[10] = "";
    char ETX_character;
 int i,a,lazy_timeout_counter,lazy_timeout_max,tmp,adc_value;
 char c; 
 
  RCC_Configuration();
 
  GPIO_Configuration();

  SPI2_Configuration();   //SPI configure
 
  USART1_Configuration();

   GPIO_SetBits(GPIOB, GPIO_Pin_12);   //set Chip Select HIGH for SPI
 
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Wait for Empty
 
    USART_SendData(USART1, 0x49); // Send 'I'
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, 0x42); // Send 'B'
SPI_Loop:
 Delay(1000);    //1second delay

 //goto Jump2Here;

 //Select CH0 of LTC2492
 //SPI_Cmd(SPI2, ENABLE);           /* Enable the SPI  */

   // while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0) //wait for transmit buffer to not be empty (ie data loaded in)

 GPIO_ResetBits(GPIOB, GPIO_Pin_12);
 Delay_us(10);
 SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Tx);  //set SPI direction to Transmit   ????????
 //while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0) //wait for transmit buffer to be empty
    //SPI_I2S_SendData(SPI2, LTC_CH0_select);
 SPI_I2S_SendData(SPI2, LTC_Internal_Temperature_select); //LTC_Internal_Temperature_select
 while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0) //wait for transmit buffer to not be empty (ie data loaded in)
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == 1) //wait for transmit busy flag to be LOW
 //SPI_Cmd(SPI2, DISABLE);           /* Disable the SPI  */
 Delay_us(60);
 GPIO_SetBits(GPIOB, GPIO_Pin_12); 

 Delay(1000);    //1second delay

 //while(1);

 //await result readable via SPI and read in result via SPI   two 16bit reads over SPI
 //SPI_Cmd(SPI2, ENABLE);           /* Enable the SPI  */
 GPIO_ResetBits(GPIOB, GPIO_Pin_12);
 Delay_us(10);
 SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Rx);  //set SPI direction to Receive
 //while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == 0)  // wait until receive buffer is not empty 
    //tmp = SPI_I2S_ReceiveData(SPI2);  // read byte from receive buffer
 SPI_I2S_SendData(SPI2, LTC_Internal_Temperature_select);    //dummy_bits_for_SPI
 while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0) //wait for transmit buffer to not be empty (ie data loaded in)
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == 1) //wait for transmit busy flag to be LOW
 tmp = SPI_I2S_ReceiveData(SPI2);  // read byte from receive buffer
 adc_value =  tmp * 65536;
 
 //while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == 0)  // wait until receive buffer is not empty 
    //tmp = SPI_I2S_ReceiveData(SPI2);  // read byte from receive buffer
 SPI_I2S_SendData(SPI2, 0);    //dummy_bits_for_SPI
 while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == 0) //wait for transmit buffer to be empty
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == 1) //wait for transmit busy flag to be LOW
 tmp = SPI_I2S_ReceiveData(SPI2);  // read byte from receive buffer
 //SPI_Cmd(SPI2, DISABLE);           /* Disable the SPI  */
 Delay_us(10);
 GPIO_SetBits(GPIOB, GPIO_Pin_12);
 adc_value = adc_value + tmp;
 //adc_value = adc_value /

 

 

Jump2Here:
 //send result via RS232

 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, 0x43); // Send 'C'
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, 0x48); // Send 'H'
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, 0x30); // Send '0'
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, 0x3A); // Send ':'

 //adc_value = 1234567890;
 tmp = adc_value;    
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, tmp/16777216);
 tmp = tmp/16777216;
 tmp = adc_value - 16777216 * tmp;
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, tmp/65536);
 tmp = tmp/65536;
 tmp = adc_value - 65536 * tmp;
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, tmp/256);
 tmp = tmp/256;
 tmp = adc_value - 256 * tmp;
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, tmp);

 //goto SPI_Loop;

 while (1);
}

void Delay(int ms) {  //practical limit of 25,000ms
    ms = ms * 168000 / 4;
 while (ms) {
     ms--;
 }
}

void Delay_us(int us) {  //practical limit of 25,000us
    us = us * 168 / 4;
 while (us) {
     us--;
 }
}

Outcomes