Question
SPI Communication Issues
Posted on March 29, 2013 at 23:57
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 ); } } #spi #spi-cpha #spi-st32l151rb