1 /*
2  * Copyright (c) 2019 Winner Microelectronics Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2019-04-04     tyx          1st version
9  */
10 #include <rtthread.h>
11 #include <rtdevice.h>
12 #include "wm_flash_map.h"
13 #include "wm_internal_flash.h"
14 #include "drv_flash.h"
15 
16 #define FLASH_SECTOR (4096)
17 
18 #ifdef RT_USING_SPI
19 static void *_spi0;
20 #endif
21 
22 extern unsigned int flashtotalsize;
23 
wm_flash_total(void)24 rt_uint32_t wm_flash_total(void)
25 {
26     rt_uint32_t total = 0x100000;
27 
28     if (flashtotalsize == 0x200000)
29     {
30         total = 0x200000;
31     }
32 
33     return total;
34 }
35 
wm_flash_addr(void)36 rt_uint32_t wm_flash_addr(void)
37 {
38     return FLASH_BASE_ADDR;
39 }
40 
wm_flash_blksize(void)41 rt_uint32_t wm_flash_blksize(void)
42 {
43     return FLASH_SECTOR;
44 }
45 
wm_flash_read(long offset,void * data,int size)46 int wm_flash_read(long offset, void *data, int size)
47 {
48     offset += FLASH_BASE_ADDR;
49 #ifdef RT_USING_SPI
50     if (_spi0)
51     {
52         rt_spi_take_bus(_spi0);
53     }
54 #endif
55     if (tls_fls_read(offset, data, size) != TLS_FLS_STATUS_OK)
56     {
57         size = -1;
58     }
59 #ifdef RT_USING_SPI
60     if (_spi0)
61     {
62         rt_spi_release_bus(_spi0);
63     }
64 #endif
65 
66     return size;
67 }
68 
wm_flash_write(long offset,void * data,int size)69 int wm_flash_write(long offset, void *data, int size)
70 {
71     offset += FLASH_BASE_ADDR;
72 #ifdef RT_USING_SPI
73     if (_spi0)
74     {
75         rt_spi_take_bus(_spi0);
76     }
77 #endif
78     if (tls_fls_write(offset, data, size) != TLS_FLS_STATUS_OK)
79     {
80         size = -1;
81     }
82 #ifdef RT_USING_SPI
83     if (_spi0)
84     {
85         rt_spi_release_bus(_spi0);
86     }
87 #endif
88 
89     return size;
90 }
91 
wm_flash_erase(long offset,int size)92 int wm_flash_erase(long offset, int size)
93 {
94     int count, sector;
95 
96     offset += FLASH_BASE_ADDR;
97     count = size / FLASH_SECTOR;
98     sector = offset / FLASH_SECTOR;
99 #ifdef RT_USING_SPI
100     if (_spi0)
101     {
102         rt_spi_take_bus(_spi0);
103     }
104 #endif
105     while (count)
106     {
107         if (tls_fls_erase(sector) != TLS_FLS_STATUS_OK)
108         {
109             size = -1;
110             break;
111         }
112         count--;
113         sector++;
114     }
115 #ifdef RT_USING_SPI
116     if (_spi0)
117     {
118         rt_spi_release_bus(_spi0);
119     }
120 #endif
121 
122     return size;
123 }
124 
wm_flash_init(void)125 int wm_flash_init(void)
126 {
127 #ifdef RT_USING_SPI
128     rt_err_t ret;
129 
130     if (_spi0 != RT_NULL)
131     {
132         return 0;
133     }
134 
135     _spi0 = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
136     RT_ASSERT(_spi0 != RT_NULL);
137 
138 #ifdef WM_SPI_BUS_NAME
139     ret = rt_spi_bus_attach_device(_spi0, "flash", WM_SPI_BUS_NAME, RT_NULL);
140 #else
141     ret = rt_spi_bus_attach_device(_spi0, "flash", "spi0", RT_NULL);
142 #endif
143     if (ret != RT_EOK)
144     {
145         rt_free(_spi0);
146         _spi0 = RT_NULL;
147     }
148 
149     if (_spi0)
150     {
151         ((struct rt_spi_device *)_spi0)->config.mode = RT_SPI_MODE_0;
152         ((struct rt_spi_device *)_spi0)->config.data_width = 8;
153         ((struct rt_spi_device *)_spi0)->config.max_hz = 20 * 1000 * 1000;
154     }
155 #endif
156 
157     return 0;
158 }
159