AT45DB161 DMA方试读写部分代码:
/* set Page (12Bit) and Byte Address (10Bit) */
/* 2 res.bits + 6 bits of 12-bit page-address */
#define ADR_P_B_1(page) (u8)(page>>6)
/* 6 bit page-address and 2bit Byte-address */
#define ADR_P_B_2(page, address) (u8)(page<<2)|(address>>8)
/* 8 bit Byte-address */
#define ADR_P_B_3(address) (u8)address
/*******************************************************************************
* Function Name : store_waitBusy
* Description : 存储器: 等待Flash空闲
*
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void store_waitBusy(void)
{
u8 state_reg=0x00;
store_init_spiMode(); /*进入SPI模式*/
store_selectFlash(FALSE, TRUE);
store_selectFlash(TRUE, TRUE);
store_spi_sendByte(DEF_FLASH_OP_STATUS);
while((state_reg&0x80) == 0)
{
state_reg = store_spi_readByte();
}
store_selectFlash(FALSE, FALSE);
store_init_dmaMode(); /*进入DMA模式*/
}
/*******************************************************************************
* Function Name : store_selectFlash
* Description : 存储器:选中Flash
*
* Input : bSelect :选中或释放, bLock :锁定或释放
* Output : None
* Return : None
*******************************************************************************/
void store_selectFlash(bool bSelect, bool bLock)
{
if (TRUE == bSelect)
{
if (TRUE == bLock)
{/*试图获得 g_stortState 互斥锁*/
rt_mutex_take(&g_stortState, RT_WAITING_FOREVER);
}
/*选中Flash*/
GPIO_ResetBits(FLASH_GPIO, FLASH_CS_PIN);
}
else
{
if (FALSE == bLock)
{/* 释放 g_stortState 互斥锁*/
rt_mutex_release(&g_stortState);
}
/*释放Flash*/
GPIO_SetBits(FLASH_GPIO, FLASH_CS_PIN);
}
}
/*******************************************************************************
* Function Name : store_init_dmaMode
* Description : Initializes the peripherals used by the DMA FLASH driver.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void store_init_dmaMode(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 GPIOA and GPIOB clocks */
RCC_APB2PeriphClockCmd(FLASH_SPI_RCC | FLASH_RCC, ENABLE);
/* Configure SPI1 pins: NSS, SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = FLASH_SCK_PIN | FLASH_MISO_PIN | FLASH_MOSI_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(FLASH_GPIO, &GPIO_InitStructure);
/* Configure PB.02 as Output push-pull, used as Flash Chip select */
GPIO_InitStructure.GPIO_Pin = FLASH_CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Deselect the FLASH: Chip Select high */
store_selectFlash(FALSE, TRUE);
/* SPI1 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_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_X, &SPI_InitStructure);
/* Enable FLASH_SPI_X Rx buffer DMA transfer request */
SPI_I2S_DMACmd(FLASH_SPI_X, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx,ENABLE);
/* Enable FLASH_SPI_X */
SPI_Cmd(FLASH_SPI_X, ENABLE);
}
/*******************************************************************************
* Function Name : store_dma_rx_init
* Description : 存储器:DMA方式读
*
* Input : nSize :大小
* Output : pData :目的数据地址
* Return : None
*******************************************************************************/
void store_dma_rx_init(u8* pData, u32 nSize)
{
#define TEMP_SIZE 50
DMA_InitTypeDef DMA_InitStructure;
u32 nloop = 0;
u8 temp[TEMP_SIZE];
DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&FLASH_SPI_X->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pData;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = nSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
//配置完成后,启动DMA通道
//DMA_ITConfig(DMA1_Channel3,DMA1_FLAG_TC3,ENABLE);
DMA_ClearFlag(DMA1_FLAG_TC2|DMA1_FLAG_GL2|DMA1_FLAG_HT2|DMA1_FLAG_TE2);//清标志位
DMA_Cmd(DMA1_Channel2, ENABLE);
DMA_Cmd(DMA1_Channel2, DISABLE);
DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&FLASH_SPI_X->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pData;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = nSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
DMA_ClearFlag(DMA1_FLAG_TC2|DMA1_FLAG_GL2|DMA1_FLAG_HT2|DMA1_FLAG_TE2);//清标志位
DMA_Cmd(DMA1_Channel2, ENABLE);
for (nloop = 0;nloop<(nSize/TEMP_SIZE);nloop++)
{
store_dma_tx_init(temp, TEMP_SIZE);
}
if ((nSize%TEMP_SIZE) > 0)
{
store_dma_tx_init(temp,(nSize%TEMP_SIZE));
}
while(RESET == DMA_GetFlagStatus(DMA1_FLAG_TC2));
DMA_Cmd(DMA1_Channel2, DISABLE);
}
/*******************************************************************************
* Function Name : store_dma_tx_init
* Description : 存储器:DMA方式写
*
* Input : nSize :大小
* Output : pData :源数据地址
* Return : None
*******************************************************************************/
void store_dma_tx_init(u8* pData, u32 nSize)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&FLASH_SPI_X->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pData;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = nSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
//配置完成后,启动DMA通道
//DMA_ITConfig(DMA1_Channel3,DMA1_FLAG_TC3,ENABLE);
DMA_ClearFlag(DMA1_FLAG_TC3|DMA1_FLAG_GL3|DMA1_FLAG_HT3|DMA1_FLAG_TE3);//清标志位
DMA_Cmd(DMA1_Channel3, ENABLE);
while(RESET == DMA_GetFlagStatus(DMA1_FLAG_TC3));
DMA_Cmd(DMA1_Channel3, DISABLE);
}
/*******************************************************************************
* Function Name : store_read
* Description : 存储器读
*
* Input : nAddr :Flash地址
* : nSize :大小
*
* Output : pData :数据指针
* Return : true or false
*******************************************************************************/
bool store_read(const u32 nAddr, const u32 nSize, void* pData)
{
u16 i = 0;
u32 page = nAddr / DEF_FLASH_PAGE_SIZE;
u32 address = nAddr % DEF_FLASH_PAGE_SIZE;
u8 arr_flash_cmd[9];
#ifdef __DEBUG__
rt_kprintf("store_read(nAddr: 0x%08X, nSize: %10d)
", nAddr, nSize);
#endif
if ((page < DEF_FLASH_MAX_PAGE)&&(nSize > 0)&&(pData != NULL))
{
store_waitBusy();
store_selectFlash(FALSE, TRUE);
store_selectFlash(TRUE, TRUE);
arr_flash_cmd[i++] = DEF_FLASH_OP_CONT_READ;
arr_flash_cmd[i++] = ADR_P_B_1(page);
arr_flash_cmd[i++] = ADR_P_B_2(page,address);
arr_flash_cmd[i++] = ADR_P_B_3(address);
arr_flash_cmd[i++] = 0x00;
arr_flash_cmd[i++] = 0x00;
arr_flash_cmd[i++] = 0x00;
arr_flash_cmd[i++] = 0x00;
/*发命令字*/
store_dma_tx_init(arr_flash_cmd, i);
/*传数据*/
store_dma_rx_init(pData, nSize);
store_selectFlash(FALSE, FALSE);
return TRUE;
}
else
{
return FALSE;
}
}
/*******************************************************************************
* Function Name : store_write
* Description : 存储器写
*
* Input : nAddr :Flash地址
* : nSize :大小
* : pData :数据指针
* Output : None
* Return : true or false
*******************************************************************************/
bool store_write(const u32 nAddr, const u32 nSize, void* pData)
{
u16 i = 0;
u32 page = nAddr / DEF_FLASH_PAGE_SIZE;
u32 address = nAddr % DEF_FLASH_PAGE_SIZE;
u8 arr_flash_cmd[9];
#ifdef __DEBUG__
rt_kprintf("store_write(nAddr: 0x%08X, nSize: %10d)
", nAddr, nSize);
#endif
if ((page < DEF_FLASH_MAX_PAGE)&&(nSize > 0)&&(pData != NULL))
{
store_waitBusy();
store_selectFlash(FALSE, TRUE);
store_selectFlash(TRUE, TRUE);
arr_flash_cmd[i++] = DEF_FLASH_OP_CONT_WRITE;
arr_flash_cmd[i++] = ADR_P_B_1(page);
arr_flash_cmd[i++] = ADR_P_B_2(page,address);
arr_flash_cmd[i++] = ADR_P_B_3(address);
/*发命令字*/
store_dma_tx_init(arr_flash_cmd, i);
/*传数据*/
store_dma_tx_init(pData, nSize);
store_selectFlash(FALSE, FALSE);
return TRUE;
}
else
{
return FALSE;
}
}