AnsweredAssumed Answered

SPI Communication Issues

Question asked by minga.matt on Mar 29, 2013
Latest reply on Jul 8, 2015 by peacock.jack.003
I am using the stm32l151RB microcontroller. It is running on an external clock source at 14.7456 MHz. I am communicating with a Micron M25P16 serial flash memory. This device states that it is compatible with CPOL/CPHA configurations of 0/0 and 1/1.

I am currently in the hardware validation phase writing simple blocks of code just to make sure the layout is correct. I was able to read the manufacturer id, memory type and memory capacity off of the device using a CPOL/CPHA set to 1/1.

The problem is that when CPOL/CPHA are set to 0/0 I am unable to read the previously listed items. Originally I was getting nothing but zeroes, but I have since updated to the latest SPI library files that I could find on the website. I now get 0xFF when I attempt to read. Also strangely enough when hooked up to the scope, we don't see any data coming out of the controller on the MOSI line in the 0/0 configuration. Any help that can be provided would be greatly appreciated. Please let me know that additional information I can provide.

Below you will find a snippet of the code that I am using detailing the SPI configuration.

Pin Configurations

void SPI_Flash_LowLevel_Init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
   
  RCC_AHBPeriphClockCmd(FLASH_SPI_CS_GPIO_CLK | FLASH_SPI_MOSI_GPIO_CLK | FLASH_SPI_MISO_GPIO_CLK |
                        FLASH_SPI_SCK_GPIO_CLK, ENABLE);

  RCC_APB2PeriphClockCmd(FLASH_SPI_CLK, ENABLE);

  GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(FLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN;
  GPIO_Init(FLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN;
  GPIO_Init(FLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
 
  /*MKM - TODO - Clean this up and put this pin configuration in the right place*/
  GPIO_InitStructure.GPIO_Pin = FLASH_SPI_CS_PIN;
  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_10MHz;
  GPIO_Init(FLASH_SPI_CS_GPIO_PORT, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  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_10MHz;
  GPIO_Init(FLASH_SPI_CS_GPIO_PORT, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  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_10MHz;
  GPIO_Init(FLASH_SPI_CS_GPIO_PORT, &GPIO_InitStructure);
 
  GPIO_PinAFConfig(FLASH_SPI_SCK_GPIO_PORT, FLASH_SPI_SCK_SOURCE, FLASH_SPI_SCK_AF);
  GPIO_PinAFConfig(FLASH_SPI_MISO_GPIO_PORT, FLASH_SPI_MISO_SOURCE, FLASH_SPI_MISO_AF);
  GPIO_PinAFConfig(FLASH_SPI_MOSI_GPIO_PORT, FLASH_SPI_MOSI_SOURCE, FLASH_SPI_MOSI_AF);  
 
  SPI_Cmd(FLASH_SPI, ENABLE);
}


Usage

unsigned int i,mfg,memtype,capacity,address;
            
static portTASK_FUNCTION( vSPITask, pvParameters )
{
  /* The parameters are not used. */
  ( void ) pvParameters;
 
  SPI_InitTypeDef   SPI_InitStructure;
  SPI_InitTypeDef   *ptr_SPI_InitStructure;
  ptr_SPI_InitStructure = &SPI_InitStructure;
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(FLASH_SPI, &SPI_InitStructure);  
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  SPI_Init(FLASH_SPI, ptr_SPI_InitStructure);
  SPI_Cmd(FLASH_SPI, ENABLE);
 
   for(;;){
    
     
    GPIO_ResetBits(GPIOA, GPIO_Pin_4); //Flash Chip Select
    //GPIO_ResetBits(GPIOA, GPIO_Pin_3); //FPGA Chip Select
    
    while(SPI_GetFlagStatus(FLASH_SPI, SPI_FLAG_TXE)==RESET){}
    
    SPI_SendData(FLASH_SPI,0x9F); //Read ID command

    while(SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_TXE)==RESET){}

    SPI_I2S_ReceiveData(FLASH_SPI); // Clear out any pending RX data

    SPI_I2S_SendData(FLASH_SPI,0x00); // Junk Byte        
    
    while(SPI_GetFlagStatus(FLASH_SPI, SPI_FLAG_RXNE)==RESET){}
   
    mfg = SPI_ReceiveData(FLASH_SPI); // Manufactuer ID 0x20
   
    while(SPI_GetFlagStatus(FLASH_SPI, SPI_FLAG_TXE)==RESET){}

    SPI_SendData(FLASH_SPI,0x00); // Junk Byte

    while(SPI_GetFlagStatus(FLASH_SPI, SPI_FLAG_RXNE)==RESET){}
   
    memtype = SPI_I2S_ReceiveData(FLASH_SPI);

    while(SPI_GetFlagStatus(FLASH_SPI, SPI_FLAG_TXE)==RESET){}

    SPI_SendData(FLASH_SPI,0x00); // Junk Byte

    while(SPI_GetFlagStatus(FLASH_SPI, SPI_FLAG_RXNE)==RESET){}

    capacity = SPI_ReceiveData(FLASH_SPI);

    GPIO_SetBits(GPIOA, GPIO_Pin_4);

    vTaskDelay( 2000/ portTICK_RATE_MS );
   }
}
 

Outcomes