硬件说明:
Nor_flash 采用的是镁光公司的N25Q032A11ESE40F Norflash。
norflash 一共有64个扇区(每个扇区64KB),每个扇区有16个亚扇区(每个亚扇区4KB),在擦除操作时,只支持对扇区、亚扇区、或者整个norflash擦除。
这种norflash 支持3种操作模式:a.标准的SPI协议格式;b.双通道SPI模式;C.四通道SPI模式;
创龙 开发板采用标准的SPI协议格式,详细见 电路图1,图2 图3 是所有SPI命令操作。
图1 Norflash硬件连接关系图
图2 命令(1)
图3 命令(2) 1.Nor_flash 数据结构
- typedef struct {
- int32_t manufacturer_id; /**
- int32_t device_id; /**
- PLATFORM_DEVICE_TYPE type; /**
- int32_t width; /**
- int32_t block_count; /**
- int32_t page_count; /**
- int32_t page_size; /**
- int32_t spare_size; /**
- PLATFORM_DEVHANDLE handle; /**
- int32_t bboffset; /**
- uint32_t column; /**
- uint32_t flags; /**
- void *internal; /**
- uint8_t *bblist; /**
- } PLATFORM_DEVICE_info;
复制代码
2. 初始化nor_flash
- if (deviceid == PLATFORM_DEVID_NORN25Q032A) {
- /* Disable Write protect in NOR */
- //FPGADisableNorWriteProtect();
- nor_status = nor_init();
- if (nor_status != NOR_EOK) {
- IFPRINT(platform_write("platform_device_open: Initialization failed.n"));
- return NULL;
- }
- /* Store the open flags */
- gDeviceNor.flags = flags;
- p_info = &gDeviceNor;
- if (nor_get_details(p_info) != SUCCESS) {
- IFPRINT(platform_write("platform_device_open: Unable to read device information.n"));
- platform_errno = PLATFORM_ERRNO_BADFLASHDEV;
- return NULL;
- }
- p_info->handle = deviceid;
- return p_info;
- }
复制代码
3.配置SPI传输频率
spi_claim(SPI_NOR_CS, SPI_MAX_FREQ);
4.发送SPI读命令
spi_cmd(SPI_NOR_CMD_RDID, idcode, sizeof(idcode));
spi_release();
6.基于platform擦除Norflash platform_device_erase_block(p_device->handle, EMIF_NANDFLASH_TEST_BLOCK)
- if (deviceid == PLATFORM_DEVID_NORN25Q032A) {
- if (block_number > gDeviceNor.block_count) {
- platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT;
- return Platform_EINVALID;
- }
- if (nor_erase (&gDeviceNor, block_number) != SUCCESS) {
- return ( (Platform_STATUS) Platform_EFAIL);
- }
- return Platform_EOK;
复制代码
7. 擦除norflash
- nor_erase( PLATFORM_DEVICE_info* p_device,
- uint32_t sector_number)
- {
- NOR_STATUS ret;
- uint8_t cmd[4];
- uint32_t cmd_len;
- uint32_t address;
- /* Claim the SPI controller */
- spi_claim(SPI_NOR_CS, SPI_MAX_FREQ);
- if (sector_number == SPI_NOR_BE_SECTOR_NUM)
- {
- cmd[0] = SPI_NOR_CMD_BE;
- cmd_len = 1;
- }
- else if (sector_number >= SPI_NOR_SECTOR_COUNT)
- {
- platform_errno = PLATFORM_ERRNO_NORADDR;
- return NOR_EFAIL;
- }
- else
- {
- address = sector_number * SPI_NOR_SECTOR_SIZE;
- cmd[0] = SPI_NOR_CMD_SE;
- cmd[1] = (address >> 16) & 0xff;
- cmd[2] = (address >> 8) & 0xff;
- cmd[3] = (address >> 0) & 0xff;
- cmd_len = 4;
- }
- ret = spi_cmd(SPI_NOR_CMD_WREN, NULL, 0);
- if (ret)
- {
- platform_errno = PLATFORM_ERRNO_DEV_FAIL;
- spi_release();
- return NOR_EFAIL;
- }
-
- ret = spi_cmd_write(cmd, cmd_len, NULL, 0);
- if (ret)
- {
- platform_errno = PLATFORM_ERRNO_DEV_FAIL;
- spi_release();
- return NOR_EFAIL;
- }
-
- ret = nor_wait_ready(SPI_NOR_SECTOR_ERASE_TIMEOUT);
- if (ret)
- {
- platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
- spi_release();
- return NOR_EFAIL;
- }
- spi_release();
- return ret;
- }
复制代码
8.读Nor_flash
- nor_read(
- PLATFORM_DEVICE_info* p_device,
- uint32_t addr,
- uint32_t len,
- uint8_t* buf
- )
- {
- uint8_t cmd[4];
- NOR_STATUS ret_val;
- spi_claim(SPI_NOR_CS, SPI_MAX_FREQ);
- if(addr + len > SPI_NOR_MAX_FLASH_SIZE)
- {
- platform_errno = PLATFORM_ERRNO_FLASHADDR;
- spi_release();
- return NOR_EFAIL;
- }
- cmd[0] = SPI_NOR_CMD_READ;
- cmd[1] = (uint8_t)(addr>>16);
- cmd[2] = (uint8_t)(addr>>8);
- cmd[3] = (uint8_t)addr;
- ret_val = (spi_cmd_read(cmd, 4, buf, len));
- spi_release();
- return (ret_val);
- }
复制代码
9.写Nor_flash
- nor_write
- (
- PLATFORM_DEVICE_info* p_device,
- uint32_t addr,
- uint32_t len,
- uint8_t* buf
- )
- {
- uint32_t page_addr;
- uint32_t byte_addr;
- uint32_t page_size;
- uint32_t loopCount;
- uint32_t chunk_len;
- uint32_t actual;
- uint32_t ret;
- uint8_t cmd[4];
- spi_claim(SPI_NOR_CS, SPI_MAX_FREQ);
- if(addr + len > SPI_NOR_MAX_FLASH_SIZE)
- {
- platform_errno = PLATFORM_ERRNO_NOFREEBLOCKS;
- spi_release();
- return NOR_EFAIL;
- }
- page_size = SPI_NOR_PAGE_SIZE;
- page_addr = addr / page_size;
- byte_addr = addr & (SPI_NOR_PAGE_SIZE - 1); /* % page_size; */
- ret = NOR_EOK;
- for (actual = 0; actual < len; actual += chunk_len)
- {
- ret = spi_cmd(SPI_NOR_CMD_WREN, NULL, 0);
- if (ret)
- {
- platform_errno = PLATFORM_ERRNO_DEV_FAIL;
- spi_release();
- return NOR_EFAIL;
- }
- chunk_len = ((len - actual) < (page_size - byte_addr) ?
- (len - actual) : (page_size - byte_addr));
- cmd[0] = SPI_NOR_CMD_PP;
- cmd[1] = (uint8_t)(addr>>16);
- cmd[2] = (uint8_t)(addr>>8);
- cmd[3] = (uint8_t)addr;
- ret = spi_cmd_write(cmd, 4, buf + actual, chunk_len);
- if (ret)
- {
- platform_errno = PLATFORM_ERRNO_DEV_FAIL;
- spi_release();
- return NOR_EFAIL;
- }
- ret = nor_wait_ready(SPI_NOR_PROG_TIMEOUT);
- if (ret)
- {
- platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
- spi_release();
- return NOR_EFAIL;
- }
- page_addr++;
- addr += chunk_len;
- byte_addr = 0;
- loopCount = 4000;
- while (loopCount--) {
- asm(" NOP");
- }
- }
- spi_release();
- return ((NOR_STATUS) ret);
- }
复制代码
总结:操作SPI_Norflash跟操作Nandflash一样,但是结构不一样。都需要先配置模式,再进行命令操作。
2
|
|
|
|
多谢楼主分享 多多看看你们的试用报告感觉还是能学点东西的
|
|
|
|
|