Skip to content

Commit 5153f38

Browse files
authored
[bsp][wch][risc-v] add drv_flash for ch32v307. (#10306)
* [bsp][wch][risc-v] add drv_flash for ch32v307. * [bsp][wch][risc-v] 1. add yml file for ch32v307. 2. fix programs a word at chip flash timeout. 3. priority use of fast mode. * [bsp][wch][risc-v] fix spi device for ch32v307.
1 parent 31ff6fe commit 5153f38

File tree

14 files changed

+626
-18
lines changed

14 files changed

+626
-18
lines changed

bsp/wch/risc-v/Libraries/ch32_drivers/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ if GetDepend('SOC_RISCV_FAMILY_CH32'):
5151
if GetDepend('BSP_USING_HWTIMER'):
5252
src += ['drv_hwtimer.c']
5353

54+
if GetDepend(['BSP_USING_ON_CHIP_FLASH']):
55+
src += ['drv_flash.c']
56+
5457
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
5558

5659
Return('group')
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
/*
2+
* Copyright (c) 2006-2023, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-05-20 Chasel first version
9+
*
10+
*/
11+
12+
#include <rtconfig.h>
13+
#include <rtdef.h>
14+
15+
#ifdef BSP_USING_ON_CHIP_FLASH
16+
#include "drv_flash.h"
17+
#include <board.h>
18+
19+
#if defined(RT_USING_FAL)
20+
#include "fal.h"
21+
#endif
22+
23+
#define DRV_DEBUG
24+
#define LOG_TAG "drv.flash"
25+
#include <drv_log.h>
26+
27+
#define FLASH_PAGE_SIZE 4096
28+
29+
/* @note If there is no down-frequency processing, the timeout time needs to be modified */
30+
#ifdef ProgramTimeout
31+
#undef ProgramTimeout
32+
#define ProgramTimeout ((uint32_t)0x00010000)
33+
#endif
34+
35+
36+
/**
37+
* @brief Gets the page of a given address
38+
* @param Addr: Address of the FLASH Memory
39+
* @retval The page of a given address
40+
*/
41+
static uint32_t GetPage(uint32_t addr)
42+
{
43+
uint32_t page = 0;
44+
page = RT_ALIGN_DOWN(addr, FLASH_PAGE_SIZE);
45+
return page;
46+
}
47+
48+
/**
49+
* Read data from flash.
50+
* @note This operation's units is word.
51+
*
52+
* @param addr flash address
53+
* @param buf buffer to store read data
54+
* @param size read bytes size
55+
*
56+
* @return result
57+
*/
58+
int ch32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
59+
{
60+
size_t i;
61+
62+
if ((addr + size) > CH32_FLASH_END_ADDRESS)
63+
{
64+
LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size));
65+
return -RT_EINVAL;
66+
}
67+
68+
for (i = 0; i < size; i++, buf++, addr++)
69+
{
70+
*buf = *(rt_uint8_t *) addr;
71+
}
72+
73+
return size;
74+
}
75+
76+
/**
77+
* Write data to flash.
78+
* @note This operation's units is word.
79+
* @note This operation must after erase. @see flash_erase.
80+
*
81+
* @param addr flash address
82+
* @param buf the write data buffer
83+
* @param size write bytes size
84+
*
85+
* @return result
86+
*/
87+
int ch32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
88+
{
89+
rt_err_t result = RT_EOK;
90+
FLASH_Status status = 0;
91+
rt_uint32_t end_addr = addr + size;
92+
93+
if (addr % 4 != 0)
94+
{
95+
LOG_E("write addr must be 4-byte alignment");
96+
return -RT_EINVAL;
97+
}
98+
99+
if ((end_addr) > CH32_FLASH_END_ADDRESS)
100+
{
101+
LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
102+
return -RT_EINVAL;
103+
}
104+
105+
if (((addr & 0x000000FF) == 0) && (size & 0xFFFFFF00)) {
106+
rt_uint32_t fast_size = (size & 0xFFFFFF00);
107+
108+
status = FLASH_ROM_WRITE(addr, (rt_uint32_t *)buf, fast_size);
109+
if (status != FLASH_COMPLETE) {
110+
LOG_E("FLASH ROM Write Fail\r\n");
111+
return -RT_ERROR;
112+
}
113+
114+
addr += fast_size;
115+
buf += fast_size;
116+
}
117+
if (addr == end_addr) {
118+
return size;
119+
}
120+
121+
FLASH_Access_Clock_Cfg(FLASH_Access_SYSTEM_HALF);
122+
FLASH_Unlock();
123+
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
124+
125+
while (addr < end_addr)
126+
{
127+
status = FLASH_ProgramWord(addr, *((rt_uint32_t *)buf));
128+
if (status == FLASH_COMPLETE)
129+
{
130+
if (*(rt_uint32_t *)addr != *(rt_uint32_t *)buf)
131+
{
132+
result = -RT_ERROR;
133+
break;
134+
}
135+
addr += 4;
136+
buf += 4;
137+
}
138+
else
139+
{
140+
result = -RT_ERROR;
141+
break;
142+
}
143+
}
144+
145+
FLASH_Lock();
146+
FLASH_Access_Clock_Cfg(FLASH_Access_SYSTEM);
147+
148+
if (result != RT_EOK)
149+
{
150+
return result;
151+
}
152+
153+
return size;
154+
}
155+
156+
/**
157+
* Erase data on flash .
158+
* @note This operation is irreversible.
159+
* @note This operation's units is different which on many chips.
160+
*
161+
* @param addr flash address
162+
* @param size erase bytes size
163+
*
164+
* @return result
165+
*/
166+
int ch32_flash_erase(rt_uint32_t addr, size_t size)
167+
{
168+
rt_err_t result = RT_EOK;
169+
FLASH_Status status = 0;
170+
uint32_t num_page = 0;
171+
uint32_t i = 0;
172+
rt_uint32_t total_size = size;
173+
174+
if ((addr + size) > CH32_FLASH_END_ADDRESS)
175+
{
176+
LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void *)(addr + size));
177+
return -RT_EINVAL;
178+
}
179+
180+
if (((addr & 0x000000FF) == 0) && (total_size & 0xFFFFFF00)) {
181+
rt_uint32_t fast_size = (total_size & 0xFFFFFF00);
182+
183+
status = FLASH_ROM_ERASE(addr, fast_size);
184+
if (status != FLASH_COMPLETE) {
185+
LOG_E("FLASH ROM Erase Fail\r\n");
186+
return -RT_ERROR;
187+
}
188+
189+
addr += fast_size;
190+
total_size -= fast_size;
191+
}
192+
193+
if (0 == total_size) {
194+
return size;
195+
}
196+
197+
FLASH_Access_Clock_Cfg(FLASH_Access_SYSTEM_HALF);
198+
FLASH_Unlock();
199+
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
200+
201+
num_page = (total_size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE;
202+
203+
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
204+
205+
for(i = 0; (i < num_page) && (status == FLASH_COMPLETE); i++)
206+
{
207+
status = FLASH_ErasePage(GetPage(addr + i * FLASH_PAGE_SIZE)); //Erase 4KB
208+
209+
if(status != FLASH_COMPLETE)
210+
{
211+
LOG_E("FLASH Erase Fail\r\n");
212+
result = -RT_ERROR;
213+
goto __exit;
214+
}
215+
}
216+
217+
__exit:
218+
FLASH_Lock();
219+
FLASH_Access_Clock_Cfg(FLASH_Access_SYSTEM);
220+
221+
if (result != RT_EOK)
222+
{
223+
return -RT_ERROR;
224+
}
225+
226+
return size;
227+
}
228+
229+
230+
#if defined(RT_USING_FAL)
231+
232+
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
233+
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
234+
static int fal_flash_erase(long offset, size_t size);
235+
236+
const struct fal_flash_dev ch32_onchip_flash = { "onchip_flash", CH32_FLASH_START_ADRESS, CH32_FLASH_SIZE, FLASH_PAGE_SIZE, {NULL, fal_flash_read, fal_flash_write, fal_flash_erase}, 8, {} ,};
237+
238+
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
239+
{
240+
return ch32_flash_read(ch32_onchip_flash.addr + offset, buf, size);
241+
}
242+
243+
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
244+
{
245+
return ch32_flash_write(ch32_onchip_flash.addr + offset, buf, size);
246+
}
247+
248+
static int fal_flash_erase(long offset, size_t size)
249+
{
250+
return ch32_flash_erase(ch32_onchip_flash.addr + offset, size);
251+
}
252+
253+
#endif
254+
#endif /* BSP_USING_ON_CHIP_FLASH */
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2006-2023, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-05-20 Chasel first version
9+
*/
10+
11+
#ifndef __DRV_FLASH_H__
12+
#define __DRV_FLASH_H__
13+
14+
#include <rtthread.h>
15+
#include "rtdevice.h"
16+
#include <rthw.h>
17+
#include <drv_common.h>
18+
19+
#ifdef __cplusplus
20+
extern "C" {
21+
#endif
22+
23+
int ch32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size);
24+
int ch32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size);
25+
int ch32_flash_erase(rt_uint32_t addr, size_t size);
26+
27+
#ifdef __cplusplus
28+
}
29+
#endif
30+
31+
#endif /* __DRV_FLASH_H__ */

bsp/wch/risc-v/Libraries/ch32_drivers/drv_spi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,9 @@ static rt_err_t ch32_spi_init(struct ch32_spi *spi_drv, struct rt_spi_configurat
322322
/* min prescaler 256 */
323323
spi_handle->Init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
324324
}
325+
SystemCoreClockUpdate();
325326
LOG_D("sys freq: %d, pclk2 freq: %d, SPI limiting freq: %d, BaudRatePrescaler: %d",
326-
HAL_RCC_GetSysClockFreq(),
327+
SystemCoreClock,
327328
SPI_APB_CLOCK,
328329
cfg->max_hz,
329330
spi_handle->Init.SPI_BaudRatePrescaler);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
devices.gpio:
2+
kconfig:
3+
- CONFIG_BSP_USING_GPIO=y
4+
devices.adc:
5+
kconfig:
6+
- CONFIG_BSP_USING_ADC=y
7+
- CONFIG_BSP_USING_ADC1=y
8+
- CONFIG_BSP_USING_ADC2=n
9+
devices.dac:
10+
kconfig:
11+
- CONFIG_BSP_USING_DAC=y
12+
- CONFIG_BSP_USING_DAC_CHANNEL1=y
13+
- CONFIG_BSP_USING_DAC_CHANNEL2=n
14+
devices.i2c:
15+
kconfig:
16+
- CONFIG_BSP_USING_SOFT_I2C=y
17+
- CONFIG_BSP_USING_I2C1=y
18+
- CONFIG_BSP_USING_I2C2=y
19+
devices.spi:
20+
kconfig:
21+
- CONFIG_BSP_USING_SPI=y
22+
- CONFIG_BSP_USING_SPI1=n
23+
- CONFIG_BSP_USING_SPI2=n
24+
- CONFIG_BSP_USING_SPI3=y
25+
devices.uart:
26+
kconfig:
27+
- CONFIG_BSP_USING_UART=y
28+
devices.watchdog:
29+
kconfig:
30+
- CONFIG_BSP_USING_IWDT=y
31+
devices.flash:
32+
kconfig:
33+
- CONFIG_BSP_USING_ON_CHIP_FLASH=y

0 commit comments

Comments
 (0)