Skip to content

Commit e36d481

Browse files
Yuriy Vynnychekcarlescufi
authored andcommitted
drivers: flash: Improve Telink B91 Flash Write and Erase APIs
- Fixed from Flash to Flash write issue (added heap usage). - Speed up Flash Erase operation (based on erase size). Signed-off-by: Yuriy Vynnychek <[email protected]>
1 parent 76c80fb commit e36d481

File tree

1 file changed

+59
-6
lines changed

1 file changed

+59
-6
lines changed

drivers/flash/soc_flash_b91.c

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,24 @@
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 */
1627
struct 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)
92122
static 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

Comments
 (0)