Skip to content

Commit c23590f

Browse files
committed
more testing on GD32, SPI not working
1 parent 5849de6 commit c23590f

File tree

5 files changed

+105
-13
lines changed

5 files changed

+105
-13
lines changed

Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# * Override toochain: make CROSS=/path/to/arm-none-eabi
44
# * Override UART for downloading: make SERIAL=/dev/ttyS1
55
# * Override hardware config: make BOARD=some_board_in_boards_folder
6+
# * Build for GD32 variants with 12MHz crystal: make EXTRA_CFLAGS=-DGD32F103
67

78
###############################################################################
89

@@ -39,7 +40,7 @@ CFLAGS += -O3 -Wall -g
3940
#CFLAGS += -Os -Wall -g
4041
#CFLAGS += -Wextra -fprofile-generate -fprofile-use
4142
CFLAGS += -fno-common -ffunction-sections -fdata-sections
42-
CFLAGS += $(ARCH_FLAGS) -Ilibopencm3/include/
43+
CFLAGS += $(ARCH_FLAGS) -Ilibopencm3/include/ $(EXTRA_CFLAGS)
4344

4445
LIBM = $(shell $(CC) $(CFLAGS) --print-file-name=libm.a)
4546
LIBC = $(shell $(CC) $(CFLAGS) --print-file-name=libc.a)

spi.c

+13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define likely(x) __builtin_expect((x), 1)
1010
#define unlikely(x) __builtin_expect((x), 0)
1111

12+
/* DMA channel and requests has fixed mapping, do not change */
1213
#define SPI_DMA_RX_CH DMA_CHANNEL2
1314
#define SPI_DMA_TX_CH DMA_CHANNEL3
1415

@@ -66,6 +67,7 @@ uint32_t spi_setup(uint32_t speed_hz) {
6667
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_SPI1_MISO);
6768
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO_SPI1_NSS); /* SS is manual */
6869
gpio_set(GPIOA, GPIO_SPI1_MISO);
70+
gpio_set(GPIOA, GPIO_SPI1_NSS);
6971

7072
/* Reset SPI, SPI_CR1 register cleared, SPI is disabled */
7173
spi_reset(SPI1);
@@ -187,6 +189,16 @@ static void spi_copy_from_usb(uint32_t len) {
187189
}
188190
}
189191

192+
#ifdef GD32F103
193+
/* FIXME: Currently SPI does not work on GD32 under any clock... */
194+
void spi_bulk_read(uint32_t rlen) {
195+
spi_copy_to_usb(rlen);
196+
}
197+
198+
void spi_bulk_write(uint32_t slen) {
199+
spi_copy_from_usb(slen);
200+
}
201+
#else
190202
void spi_bulk_read(uint32_t rlen) {
191203
while (likely(rlen >= USBCDC_PKT_SIZE_DAT)) {
192204
spi_dma_read(USBCDC_PKT_SIZE_DAT);
@@ -254,3 +266,4 @@ void spi_bulk_write(uint32_t slen) {
254266
/* Mark USB RX buffer as used. */
255267
usbcdc_get_remainder(&urbuf);
256268
}
269+
#endif /* GD32F103 */

usbcdc.c

+11
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *
187187
return 0;
188188
}
189189

190+
volatile bool usb_ready = false;
191+
192+
static void cdcacm_reset(void) {
193+
usb_ready = false;
194+
}
195+
190196
static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue) {
191197
usbd_ep_setup(usbd_dev, EP_IN , USB_ENDPOINT_ATTR_BULK, 64, NULL);
192198
usbd_ep_setup(usbd_dev, EP_OUT, USB_ENDPOINT_ATTR_BULK, 64, NULL);
@@ -197,6 +203,10 @@ static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue) {
197203
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
198204
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
199205
cdcacm_control_request);
206+
207+
if (wValue > 0) {
208+
usb_ready = true;
209+
}
200210
}
201211

202212
static usbd_device *usbd_dev; /* Just a pointer, need not to be volatile. */
@@ -215,6 +225,7 @@ void usbcdc_init(void) {
215225

216226
usbd_dev = usbd_init(&st_usbfs_v1_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
217227
usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
228+
usbd_register_reset_callback(usbd_dev, cdcacm_reset);
218229

219230
/* NOTE: Must be called after USB setup since this enables calling usbd_poll(). */
220231
nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);

usbcdc.h

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define USBCDC_PKT_SIZE_INT 16
99

1010
extern char usbcdc_rxbuf[USBCDC_PKT_SIZE_DAT]; /* DMA needs access */
11+
extern volatile bool usb_ready;
1112

1213
void usbcdc_init(void);
1314
uint16_t usbcdc_write(void *buf, size_t len);

vserprog.c

+78-12
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,12 @@ void handle_command(unsigned char command) {
232232
}
233233

234234
#ifdef GD32F103
235-
void rcc_clock_setup_in_hse_12mhz_out_120mhz(void) {
235+
#define RCC_GCFGR_ADCPS_DIV12 ((uint32_t)0x10004000)
236+
#define RCC_GCFGR_ADCPS_DIV16 ((uint32_t)0x1000C000)
237+
#define RCC_GCFGR_USBPS_Div2_5 ((uint32_t)0x00800000)
238+
#define RCC_GCFGR_USBPS_Div2 ((uint32_t)0x00C00000)
239+
240+
static void rcc_clock_setup_in_hse_12mhz_out_96mhz(void) {
236241
/* Enable internal high-speed oscillator. */
237242
rcc_osc_on(RCC_HSI);
238243
rcc_wait_for_osc_ready(RCC_HSI);
@@ -247,16 +252,68 @@ void rcc_clock_setup_in_hse_12mhz_out_120mhz(void) {
247252

248253
/*
249254
* Set prescalers for AHB, ADC, ABP1, ABP2.
250-
* Do this before touching the PLL (TODO: why?).
255+
* Do this before touching the PLL
256+
*/
257+
rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 96MHz Max. 108MHz */
258+
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 12MHz Max. 14MHz */
259+
rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 48MHz Max. 54MHz */
260+
rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 96MHz Max. 108MHz */
261+
RCC_CFGR |= RCC_GCFGR_USBPS_Div2; /* USB Set. 48MHz Max. 48MHz */
262+
263+
/* GD32 has 0-wait-state flash, do not touch anything! */
264+
265+
/*
266+
* Set the PLL multiplication factor to 10.
267+
* 12MHz (external) * 8 (multiplier) = 96MHz
268+
*/
269+
rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL8);
270+
271+
/* Select HSE as PLL source. */
272+
rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK);
273+
274+
/*
275+
* External frequency undivided before entering PLL
276+
* (only valid/needed for HSE).
277+
*/
278+
rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK);
279+
280+
/* Enable PLL oscillator and wait for it to stabilize. */
281+
rcc_osc_on(RCC_PLL);
282+
rcc_wait_for_osc_ready(RCC_PLL);
283+
284+
/* Select PLL as SYSCLK source. */
285+
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK);
286+
287+
/* Set the peripheral clock frequencies used */
288+
rcc_ahb_frequency = 96000000;
289+
rcc_apb1_frequency = 48000000;
290+
rcc_apb2_frequency = 96000000;
291+
}
292+
293+
static void rcc_clock_setup_in_hse_12mhz_out_120mhz(void) {
294+
/* Enable internal high-speed oscillator. */
295+
rcc_osc_on(RCC_HSI);
296+
rcc_wait_for_osc_ready(RCC_HSI);
297+
298+
/* Select HSI as SYSCLK source. */
299+
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK);
300+
301+
/* Enable external high-speed oscillator 12MHz. */
302+
rcc_osc_on(RCC_HSE);
303+
rcc_wait_for_osc_ready(RCC_HSE);
304+
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK);
305+
306+
/*
307+
* Set prescalers for AHB, ADC, ABP1, ABP2.
308+
* Do this before touching the PLL
251309
*/
252310
rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 120MHz Max. 108MHz */
253-
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_ADCPRE) | ((uint32_t)0x10004000); /* ADC Set. 12MHz Max. 14MHz */
311+
RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_ADCPRE) | RCC_GCFGR_ADCPS_DIV12; /* ADC Set. 10MHz Max. 14MHz */
254312
rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 60MHz Max. 54MHz */
255313
rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 120MHz Max. 108MHz */
256-
RCC_CFGR |= ((uint32_t)0x00800000); /* USB Set. 48MHz Max. 48MHz */
314+
RCC_CFGR |= RCC_GCFGR_USBPS_Div2_5; /* USB Set. 48MHz Max. 48MHz */
257315

258-
/* GD32 has 0-wait-state flash */
259-
flash_set_ws(FLASH_ACR_LATENCY_0WS);
316+
/* GD32 has 0-wait-state flash, do not touch anything! */
260317

261318
/*
262319
* Set the PLL multiplication factor to 10.
@@ -319,15 +376,24 @@ int main(void) {
319376

320377
usbcdc_init();
321378
spi_setup(SPI_DEFAULT_CLOCK);
322-
/* Wait 500ms for USB setup to complete before trying to send anything. */
323-
/* FIXME: in ST's USB library there is some way to tell whether USB has finished initialization. */
324-
for (i = 0; i < 10000000; i ++) {
325-
asm("nop");
326-
}
327-
LED_IDLE();
328379

329380
/* The loop. */
330381
while (true) {
382+
/* Wait and blink if USB is not ready. */
383+
LED_IDLE();
384+
while (!usb_ready) {
385+
LED_DISABLE();
386+
for (i = 0; i < 1000000; i ++) {
387+
asm("nop");
388+
}
389+
LED_ENABLE();
390+
for (i = 0; i < 1000000; i ++) {
391+
asm("nop");
392+
}
393+
}
394+
395+
/* Actual thing */
396+
/* TODO: we are blocked here, hence no knowledge about USB bet reset. */
331397
handle_command(usbcdc_getc());
332398
}
333399

0 commit comments

Comments
 (0)