55 */
66
77#define DT_DRV_COMPAT telink_b91_flash_controller
8- #define FLASH_SIZE DT_REG_SIZE(DT_INST(0, soc_nv_flash))
8+ #define FLASH_SIZE DT_REG_SIZE(DT_INST(0, soc_nv_flash))
9+ #define FLASH_ORIGIN DT_REG_ADDR(DT_INST(0, soc_nv_flash))
910
1011#include "flash.h"
12+ #include <string.h>
1113#include <zephyr/device.h>
1214#include <zephyr/drivers/flash.h>
1315
1416
17+ /* driver definitions */
18+ #define BLOCK_64K_SIZE (0x10000u)
19+ #define BLOCK_64K_PAGES (BLOCK_64K_SIZE / PAGE_SIZE)
20+ #define BLOCK_32K_SIZE (0x8000u)
21+ #define BLOCK_32K_PAGES (BLOCK_32K_SIZE / PAGE_SIZE)
22+ #define SECTOR_SIZE (0x1000u)
23+ #define SECTOR_PAGES (SECTOR_SIZE / PAGE_SIZE)
24+
25+
1526/* driver data structure */
1627struct flash_b91_data {
1728 struct k_sem write_lock ;
@@ -66,7 +77,7 @@ static int flash_b91_erase(const struct device *dev, off_t offset, size_t len)
6677 return - EINVAL ;
6778 }
6879
69- /* Erase can be done only by pages */
80+ /* erase can be done only by pages */
7081 if (((offset % PAGE_SIZE ) != 0 ) || ((len % PAGE_SIZE ) != 0 )) {
7182 return - EINVAL ;
7283 }
@@ -76,10 +87,29 @@ static int flash_b91_erase(const struct device *dev, off_t offset, size_t len)
7687 return - EACCES ;
7788 }
7889
79- /* erase flash page by page */
80- for (int i = 0 ; i < page_nums ; i ++ ) {
81- flash_erase_page (offset );
82- offset += PAGE_SIZE ;
90+ while (page_nums ) {
91+ /* check for 64K erase possibility, then check for 32K and so on.. */
92+ if ((page_nums >= BLOCK_64K_PAGES ) && ((offset % BLOCK_64K_SIZE ) == 0 )) {
93+ /* erase 64K block */
94+ flash_erase_64kblock (offset );
95+ page_nums -= BLOCK_64K_PAGES ;
96+ offset += BLOCK_64K_SIZE ;
97+ } else if ((page_nums >= BLOCK_32K_PAGES ) && ((offset % BLOCK_32K_SIZE ) == 0 )) {
98+ /* erase 32K block */
99+ flash_erase_32kblock (offset );
100+ page_nums -= BLOCK_32K_PAGES ;
101+ offset += BLOCK_32K_SIZE ;
102+ } else if ((page_nums >= SECTOR_PAGES ) && ((offset % SECTOR_SIZE ) == 0 )) {
103+ /* erase sector */
104+ flash_erase_sector (offset );
105+ page_nums -= SECTOR_PAGES ;
106+ offset += SECTOR_SIZE ;
107+ } else {
108+ /* erase page */
109+ flash_erase_page (offset );
110+ page_nums -- ;
111+ offset += PAGE_SIZE ;
112+ }
83113 }
84114
85115 /* release semaphore */
@@ -92,6 +122,7 @@ static int flash_b91_erase(const struct device *dev, off_t offset, size_t len)
92122static int flash_b91_write (const struct device * dev , off_t offset ,
93123 const void * data , size_t len )
94124{
125+ void * buf = NULL ;
95126 struct flash_b91_data * dev_data = dev -> data ;
96127
97128 /* return SUCCESS if len equals 0 (required by tests/drivers/flash) */
@@ -109,9 +140,31 @@ static int flash_b91_write(const struct device *dev, off_t offset,
109140 return - EACCES ;
110141 }
111142
143+ /* need to store data in intermediate RAM buffer in case from flash to flash write */
144+ if (((uint32_t )data >= FLASH_ORIGIN ) &&
145+ ((uint32_t )data < (FLASH_ORIGIN + FLASH_SIZE ))) {
146+
147+ buf = k_malloc (len );
148+ if (buf == NULL ) {
149+ k_sem_give (& dev_data -> write_lock );
150+ return - ENOMEM ;
151+ }
152+
153+ /* copy Flash data to RAM */
154+ memcpy (buf , data , len );
155+
156+ /* substitute data with allocated buffer */
157+ data = buf ;
158+ }
159+
112160 /* write flash */
113161 flash_write_page (offset , len , (unsigned char * )data );
114162
163+ /* if ram memory is allocated for flash writing it should be free */
164+ if (buf != NULL ) {
165+ k_free (buf );
166+ }
167+
115168 /* release semaphore */
116169 k_sem_give (& dev_data -> write_lock );
117170
0 commit comments