123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /*
- * File : rtdef.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2012-10-21 prife the first version
- */
- #include <rtdevice.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "sst25vfxx_mtd.h"
- #ifdef RT_USING_MTD_NOR
- #define NOR_SIM "nor.bin"
- /* JEDEC Manufacturer¡¯s ID */
- #define MF_ID (0xBF)
- /* JEDEC Device ID : Memory Type */
- #define MT_ID (0x25)
- /* JEDEC Device ID: Memory Capacity */
- #define MC_ID_SST25VF016 (0x41)
- #define MC_ID_SST25VF032 (0x4A)
- #define MC_ID_SST25VF064 (0x4B)
- #define BLOCK_SIZE (64*1024)
- #define SST25_MTD(device) ((struct sst25_mtd*)(device))
- struct sst25_mtd
- {
- struct rt_mtd_nor_device parent;
- FILE *file;
- };
- static struct sst25_mtd _sst25_mtd;
- static struct rt_mutex flash_lock;
- /* RT-Thread MTD device interface */
- static rt_uint32_t sst25vfxx_read_id(struct rt_mtd_nor_device *device)
- {
- rt_uint8_t id_recv[3] = {MF_ID, MT_ID, MC_ID_SST25VF016};
- return (id_recv[0] << 16) | (id_recv[1] << 8) | id_recv[2];
- }
- static int sst25vfxx_read(struct rt_mtd_nor_device *device, rt_off_t position, rt_uint8_t *data, rt_size_t size)
- {
- struct sst25_mtd *sst25;
- int result;
- sst25 = SST25_MTD(device);
- RT_ASSERT(sst25 != RT_NULL);
- rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
- fseek(sst25->file, position, SEEK_SET);
- result = fread(data, size, 1, sst25->file);
- if (result < 0)
- rt_kprintf("sst read error.\n");
- rt_mutex_release(&flash_lock);
- return size;
- }
- static int sst25vfxx_write(struct rt_mtd_nor_device *device, rt_off_t position,
- const rt_uint8_t *data, rt_size_t size)
- {
- struct sst25_mtd *sst25;
- int result;
- sst25 = SST25_MTD(device);
- RT_ASSERT(sst25 != RT_NULL);
- rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
- fseek(sst25->file, position, SEEK_SET);
- result = fwrite(data, size, 1, sst25->file);
- if (result < 0)
- rt_kprintf("sst write error.\n");
- rt_mutex_release(&flash_lock);
- return size;
- }
- static char block_buffer[BLOCK_SIZE];
- static rt_err_t sst25vfxx_erase_block(struct rt_mtd_nor_device *device, rt_uint32_t block)
- {
- struct sst25_mtd *sst25;
- int result;
- sst25 = SST25_MTD(device);
- RT_ASSERT(sst25 != RT_NULL);
- rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
- memset(block_buffer, 0xFF, BLOCK_SIZE);
- fseek(sst25->file, block, SEEK_SET);
- result = fwrite(block_buffer, BLOCK_SIZE, 1, sst25->file);
- if (result < 0)
- rt_kprintf("sst write error.\n");
- rt_mutex_release(&flash_lock);
- return RT_EOK;
- }
- const static struct rt_mtd_nor_driver_ops sst25vfxx_mtd_ops =
- {
- sst25vfxx_read_id,
- sst25vfxx_read,
- sst25vfxx_write,
- sst25vfxx_erase_block,
- };
- static rt_err_t sst25vfxx_hw_init(struct sst25_mtd *mtd)
- {
- mtd = mtd;
- return RT_EOK;
- }
- /**
- * SST25vfxx API
- */
- rt_err_t sst25vfxx_mtd_init(const char *nor_name,
- rt_uint32_t block_start,
- rt_uint32_t block_end)
- {
- rt_uint32_t id, total_block;
- struct sst25_mtd *sst25;
- struct rt_mtd_nor_device *mtd;
- sst25 = &_sst25_mtd;
- mtd = &(sst25->parent);
- /* set page size and block size */
- mtd->block_size = 64 * 1024; /* 64kByte */
- mtd->ops = &sst25vfxx_mtd_ops;
- /* initialize mutex */
- if (rt_mutex_init(&flash_lock, nor_name, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- rt_kprintf("init sd lock mutex failed\n");
- }
- /* initialize flash */
- id = sst25vfxx_read_id(mtd);
- switch (id & 0xff)
- {
- case MC_ID_SST25VF016:
- total_block = (16 * 1024 * 1024 / 8) / mtd->block_size;
- break;
- case MC_ID_SST25VF032:
- total_block = (32 * 1024 * 1024 / 8) / mtd->block_size;
- break;
- case MC_ID_SST25VF064:
- total_block = (64 * 1024 * 1024 / 8) / mtd->block_size;
- break;
- default:
- rt_kprintf("SST25 detection error, id: %x\n", id);
- return -RT_ERROR;
- }
- if ((block_end == RT_UINT32_MAX) || (block_end == 0))
- {
- block_end = total_block;
- }
- else if (block_end > total_block)
- {
- rt_kprintf("SST25 total block: %d, out of block\n", total_block);
- return -RT_ERROR;
- }
- mtd->block_start = block_start;
- mtd->block_end = block_end;
- /* open nor file, if not exist, then create it */
- sst25->file = fopen(NOR_SIM, "rb+");
- if (sst25->file == NULL)
- {
- int i;
- /* create a file to simulate nor */
- sst25->file = fopen(NOR_SIM, "wb+");
- memset(block_buffer, 0xFF, sizeof(block_buffer));
- for (i = 0; i < total_block; i++)
- {
- fseek(sst25->file, i * BLOCK_SIZE, SEEK_SET);
- fwrite(block_buffer, BLOCK_SIZE, 1, sst25->file);
- }
- }
- fseek(sst25->file, 0, SEEK_SET);
- /* initialize hardware */
- sst25vfxx_hw_init(&_sst25_mtd);
- /* register MTD device */
- rt_mtd_nor_register_device("nor", mtd);
- return RT_EOK;
- }
- #ifdef RT_USING_FINSH
- #include <finsh.h>
- void nor_erase(void)
- {
- rt_uint32_t index;
- struct rt_mtd_nor_device *mtd;
- mtd = SST25_MTD(&_sst25_mtd);
- for (index = mtd->block_start; index < mtd->block_end; index ++)
- {
- sst25vfxx_erase_block(mtd, index * mtd->block_size);
- }
- }
- FINSH_FUNCTION_EXPORT(nor_erase, erase all block in SPI flash);
- #endif
- #endif
|