I am facing problem with STM32F401RE with SPI flash driver.
I am able to do normal SPI operations like read,write etc...
But I need to use DMA to read and write to FLASH.
/********************************
I am trying to read the data(DMA Methos) from specific address location 0x700000
which was written already.
*********************/
Now I was able to DMA sent sucessfully but on the DMA Receiving buffer it has starting four bytes of NULL data followed by actual Data and last four bytes are missing.
Original: STM32F4xx SPI Firmware Library Example: communication with an S25FL164K SPI FLASH from SPANSION
Receiving : "0x00 0x00 0x00 0x00 STM32F4xx SPI Firmware Library Example: communication with an S25FL164K SPI FLASH from SPAN"
Can some one please suggest why I am getting junk characters like NULL in the first four bytes and why the last four bytes are missing??
Is there any issue issues with clock cycles?? And one more thing I have to clear/read all the data present on "SPI1->DR " before the dma transfer
This is the code.. Please suggest if any issues in the below code
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/*!< Enable the SPI clock */
sFLASH_SPI_CLK_INIT(sFLASH_SPI_CLK, ENABLE);
/*!< Enable GPIO clocks */
/*!< Enable GPIO clocks */
RCC_AHB1PeriphClockCmd(sFLASH_SPI_SCK_GPIO_CLK | sFLASH_SPI_MISO_GPIO_CLK |
sFLASH_SPI_MOSI_GPIO_CLK | sFLASH_CS_GPIO_CLK, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/*!< SPI pins configuration *************************************************/
/*!< Connect SPI pins to AF5 */
GPIO_PinAFConfig(sFLASH_SPI_SCK_GPIO_PORT, sFLASH_SPI_SCK_SOURCE, sFLASH_SPI_SCK_AF);
GPIO_PinAFConfig(sFLASH_SPI_MISO_GPIO_PORT, sFLASH_SPI_MISO_SOURCE, sFLASH_SPI_MISO_AF);
GPIO_PinAFConfig(sFLASH_SPI_MOSI_GPIO_PORT, sFLASH_SPI_MOSI_SOURCE, sFLASH_SPI_MOSI_AF);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
/*!< SPI SCK pin configuration */
GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_SCK_PIN;
GPIO_Init(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
/*!< SPI MOSI pin configuration */
GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MOSI_PIN;
GPIO_Init(sFLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
/*!< SPI MISO pin configuration */
GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MISO_PIN;
GPIO_Init(sFLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sFLASH Card CS pin in output pushpull mode ********************/
GPIO_InitStructure.GPIO_Pin = sFLASH_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(sFLASH_CS_GPIO_PORT, &GPIO_InitStructure);
/*!< Deselect the FLASH: Chip Select high */
sFLASH_CS_HIGH();
/*!< SPI configuration */
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_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(sFLASH_SPI, &SPI_InitStructure);
void SPI_DMA_READ(uint8_t* Addref, uint8_t* pRxBuf, uint16_t rx_len)
{
uint16_t i;
memset(pTmpBuf1, 0, rx_len + 3);
memset(pTmpBuf2, 0, rx_len + 3);
pTmpBuf1[0] = sFLASH_CMD_READ;
pTmpBuf1[1] = Addref[0];
pTmpBuf1[2] = Addref[1];
pTmpBuf1[3] = Addref[2];
DMA_InitStructure.DMA_BufferSize = (uint16_t)(rx_len);
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI1->DR));
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
/* Configure Tx DMA */
DMA_InitStructure.DMA_Channel = DMA_Channel_3;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)pTmpBuf1;
DMA_Init(DMA2_Stream3, &DMA_InitStructure);
/* Configure Rx DMA */
DMA_InitStructure.DMA_Channel = DMA_Channel_3;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)pTmpBuf2;
DMA_Init(DMA2_Stream2, &DMA_InitStructure);
#if 1
//DMA Interrupt Structure Initialisation
static NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn;//SPI_PORT_DMA_TX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//Initialise the Interrupt
NVIC_Init(&NVIC_InitStructure);
// Enable DMA1 channel IRQ Channel */
DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE);
#endif
/* Enable the DMA channel */
/* Enable the DMA SPI TX Stream */
DMA_Cmd(DMA2_Stream3, ENABLE);
/* Enable the DMA SPI RX Stream */
DMA_Cmd(DMA2_Stream2, ENABLE);
/* Enable the SPI Rx DMA request */
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
sFLASH_CS_LOW();
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
{}
SPI_Cmd(SPI1, ENABLE);
while(trasfer_complete_rx == 0);
memcpy(pRxBuf, pTmpBuf2 ,rx_len);
/*******************************************/ IRQ Handler /***************************************/
void DMA2_Stream2_IRQHandler()
{
if(DMA_GetITStatus(DMA2_Stream2,DMA_IT_TCIF2))
DMA_ClearITPendingBit(DMA2_Stream2,DMA_IT_TCIF2);
DMA_ClearITPendingBit(DMA2_Stream3,DMA_IT_TCIF3);
DMA_ClearITPendingBit(DMA2_Stream2,DMA_IT_TCIF2);
DMA_Cmd(DMA2_Stream3, DISABLE);
DMA_Cmd(DMA2_Stream2, DISABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, DISABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, DISABLE);
SPI_Cmd(SPI1, DISABLE);
sFLASH_CS_HIGH();
trasfer_complete_rx =1;
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); // Wait for Empty
USART_SendData(USART2,*(pTmpBuf2+2)); // Send 'I'
}