1 /*
2 * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-05-31 ZYH first version
9 * 2018-12-10 Zohar_Lee format file
10 * 2020-07-10 lik rewrite
11 */
12
13 #include "drv_nor_flash.h"
14
15 #ifdef BSP_USING_NOR_FLASH
16
17 #define DRV_DEBUG
18 #define LOG_TAG "drv.norflash"
19 #include <drv_log.h>
20
21 #define BLOCK_SIZE (64 * 1024)
22 #define FLASH_SIZE (BSP_NOR_FLASH_SIZE)
23 #define BLOCK_COUNTER (FLASH_SIZE / BLOCK_SIZE)
24
25 static struct rt_mutex flash_lock;
26
27 /* RT-Thread MTD device interface */
swm_norflash_read_id(struct rt_mtd_nor_device * device)28 static long swm_norflash_read_id(struct rt_mtd_nor_device *device)
29 {
30 return 0xdeadbeef;
31 }
32
swm_norflash_read(struct rt_mtd_nor_device * device,rt_off_t position,rt_uint8_t * data,rt_uint32_t size)33 static rt_ssize_t swm_norflash_read(struct rt_mtd_nor_device *device,
34 rt_off_t position,
35 rt_uint8_t *data,
36 rt_uint32_t size)
37 {
38 rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
39 memcpy(data, ((const void *)(NORFLM_BASE + position)), size);
40 rt_mutex_release(&flash_lock);
41 return size;
42 }
43
swm_norflash_write(struct rt_mtd_nor_device * device,rt_off_t position,const rt_uint8_t * data,rt_uint32_t size)44 static rt_ssize_t swm_norflash_write(struct rt_mtd_nor_device *device,
45 rt_off_t position,
46 const rt_uint8_t *data,
47 rt_uint32_t size)
48 {
49 rt_size_t i;
50 const rt_uint16_t *hwdata = (const rt_uint16_t *)data;
51 rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
52 for (i = 0; i < size / 2; i++)
53 {
54 NORFL_Write(position, hwdata[i]);
55 position += 2;
56 }
57 rt_mutex_release(&flash_lock);
58 return size;
59 }
60
swm_norflash_erase_block(struct rt_mtd_nor_device * device,rt_off_t offset,rt_uint32_t length)61 static rt_err_t swm_norflash_erase_block(struct rt_mtd_nor_device *device,
62 rt_off_t offset,
63 rt_uint32_t length)
64 {
65 rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
66 NORFL_SectorErase(offset);
67 rt_mutex_release(&flash_lock);
68 return RT_EOK;
69 }
70
71 const static struct rt_mtd_nor_driver_ops swm_mtd_ops =
72 {
73 swm_norflash_read_id,
74 swm_norflash_read,
75 swm_norflash_write,
76 swm_norflash_erase_block};
77
78 static struct rt_mtd_nor_device mtd_device;
79
swm_norflash_init(void)80 int swm_norflash_init(void)
81 {
82 NORFL_InitStructure NORFL_InitStruct;
83
84 PORT->PORTP_SEL0 = 0xAAAAAAAA; //PP0-23 => ADDR0-23
85 PORT->PORTP_SEL1 = 0xAAAA;
86
87 PORT->PORTM_SEL0 = 0xAAAAAAAA; //PM0-15 => DATA15-0
88 PORT->PORTM_INEN = 0xFFFF;
89
90 PORT->PORTM_SEL1 = 0xAAA; //PM16 => OEN、PM17 => WEN、PM18 => NORFL_CSN、PM19 => SDRAM_CSN、PM20 => SRAM_CSN、PM21 => SDRAM_CKE
91
92 NORFL_InitStruct.DataWidth = 16;
93 NORFL_InitStruct.WELowPulseTime = 5;
94 NORFL_InitStruct.OEPreValidTime = 12;
95 NORFL_InitStruct.OperFinishIEn = 0;
96 NORFL_InitStruct.OperTimeoutIEn = 0;
97 NORFL_Init(&NORFL_InitStruct);
98
99 /* set page size and block size */
100 mtd_device.block_size = BLOCK_SIZE; /* 64kByte */
101 mtd_device.ops = &swm_mtd_ops;
102
103 /* initialize mutex */
104 if (rt_mutex_init(&flash_lock, "nor", RT_IPC_FLAG_PRIO) != RT_EOK)
105 {
106 rt_kprintf("init sd lock mutex failed\n");
107 return -RT_ERROR;
108 }
109 mtd_device.block_start = 0;
110 mtd_device.block_end = BLOCK_COUNTER;
111
112 /* register MTD device */
113 rt_mtd_nor_register_device("nor", &mtd_device);
114 return RT_EOK;
115 }
116 INIT_DEVICE_EXPORT(swm_norflash_init);
117
118 #endif /* BSP_USING_NOR_FLASH */
119