add iccarm support for cm3

1. IAR project, see TencentOS-tiny\board\STM32F103_SIM800A\iar
This commit is contained in:
daishengdong
2020-07-01 20:24:57 +08:00
parent 61a88b4988
commit 4eb56ab12a
936 changed files with 576567 additions and 113 deletions

View File

@@ -0,0 +1,77 @@
/* Includes ------------------------------------------------------------------*/
//#include "fatfs.h"
#include "fatfs_drv.h"
#include "tos_k.h"
#include <hal_spi_flash.h>
/* Defines ------------------------------------------------------------------*/
#define SPI_FLASH_SECTOR_SIZE (4 * 1024)
#define SPI_FLASH_PAGE_SIZE 256
DSTATUS w25q64_fatfs_status(BYTE lun)
{
DSTATUS status = STA_NOINIT;
if(SPI_FLASH_ID == hal_spi_flash_get_id())
{
status &= ~STA_NOINIT;
}
return status;
}
DSTATUS w25q64_fatfs_initialize(BYTE lun)
{
DSTATUS status = STA_NOINIT;
hal_spi_flash_config();
hal_spi_flash_wake_up();
status = w25q64_fatfs_status(lun);
return status;
}
DRESULT w25q64_fatfs_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
{
int ret;
ret = hal_spi_flash_read(buff, count * SPI_FLASH_SECTOR_SIZE,
FF_PHYS_ADDR + sector * SPI_FLASH_SECTOR_SIZE);
if(ret != 0)
return RES_ERROR;
return RES_OK;
}
DRESULT w25q64_fatfs_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
int ret;
ret = hal_spi_flash_erase_write(buff, count * SPI_FLASH_SECTOR_SIZE,
FF_PHYS_ADDR + sector * SPI_FLASH_SECTOR_SIZE);
if(ret != 0)
return RES_ERROR;
return RES_OK;
}
DRESULT w25q64_fatfs_ioctl(BYTE lun, BYTE cmd, void *buff)
{
switch (cmd)
{
case GET_SECTOR_COUNT:
*(DWORD *)buff = FF_PHYS_SIZE / SPI_FLASH_SECTOR_SIZE;
break;
case GET_SECTOR_SIZE:
*(WORD *)buff = SPI_FLASH_SECTOR_SIZE;
break;
case GET_BLOCK_SIZE:
*(DWORD *)buff = 1;
break;
default:
return RES_PARERR;
}
return RES_OK;
}
DWORD get_fattime (void)
{
return 0;
}
/* Private functions --------------------------------------------------------*/

View File

@@ -0,0 +1,18 @@
#ifndef FATFS_DRV_H
#define FATFS_DRV_H
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "hal_spi_flash.h"
DSTATUS w25q64_fatfs_initialize(BYTE);
DSTATUS w25q64_fatfs_status(BYTE);
DRESULT w25q64_fatfs_read (BYTE, BYTE*, DWORD, UINT);
#if 1
DRESULT w25q64_fatfs_write (BYTE, const BYTE*, DWORD, UINT);
#endif /* _USE_WRITE == 1 */
#if 1
DRESULT w25q64_fatfs_ioctl (BYTE, BYTE, void*);
#endif /* _USE_IOCTL == 1 */
#endif

View File

@@ -0,0 +1,425 @@
#include "hal_spi_flash.h"
#include "stm32f1xx.h"
#include "stm32f1xx_hal_spi.h"
#ifdef HAL_SPI_MODULE_ENABLED
#define SPI_FLASH_WriteEnable 0x06
#define SPI_FLASH_WriteDisable 0x04
#define SPI_FLASH_ReadStatusReg 0x05
#define SPI_FLASH_WriteStatusReg 0x01
#define SPI_FLASH_ReadData 0x03
#define SPI_FLASH_FastReadData 0x0B
#define SPI_FLASH_FastReadDual 0x3B
#define SPI_FLASH_PageProgram 0x02
#define SPI_FLASH_BlockErase 0xD8
#define SPI_FLASH_SectorErase 0x20
#define SPI_FLASH_ChipErase 0xC7
#define SPI_FLASH_PowerDown 0xB9
#define SPI_FLASH_ReleasePowerDown 0xAB
#define SPI_FLASH_DeviceID 0xAB
#define SPI_FLASH_ManufactDeviceID 0x90
#define SPI_FLASH_JedecDeviceID 0x9F
#define SPI_FLASH_WIP_FLAG 0x01
#define SPI_FLASH_DUMMY_BYTE 0xFF
#define SPI_FLASH_PERIPHERAL SPI2
#define SPI_FLASH_ALTERNATE GPIO_AF2_SPI2
#define SPI_FLASH_GPIO_PORT GPIOB
#define SPI_FLASH_SCK_PIN GPIO_PIN_13
#define SPI_FLASH_MISO_PIN GPIO_PIN_14
#define SPI_FLASH_MOSI_PIN GPIO_PIN_15
#define SPI_FLASH_CS_PORT SPI_CS_GPIO_Port
#define SPI_FLASH_CS_PIN SPI_CS_Pin
#define CHOOSE_BIT_16 16
#define CHOOSE_BIT_8 8
#define SPI_FLASH_ENABLE(__HANDLE__) __HAL_SPI_ENABLE(__HANDLE__)
#define SPI_FLASH_DISABLE(__HANDLE__) __HAL_SPI_DISABLE(__HANDLE__)
#define SPI_FLASH_RCC_CLK_ENABLE() __HAL_RCC_SPI2_CLK_ENABLE()
#define SPI_FLASH_RCC_CLK_DISABLE() __HAL_RCC_SPI2_CLK_DISABLE()
#define SPI_FLASH_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPI_FLASH_CS_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define SPI_FLASH_CS_ENABLE() HAL_GPIO_WritePin(SPI_FLASH_CS_PORT, SPI_FLASH_CS_PIN, GPIO_PIN_RESET)
#define SPI_FLASH_CS_DISABLE() HAL_GPIO_WritePin(SPI_FLASH_CS_PORT, SPI_FLASH_CS_PIN, GPIO_PIN_SET)
#define CHECK_RET_RETURN(ret) \
do \
{ \
if ((ret) < 0) \
{ \
return ret; \
} \
} while (0)
SPI_HandleTypeDef g_spi_flash;
/* This function is called by inner-HAL lib */
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if (hspi->Instance == SPI_FLASH_PERIPHERAL)
{
SPI_FLASH_RCC_CLK_ENABLE();
SPI_FLASH_GPIO_CLK_ENABLE();
SPI_FLASH_CS_CLK_ENABLE();
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = SPI_FLASH_CS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(SPI_FLASH_CS_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI_FLASH_SCK_PIN | SPI_FLASH_MOSI_PIN | SPI_FLASH_MISO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SPI_FLASH_GPIO_PORT, &GPIO_InitStruct);
}
}
/* This function is called by inner-HAL lib */
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{
if (hspi->Instance == SPI_FLASH_PERIPHERAL)
{
SPI_FLASH_RCC_CLK_DISABLE();
HAL_GPIO_DeInit(SPI_FLASH_GPIO_PORT, SPI_FLASH_SCK_PIN | SPI_FLASH_MOSI_PIN | SPI_FLASH_MISO_PIN);
HAL_GPIO_DeInit(SPI_FLASH_CS_PORT, SPI_FLASH_CS_PIN);
SPI_FLASH_DISABLE(hspi);
}
}
static int prv_spi_flash_send_byte(uint8_t send, uint8_t* recv)
{
uint8_t tmp;
uint8_t t_send = send;
if (HAL_SPI_TransmitReceive(&g_spi_flash, &t_send, &tmp, 1, HAL_MAX_DELAY) != HAL_OK)
{
return -1;
}
if (NULL != recv)
{
*recv = tmp;
}
return 0;
}
static int prv_spi_flash_send_cmd(uint8_t cmd, uint32_t addr)
{
int ret = 0;
ret = prv_spi_flash_send_byte(cmd, NULL);
CHECK_RET_RETURN(ret);
ret = prv_spi_flash_send_byte((addr & 0xFF0000) >> CHOOSE_BIT_16, NULL);
CHECK_RET_RETURN(ret);
ret = prv_spi_flash_send_byte((addr & 0xFF00) >> CHOOSE_BIT_8, NULL);
CHECK_RET_RETURN(ret);
ret = prv_spi_flash_send_byte(addr & 0xFF, NULL);
CHECK_RET_RETURN(ret);
return ret;
}
static void prv_spi_flash_write_enable(void)
{
SPI_FLASH_CS_ENABLE();
(void)prv_spi_flash_send_byte(SPI_FLASH_WriteEnable, NULL);
SPI_FLASH_CS_DISABLE();
}
static void prv_spi_flash_wait_write_end(void)
{
uint8_t status = 0;
SPI_FLASH_CS_ENABLE();
(void)prv_spi_flash_send_byte(SPI_FLASH_ReadStatusReg, NULL);
/* Loop as long as the memory is busy with a write cycle */
do
{
/* Send a dummy byte to generate the clock needed by the FLASH
and put the value of the status register in status variable */
if (prv_spi_flash_send_byte(SPI_FLASH_DUMMY_BYTE, &status) == -1)
{
break;
}
} while ((status & SPI_FLASH_WIP_FLAG) == SET); /* Write in progress */
SPI_FLASH_CS_DISABLE();
}
static int prv_spi_flash_write_page(const uint8_t* buf, uint32_t addr, int32_t len)
{
int ret = 0;
int i;
if(0 == len)
{
return 0;
}
prv_spi_flash_write_enable();
SPI_FLASH_CS_ENABLE();
if ((ret = prv_spi_flash_send_cmd(SPI_FLASH_PageProgram, addr)) != -1)
{
for (i = 0; i < len; ++i)
{
if (prv_spi_flash_send_byte(buf[i], NULL) == -1)
{
ret = -1;
break;
}
}
}
SPI_FLASH_CS_DISABLE();
prv_spi_flash_wait_write_end();
return ret;
}
static int prv_spi_flash_erase_sector(uint32_t addr)
{
int ret = 0;
prv_spi_flash_write_enable();
prv_spi_flash_wait_write_end();
SPI_FLASH_CS_ENABLE();
ret = prv_spi_flash_send_cmd(SPI_FLASH_SectorErase, addr);
SPI_FLASH_CS_DISABLE();
prv_spi_flash_wait_write_end();
return ret;
}
void hal_spi_flash_config(void)
{
g_spi_flash.Instance = SPI_FLASH_PERIPHERAL;
g_spi_flash.State = HAL_SPI_STATE_RESET;
g_spi_flash.Init.Mode = SPI_MODE_MASTER;
g_spi_flash.Init.Direction = SPI_DIRECTION_2LINES;
g_spi_flash.Init.DataSize = SPI_DATASIZE_8BIT;
g_spi_flash.Init.CLKPolarity = SPI_POLARITY_HIGH;
g_spi_flash.Init.CLKPhase = SPI_PHASE_2EDGE;
g_spi_flash.Init.NSS = SPI_NSS_SOFT;
g_spi_flash.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
g_spi_flash.Init.FirstBit = SPI_FIRSTBIT_MSB;
g_spi_flash.Init.TIMode = SPI_TIMODE_DISABLE;
g_spi_flash.Init.CRCPolynomial = 7;
HAL_SPI_Init(&g_spi_flash);
SPI_FLASH_ENABLE(&g_spi_flash);
SPI_FLASH_CS_DISABLE();
}
int hal_spi_flash_erase(uint32_t addr, int32_t len)
{
uint32_t begin;
uint32_t end;
int i;
if (len < 0
|| addr > SPI_FLASH_TOTAL_SIZE
|| addr + len > SPI_FLASH_TOTAL_SIZE)
{
return -1;
}
begin = addr / SPI_FLASH_SECTOR * SPI_FLASH_SECTOR;
end = (addr + len - 1) / SPI_FLASH_SECTOR * SPI_FLASH_SECTOR;
for (i = begin; i <= end; i += SPI_FLASH_SECTOR)
{
if (prv_spi_flash_erase_sector(i) == -1)
{
return -1;
}
}
return 0;
}
int hal_spi_flash_write(const void* buf, int32_t len, uint32_t* location)
{
const uint8_t* pbuf = (const uint8_t*)buf;
int page_cnt = 0;
int remain_cnt = 0;
int temp = 0;
uint32_t loc_addr;
uint8_t addr = 0;
uint8_t count = 0;
int i;
int ret = 0;
if (NULL == pbuf
|| NULL == location
|| len < 0
|| *location > SPI_FLASH_TOTAL_SIZE
|| len + *location > SPI_FLASH_TOTAL_SIZE)
{
return -1;
}
loc_addr = *location;
addr = loc_addr % SPI_FLASH_PAGESIZE;
count = SPI_FLASH_PAGESIZE - addr;
page_cnt = len / SPI_FLASH_PAGESIZE;
remain_cnt = len % SPI_FLASH_PAGESIZE;
if (addr == 0) /* addr is aligned to SPI_FLASH_PAGESIZE */
{
if (page_cnt == 0) /* len < SPI_FLASH_PAGESIZE */
{
ret = prv_spi_flash_write_page(pbuf, loc_addr, len);
CHECK_RET_RETURN(ret);
}
else /* len > SPI_FLASH_PAGESIZE */
{
for (i = 0; i < page_cnt; ++i)
{
ret = prv_spi_flash_write_page(pbuf + i * SPI_FLASH_PAGESIZE, loc_addr, SPI_FLASH_PAGESIZE);
CHECK_RET_RETURN(ret);
loc_addr += SPI_FLASH_PAGESIZE;
}
ret = prv_spi_flash_write_page(pbuf + page_cnt * SPI_FLASH_PAGESIZE, loc_addr, remain_cnt);
CHECK_RET_RETURN(ret);
}
}
else /* addr is not aligned to SPI_FLASH_PAGESIZE */
{
if (page_cnt == 0) /* len < SPI_FLASH_PAGESIZE */
{
if (remain_cnt > count) /* (len + loc_addr) > SPI_FLASH_PAGESIZE */
{
temp = remain_cnt - count;
ret = prv_spi_flash_write_page(pbuf, loc_addr, count);
CHECK_RET_RETURN(ret);
ret = prv_spi_flash_write_page(pbuf + count, loc_addr + count, temp);
CHECK_RET_RETURN(ret);
}
else
{
ret = prv_spi_flash_write_page(pbuf, loc_addr, len);
CHECK_RET_RETURN(ret);
}
}
else /* len > SPI_FLASH_PAGESIZE */
{
len -= count;
page_cnt = len / SPI_FLASH_PAGESIZE;
remain_cnt = len % SPI_FLASH_PAGESIZE;
ret = prv_spi_flash_write_page(pbuf, loc_addr, count);
CHECK_RET_RETURN(ret);
loc_addr += count;
for (i = 0; i < page_cnt; ++i)
{
ret = prv_spi_flash_write_page(pbuf + count + i * SPI_FLASH_PAGESIZE, loc_addr, SPI_FLASH_PAGESIZE);
CHECK_RET_RETURN(ret);
loc_addr += SPI_FLASH_PAGESIZE;
}
if (remain_cnt != 0)
{
ret = prv_spi_flash_write_page(pbuf + count + page_cnt * SPI_FLASH_PAGESIZE, loc_addr, remain_cnt);
CHECK_RET_RETURN(ret);
}
}
}
*location += len;
return ret;
}
int hal_spi_flash_erase_write(const void* buf, int32_t len, uint32_t location)
{
int ret = 0;
ret = hal_spi_flash_erase(location, len);
CHECK_RET_RETURN(ret);
ret = hal_spi_flash_write(buf, len, &location);
return ret;
}
int hal_spi_flash_read(void* buf, int32_t len, uint32_t location)
{
int ret = 0;
int i;
uint8_t* pbuf = (uint8_t*)buf;
if (NULL == pbuf
|| len < 0
|| location > SPI_FLASH_TOTAL_SIZE
|| len + location > SPI_FLASH_TOTAL_SIZE)
{
return -1;
}
SPI_FLASH_CS_ENABLE();
if ((ret = prv_spi_flash_send_cmd(SPI_FLASH_ReadData, location)) != -1)
{
for (i = 0; i < len; ++i)
{
if (prv_spi_flash_send_byte(SPI_FLASH_DUMMY_BYTE, pbuf + i) == -1)
{
ret = -1;
break;
}
}
}
SPI_FLASH_CS_DISABLE();
return ret;
}
int hal_spi_flash_get_id(void)
{
uint8_t tmp1 = 0;
uint8_t tmp2 = 0;
uint8_t tmp3 = 0;
SPI_FLASH_CS_ENABLE();
if (prv_spi_flash_send_byte(SPI_FLASH_JedecDeviceID, NULL) != -1)
{
(void)prv_spi_flash_send_byte(SPI_FLASH_DUMMY_BYTE, &tmp1);
(void)prv_spi_flash_send_byte(SPI_FLASH_DUMMY_BYTE, &tmp2);
(void)prv_spi_flash_send_byte(SPI_FLASH_DUMMY_BYTE, &tmp3);
}
SPI_FLASH_CS_DISABLE();
return (tmp1 << CHOOSE_BIT_16) | (tmp2 << CHOOSE_BIT_8) | tmp3;
}
void hal_spi_flash_power_down(void)
{
SPI_FLASH_CS_ENABLE();
(void)prv_spi_flash_send_byte(SPI_FLASH_PowerDown, NULL);
SPI_FLASH_CS_DISABLE();
}
void hal_spi_flash_wake_up(void)
{
SPI_FLASH_CS_ENABLE();
(void)prv_spi_flash_send_byte(SPI_FLASH_ReleasePowerDown, NULL);
SPI_FLASH_CS_DISABLE();
}
#endif /* HAL_SPI_MODULE_ENABLED */

View File

@@ -0,0 +1,164 @@
/**@defgroup hal_spi_flash SPI Flash Interface
* @ingroup hal
*/
#ifndef _HAL_SPI_FLASH_H_
#define _HAL_SPI_FLASH_H_
#include <stdint.h>
#define SPI_FLASH_PAGESIZE 256
#define SPI_FLASH_SECTOR 4096
#define SPI_FLASH_TOTAL_SIZE 0x4000000
//#define SPI_FLASH_ID 0xEF3015 //W25X16
//#define SPI_FLASH_ID 0xEF4015 //W25Q16
//#define SPI_FLASH_ID 0XEF4017 //W25Q64
//#define SPI_FLASH_ID 0XEF4018 //W25Q128
#define SPI_FLASH_ID 0xEF4017
#if defined(__cplusplus)
extern "C" {
#endif
/**
*@ingroup hal_spi_flash
*@brief config the spi flash.
*
*@par Description:
*This API is used to config the spi flash.
*@attention none.
*
*@param none.
*
*@retval none.
*@par Dependency: none.
*@see none.
*/
void hal_spi_flash_config(void);
/**
*@ingroup hal_spi_flash
*@brief erase data of spi flash.
*
*@par Description:
*This API is used to erase data of spi flash.
*@attention none.
*
*@param addr [IN] the address of the spi flash to erase.
*@param len [IN] the number of bytes to be erased from addr.
Note that at lease 4K byte will be erased by once.
*
*@retval #int 0 if succeed or -1 if failed.
*@par Dependency: none.
*@see none.
*/
int hal_spi_flash_erase(uint32_t addr, int32_t len);
/**
*@ingroup hal_spi_flash
*@brief write data to spi flash.
*
*@par Description:
*This API is used to write data to spi flash. You should call @hal_spi_flash_erase before this.
*location is updated by each call so that you don't need to care about write address if you do
*sequential write.
*@attention none.
*
*@param buf [IN] the data to be wrote to spi flash.
*@param len [IN] the length of the buffer.
*@param location [IN/OUT] the address of the spi flash to write.
*
*@retval #int 0 if succeed or -1 if failed.
*@par Dependency: none.
*@see hal_spi_flash_erase.
*/
int hal_spi_flash_write(const void* buf, int32_t len, uint32_t* location);
/**
*@ingroup hal_spi_flash
*@brief write data to spi flash.
*
*@par Description:
*This API is used to write data to spi flash. You don't need to erase flash by this interface.
*@attention none.
*
*@param buf [IN] the data to be wrote to spi flash.
*@param len [IN] the length of the buffer.
*@param location [IN] the address of the spi flash to write.
*
*@retval #int 0 if succeed or -1 if failed.
*@par Dependency: none.
*@see none.
*/
int hal_spi_flash_erase_write(const void* buf, int32_t len, uint32_t location);
/**
*@ingroup hal_spi_flash
*@brief read data from spi flash.
*
*@par Description:
*This API is used to read data from spi flash.
*@attention none.
*
*@param buf [OUT] buffer to store the data read from spi flash.
*@param len [IN] the length of the buffer.
*@param location [IN] the address of the spi flash to read.
*
*@retval #int 0 if succeed or -1 if failed.
*@par Dependency: none.
*@see none.
*/
int hal_spi_flash_read(void* buf, int32_t len, uint32_t location);
/**
*@ingroup hal_spi_flash
*@brief get ID of the target spi flash.
*
*@par Description:
*This API is used to get ID of the target spi flash.
*@attention none.
*
*@param none.
*
*@retval #int ID of the spi flash.
*@par Dependency: none.
*@see none.
*/
int hal_spi_flash_get_id(void);
/**
*@ingroup hal_spi_flash
*@brief power down the spi flash.
*
*@par Description:
*This API is used to power down the spi flash.
*@attention none.
*
*@param none.
*
*@retval none.
*@par Dependency: none.
*@see none.
*/
void hal_spi_flash_power_down(void);
/**
*@ingroup hal_spi_flash
*@brief wake up the spi flash.
*
*@par Description:
*This API is used to wake up the spi flash.
*@attention none.
*
*@param none.
*
*@retval none.
*@par Dependency: none.
*@see none.
*/
void hal_spi_flash_wake_up(void);
#if defined(__cplusplus)
}
#endif
#endif /* _HAL_SPI_FLASH_H_ */