mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
Merge pull request #2485 from cesanta/ch32v307
Add example for ch32v307
This commit is contained in:
commit
f86c14abb3
31
examples/wch/ch32v307-make-baremetal-builtin/Makefile
Normal file
31
examples/wch/ch32v307-make-baremetal-builtin/Makefile
Normal file
@ -0,0 +1,31 @@
|
||||
CFLAGS = -W -Wall -Wextra -Wno-error -Wundef -Wshadow -Wdouble-promotion
|
||||
CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion
|
||||
CFLAGS += -ffunction-sections -fdata-sections #-fmessage-length=0 -fsigned-char
|
||||
CFLAGS += -march=rv32imafc -mabi=ilp32f #-msmall-data-limit=8 -mno-save-restore
|
||||
CFLAGS += -DSYSCLK_FREQ_144MHz_HSE -I. -Ivendor -g3 -Os $(CFLAGS_EXTRA)
|
||||
|
||||
LDFLAGS = -T vendor/link.ld -nostartfiles --specs=nano.specs #--specs=nosys.specs
|
||||
LDFLAGS += -lc -lgcc -Wl,--gc-sections #-Wl,-Map=$@.map
|
||||
|
||||
SOURCES = main.c mongoose.c vendor/system_ch32v30x.c vendor/startup_ch32v30x_D8C.S
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
RM = cmd /C del /Q /F /S
|
||||
else
|
||||
RM = rm -rf
|
||||
endif
|
||||
|
||||
all: firmware.bin
|
||||
|
||||
firmware.bin: firmware.elf
|
||||
riscv64-unknown-elf-objcopy -O binary $< $@
|
||||
ls -l firmware.*
|
||||
|
||||
firmware.elf: $(SOURCES) hal.h Makefile
|
||||
riscv64-unknown-elf-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
flash: firmware.bin
|
||||
wchisp flash $<
|
||||
|
||||
clean:
|
||||
$(RM) firmware.* *.su
|
140
examples/wch/ch32v307-make-baremetal-builtin/hal.h
Normal file
140
examples/wch/ch32v307-make-baremetal-builtin/hal.h
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright (c) 2023 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ch32v30x.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define BIT(x) (1UL << (x))
|
||||
#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set))
|
||||
#define PIN(bank, num) ((((bank) - 'A') << 8) | (num))
|
||||
#define PINNO(pin) (pin & 255)
|
||||
#define PINBANK(pin) (pin >> 8)
|
||||
|
||||
extern uint32_t SystemCoreClock;
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
static inline void spin(volatile uint32_t count) {
|
||||
while (count--) (void) 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
GPIO_MODE_INPUT,
|
||||
GPIO_MODE_OUTPUT_10M,
|
||||
GPIO_MODE_OUTPUT_2M,
|
||||
GPIO_MODE_OUTPUT_50M
|
||||
};
|
||||
enum { GPIO_OTYPE_PP, GPIO_OTYPE_OD, GPIO_OTYPE_AF_PP, GPIO_AF_OD };
|
||||
enum { GPIO_ITYPE_ANALOG, GPIO_ITYPE_FLOAT, GPIO_ITYPE_PUPD };
|
||||
#define GPIO(N) ((GPIO_TypeDef *) (GPIOA_BASE + 0x400 * (N)))
|
||||
|
||||
static GPIO_TypeDef *gpio_bank(uint16_t pin) {
|
||||
return GPIO(PINBANK(pin));
|
||||
}
|
||||
static inline void gpio_toggle(uint16_t pin) {
|
||||
GPIO_TypeDef *gpio = gpio_bank(pin);
|
||||
uint32_t mask = BIT(PINNO(pin));
|
||||
gpio->BSHR = mask << (gpio->OUTDR & mask ? 16 : 0);
|
||||
}
|
||||
static inline bool gpio_read(uint16_t pin) {
|
||||
return gpio_bank(pin)->INDR & BIT(PINNO(pin)) ? true : false;
|
||||
}
|
||||
static inline void gpio_write(uint16_t pin, bool val) {
|
||||
GPIO_TypeDef *gpio = gpio_bank(pin);
|
||||
gpio->BSHR = BIT(PINNO(pin)) << (val ? 0 : 16);
|
||||
}
|
||||
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t cfg) {
|
||||
GPIO_TypeDef *gpio = gpio_bank(pin);
|
||||
uint8_t bank = (uint8_t) PINBANK(pin), no = (uint8_t) PINNO(pin);
|
||||
RCC->APB2PCENR |= BIT(bank + 2); // Enable GPIO clock, section 3.4.7
|
||||
if (mode != GPIO_MODE_INPUT && cfg == GPIO_OTYPE_AF_PP) {
|
||||
RCC->APB2PCENR |= BIT(0); // Enable AFIO
|
||||
}
|
||||
volatile uint32_t *r = &gpio->CFGLR;
|
||||
if (no > 7) r = &gpio->CFGHR, no -= 8;
|
||||
uint8_t v = (mode & 3U) | ((cfg & 3U) << 2);
|
||||
CLRSET(*r, 15U << (no * 4), v << (no * 4));
|
||||
}
|
||||
static inline void gpio_input(uint16_t pin) {
|
||||
gpio_init(pin, GPIO_MODE_INPUT, GPIO_ITYPE_PUPD);
|
||||
}
|
||||
static inline void gpio_output(uint16_t pin) {
|
||||
gpio_init(pin, GPIO_MODE_OUTPUT_50M, GPIO_OTYPE_PP);
|
||||
}
|
||||
|
||||
static inline void uart_init(USART_TypeDef *uart, unsigned baud) {
|
||||
uint16_t rx = 0, tx = 0; // pins
|
||||
uint32_t freq = 0; // Bus frequency. UART1 is on APB2, rest on APB1
|
||||
|
||||
if (uart == USART1) freq = SystemCoreClock, RCC->APB2PCENR |= BIT(14);
|
||||
if (uart == USART2) freq = SystemCoreClock, RCC->APB1PCENR |= BIT(17);
|
||||
if (uart == USART3) freq = SystemCoreClock, RCC->APB1PCENR |= BIT(18);
|
||||
|
||||
if (uart == USART1) tx = PIN('A', 9), rx = PIN('A', 10);
|
||||
// if (uart == USART1) tx = PIN('B', 6), rx = PIN('B', 7);
|
||||
if (uart == USART2) tx = PIN('A', 2), rx = PIN('A', 3);
|
||||
if (uart == USART3) tx = PIN('B', 10), rx = PIN('B', 11);
|
||||
|
||||
gpio_init(tx, GPIO_MODE_OUTPUT_50M, GPIO_OTYPE_AF_PP);
|
||||
gpio_init(rx, GPIO_MODE_INPUT, GPIO_ITYPE_PUPD);
|
||||
uart->CTLR1 = 0; // Disable this UART
|
||||
unsigned div = freq / baud * 100 / 16; // 18.3
|
||||
uart->BRR = (uint16_t) (((div / 100) << 4) | (div * 16 / 100));
|
||||
uart->CTLR1 = BIT(13) | BIT(2) | BIT(3); // Set UE, RE, TE
|
||||
}
|
||||
static inline void uart_write_byte(USART_TypeDef *uart, uint8_t byte) {
|
||||
uart->DATAR = byte;
|
||||
volatile int timeout = 999;
|
||||
while ((uart->STATR & BIT(7)) == 0 && timeout--) spin(1);
|
||||
}
|
||||
static inline void uart_write_buf(USART_TypeDef *uart, char *buf, size_t len) {
|
||||
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
|
||||
}
|
||||
static inline int uart_read_ready(USART_TypeDef *uart) {
|
||||
return uart->STATR & BIT(5); // If RXNE bit is set, data is ready
|
||||
}
|
||||
static inline uint8_t uart_read_byte(USART_TypeDef *uart) {
|
||||
return (uint8_t) (uart->DATAR & 255U);
|
||||
}
|
||||
|
||||
static inline void ethernet_init(void) {
|
||||
// Set 60MHz ethernet clock
|
||||
RCC->CTLR &= ~BIT(28); // PLL3 off
|
||||
CLRSET(RCC->CFGR2, 15U << 4, 1U << 4); // 3.4.12: PREDIV2 = 2
|
||||
CLRSET(RCC->CFGR2, 15U << 12, 13U << 12); // 3.4.12: PLL3MUL = 15
|
||||
RCC->CTLR |= BIT(28); // PLL3 on
|
||||
|
||||
EXTEN->EXTEN_CTR |= EXTEN_ETH_10M_EN; // Enable built-in 10M PHY
|
||||
#if 0
|
||||
// RMII mode
|
||||
// 27.1.3 : init pins
|
||||
uint16_t pins[] = {PIN('A', 1), PIN('A', 2), PIN('A', 7),
|
||||
PIN('B', 11), PIN('B', 12), PIN('B', 13),
|
||||
PIN('C', 1), PIN('C', 4), PIN('C', 5)};
|
||||
for (size_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) {
|
||||
gpio_init(pins[i], GPIO_MODE_OUTPUT_50M, GPIO_OTYPE_AF_PP);
|
||||
}
|
||||
AFIO->PCFR1 |= BIT(23); // Use RMII
|
||||
#endif
|
||||
RCC->AHBPCENR |= BIT(14) | BIT(15) | BIT(16); // Enable MAC, TX, RX
|
||||
NVIC_EnableIRQ(ETH_IRQn);
|
||||
// NVIC_SetPriority(ETH_IRQn, 0);
|
||||
}
|
||||
|
||||
static inline void rng_init(void) {
|
||||
RNG->CR |= RNG_CR_RNGEN;
|
||||
}
|
||||
static inline uint32_t rng_read(void) {
|
||||
return RNG->DR;
|
||||
}
|
||||
|
||||
// Helper macro for MAC generation
|
||||
#define ROM_MAC ((uint8_t *) (0X1ffff7e8 + 5))
|
||||
#define GENERATE_LOCALLY_ADMINISTERED_MAC() \
|
||||
{ 2, ROM_MAC[0], ROM_MAC[1], ROM_MAC[2], ROM_MAC[3], ROM_MAC[4] }
|
131
examples/wch/ch32v307-make-baremetal-builtin/main.c
Normal file
131
examples/wch/ch32v307-make-baremetal-builtin/main.c
Normal file
@ -0,0 +1,131 @@
|
||||
// Copyright (c) 2023 Cesanta Software Limited
|
||||
|
||||
#include "hal.h"
|
||||
#include "mongoose.h"
|
||||
|
||||
#define BTN_PIN PIN('B', 3) // On-board user button
|
||||
#define LED1_PIN PIN('A', 15) // On-board red LED
|
||||
#define LED2_PIN PIN('B', 4) // On-board blue LED
|
||||
#define LED_PIN LED2_PIN
|
||||
#define UART_DEBUG USART1
|
||||
|
||||
#define BLINK_PERIOD_MS 1000 // LED_PIN blinking period in millis
|
||||
|
||||
static volatile uint64_t s_ticks; // Milliseconds since boot
|
||||
__attribute__((interrupt())) void SysTick_Handler(void) {
|
||||
s_ticks++;
|
||||
SysTick->SR = 0;
|
||||
}
|
||||
|
||||
uint64_t mg_millis(void) { // Let Mongoose use our uptime function
|
||||
return s_ticks; // Return number of milliseconds since boot
|
||||
}
|
||||
|
||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
||||
uint32_t r = rng_read();
|
||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_fn(void *arg) {
|
||||
gpio_toggle(LED_PIN); // Blink LED_PIN
|
||||
struct mg_tcpip_if *ifp = arg; // And show
|
||||
const char *names[] = {"down", "up", "req", "ready"}; // network stats
|
||||
MG_INFO(("Ethernet: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
||||
ifp->ndrop, ifp->nerr));
|
||||
}
|
||||
|
||||
void SysTick_Init(void) {
|
||||
SysTick->CMP = SystemCoreClock / 1000 - 1;
|
||||
SysTick->CNT = 0;
|
||||
SysTick->SR = 0;
|
||||
SysTick->CTLR = BIT(0) | BIT(1) | BIT(2) | BIT(3);
|
||||
NVIC_EnableIRQ(SysTicK_IRQn);
|
||||
}
|
||||
|
||||
static void mg_putchar(char ch, void *param) {
|
||||
uart_write_byte(param, ch);
|
||||
}
|
||||
|
||||
// https://mongoose.ws/documentation/#2-minute-integration-guide
|
||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
if (ev == MG_EV_HTTP_MSG) {
|
||||
// The MG_EV_HTTP_MSG event means HTTP request. `hm` holds parsed request,
|
||||
// see https://mongoose.ws/documentation/#struct-mg_http_message
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
|
||||
// If the requested URI is "/api/hi", send a simple JSON response back
|
||||
if (mg_http_match_uri(hm, "/api/hi")) {
|
||||
// Use mg_http_reply() API function to generate JSON response. It adds a
|
||||
// Content-Length header automatically. In the response, we show
|
||||
// the requested URI and HTTP body:
|
||||
mg_http_reply(c, 200, "", "{%m:%m,%m:%m}\n", // See mg_snprintf doc
|
||||
MG_ESC("uri"), mg_print_esc, hm->uri.len, hm->uri.ptr,
|
||||
MG_ESC("body"), mg_print_esc, hm->body.len, hm->body.ptr);
|
||||
} else {
|
||||
// For all other URIs, serve static content
|
||||
mg_http_reply(c, 200, "", "hi tick %llu\n", s_ticks); // See mg_snprintf doc
|
||||
}
|
||||
}
|
||||
(void) fn_data;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
SystemCoreClockUpdate();
|
||||
SysTick_Init();
|
||||
|
||||
gpio_output(LED_PIN); // Setup LED
|
||||
uart_init(UART_DEBUG, 115200); // Initialise debug printf
|
||||
|
||||
struct mg_mgr mgr; // Initialise
|
||||
mg_mgr_init(&mgr); // Mongoose event manager
|
||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
||||
mg_log_set_fn(mg_putchar, UART_DEBUG);
|
||||
|
||||
ethernet_init(); // Initialise ethernet pins
|
||||
MG_INFO(("Starting, CPU freq %g MHz", (double) SystemCoreClock / 1000000));
|
||||
|
||||
// Initialise Mongoose network stack
|
||||
struct mg_tcpip_driver_stm32_data driver_data = {.mdc_cr = 1};
|
||||
struct mg_tcpip_if mif = {.mac = GENERATE_LOCALLY_ADMINISTERED_MAC(),
|
||||
// Uncomment below for static configuration:
|
||||
// .ip = mg_htonl(MG_U32(192, 168, 0, 223)),
|
||||
// .mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
||||
// .gw = mg_htonl(MG_U32(192, 168, 0, 1)),
|
||||
.driver = &mg_tcpip_driver_stm32,
|
||||
.driver_data = &driver_data};
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif);
|
||||
|
||||
MG_INFO(("MAC: %M. Waiting for IP...", mg_print_mac, mif.mac));
|
||||
while (mif.state != MG_TCPIP_STATE_READY) {
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
}
|
||||
|
||||
MG_INFO(("Initialising application..."));
|
||||
mg_http_listen(&mgr, "http://0.0.0.0", fn, NULL);
|
||||
|
||||
MG_INFO(("Starting event loop"));
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Newlib syscalls overrides. IO retargeting, and malloc
|
||||
int _write(int fd, char *ptr, int len) {
|
||||
if (fd == 1 || fd == 2) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
|
||||
return len;
|
||||
}
|
||||
|
||||
void *_sbrk(ptrdiff_t incr) {
|
||||
extern char _end[];
|
||||
extern char _heap_end[];
|
||||
static char *curbrk = _end;
|
||||
if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) return NULL - 1;
|
||||
curbrk += incr;
|
||||
return curbrk - incr;
|
||||
}
|
1
examples/wch/ch32v307-make-baremetal-builtin/mongoose.c
Symbolic link
1
examples/wch/ch32v307-make-baremetal-builtin/mongoose.c
Symbolic link
@ -0,0 +1 @@
|
||||
../../../mongoose.c
|
1
examples/wch/ch32v307-make-baremetal-builtin/mongoose.h
Symbolic link
1
examples/wch/ch32v307-make-baremetal-builtin/mongoose.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../../mongoose.h
|
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
// See https://mongoose.ws/documentation/#build-options
|
||||
#define MG_ARCH MG_ARCH_NEWLIB
|
||||
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_ENABLE_CUSTOM_MILLIS 1
|
||||
#define MG_ENABLE_CUSTOM_RANDOM 1
|
||||
//#define MG_ENABLE_PACKED_FS 1
|
||||
#define MG_ENABLE_FILE 0
|
||||
#define MG_ENABLE_DRIVER_STM32 1
|
||||
#define MG_ENABLE_LINES 1
|
5239
examples/wch/ch32v307-make-baremetal-builtin/vendor/ch32v30x.h
vendored
Normal file
5239
examples/wch/ch32v307-make-baremetal-builtin/vendor/ch32v30x.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
390
examples/wch/ch32v307-make-baremetal-builtin/vendor/core_riscv.c
vendored
Normal file
390
examples/wch/ch32v307-make-baremetal-builtin/vendor/core_riscv.c
vendored
Normal file
@ -0,0 +1,390 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : core_riscv.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : RISC-V Core Peripheral Access Layer Source File
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
#include <stdint.h>
|
||||
|
||||
/* define compiler specific symbols */
|
||||
#if defined ( __CC_ARM )
|
||||
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_FFLAGS
|
||||
*
|
||||
* @brief Return the Floating-Point Accrued Exceptions
|
||||
*
|
||||
* @return fflags value
|
||||
*/
|
||||
uint32_t __get_FFLAGS(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "fflags" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_FFLAGS
|
||||
*
|
||||
* @brief Set the Floating-Point Accrued Exceptions
|
||||
*
|
||||
* @param value - set FFLAGS value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_FFLAGS(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw fflags, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_FRM
|
||||
*
|
||||
* @brief Return the Floating-Point Dynamic Rounding Mode
|
||||
*
|
||||
* @return frm value
|
||||
*/
|
||||
uint32_t __get_FRM(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "frm" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_FRM
|
||||
*
|
||||
* @brief Set the Floating-Point Dynamic Rounding Mode
|
||||
*
|
||||
* @param value - set frm value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_FRM(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw frm, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_FCSR
|
||||
*
|
||||
* @brief Return the Floating-Point Control and Status Register
|
||||
*
|
||||
* @return fcsr value
|
||||
*/
|
||||
uint32_t __get_FCSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "fcsr" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_FCSR
|
||||
*
|
||||
* @brief Set the Floating-Point Dynamic Rounding Mode
|
||||
*
|
||||
* @param value - set fcsr value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_FCSR(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw fcsr, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MSTATUS
|
||||
*
|
||||
* @brief Return the Machine Status Register
|
||||
*
|
||||
* @return mstatus value
|
||||
*/
|
||||
uint32_t __get_MSTATUS(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mstatus" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MSTATUS
|
||||
*
|
||||
* @brief Set the Machine Status Register
|
||||
*
|
||||
* @param value - set mstatus value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MSTATUS(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mstatus, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MISA
|
||||
*
|
||||
* @brief Return the Machine ISA Register
|
||||
*
|
||||
* @return misa value
|
||||
*/
|
||||
uint32_t __get_MISA(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "misa" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MISA
|
||||
*
|
||||
* @brief Set the Machine ISA Register
|
||||
*
|
||||
* @param value - set misa value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MISA(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw misa, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MTVEC
|
||||
*
|
||||
* @brief Return the Machine Trap-Vector Base-Address Register
|
||||
*
|
||||
* @return mtvec value
|
||||
*/
|
||||
uint32_t __get_MTVEC(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mtvec" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MTVEC
|
||||
*
|
||||
* @brief Set the Machine Trap-Vector Base-Address Register
|
||||
*
|
||||
* @param value - set mtvec value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MTVEC(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mtvec, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MSCRATCH
|
||||
*
|
||||
* @brief Return the Machine Seratch Register
|
||||
*
|
||||
* @return mscratch value
|
||||
*/
|
||||
uint32_t __get_MSCRATCH(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mscratch" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MSCRATCH
|
||||
*
|
||||
* @brief Set the Machine Seratch Register
|
||||
*
|
||||
* @param value - set mscratch value
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void __set_MSCRATCH(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mscratch, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MEPC
|
||||
*
|
||||
* @brief Return the Machine Exception Program Register
|
||||
*
|
||||
* @return mepc value
|
||||
*/
|
||||
uint32_t __get_MEPC(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mepc" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MEPC
|
||||
*
|
||||
* @brief Set the Machine Exception Program Register
|
||||
*
|
||||
* @return mepc value
|
||||
*/
|
||||
void __set_MEPC(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mepc, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MCAUSE
|
||||
*
|
||||
* @brief Return the Machine Cause Register
|
||||
*
|
||||
* @return mcause value
|
||||
*/
|
||||
uint32_t __get_MCAUSE(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mcause" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MEPC
|
||||
*
|
||||
* @brief Set the Machine Cause Register
|
||||
*
|
||||
* @return mcause value
|
||||
*/
|
||||
void __set_MCAUSE(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mcause, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MTVAL
|
||||
*
|
||||
* @brief Return the Machine Trap Value Register
|
||||
*
|
||||
* @return mtval value
|
||||
*/
|
||||
uint32_t __get_MTVAL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mtval" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __set_MTVAL
|
||||
*
|
||||
* @brief Set the Machine Trap Value Register
|
||||
*
|
||||
* @return mtval value
|
||||
*/
|
||||
void __set_MTVAL(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("csrw mtval, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MVENDORID
|
||||
*
|
||||
* @brief Return Vendor ID Register
|
||||
*
|
||||
* @return mvendorid value
|
||||
*/
|
||||
uint32_t __get_MVENDORID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mvendorid" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MARCHID
|
||||
*
|
||||
* @brief Return Machine Architecture ID Register
|
||||
*
|
||||
* @return marchid value
|
||||
*/
|
||||
uint32_t __get_MARCHID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "marchid" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MIMPID
|
||||
*
|
||||
* @brief Return Machine Implementation ID Register
|
||||
*
|
||||
* @return mimpid value
|
||||
*/
|
||||
uint32_t __get_MIMPID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mimpid" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_MHARTID
|
||||
*
|
||||
* @brief Return Hart ID Register
|
||||
*
|
||||
* @return mhartid value
|
||||
*/
|
||||
uint32_t __get_MHARTID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "csrr %0," "mhartid" : "=r" (result) );
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __get_SP
|
||||
*
|
||||
* @brief Return SP Register
|
||||
*
|
||||
* @return SP value
|
||||
*/
|
||||
uint32_t __get_SP(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ( "mv %0," "sp" : "=r"(result) : );
|
||||
return (result);
|
||||
}
|
||||
|
378
examples/wch/ch32v307-make-baremetal-builtin/vendor/core_riscv.h
vendored
Normal file
378
examples/wch/ch32v307-make-baremetal-builtin/vendor/core_riscv.h
vendored
Normal file
@ -0,0 +1,378 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : core_riscv.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : RISC-V Core Peripheral Access Layer Header File for CH32V30x
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
#ifndef __CORE_RISCV_H__
|
||||
#define __CORE_RISCV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* IO definitions */
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /* defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /* defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /* defines 'write only' permissions */
|
||||
#define __IO volatile /* defines 'read / write' permissions */
|
||||
|
||||
/* Standard Peripheral Library old types (maintained for legacy purpose) */
|
||||
typedef __I uint64_t vuc64; /* Read Only */
|
||||
typedef __I uint32_t vuc32; /* Read Only */
|
||||
typedef __I uint16_t vuc16; /* Read Only */
|
||||
typedef __I uint8_t vuc8; /* Read Only */
|
||||
|
||||
typedef const uint64_t uc64; /* Read Only */
|
||||
typedef const uint32_t uc32; /* Read Only */
|
||||
typedef const uint16_t uc16; /* Read Only */
|
||||
typedef const uint8_t uc8; /* Read Only */
|
||||
|
||||
typedef __I int64_t vsc64; /* Read Only */
|
||||
typedef __I int32_t vsc32; /* Read Only */
|
||||
typedef __I int16_t vsc16; /* Read Only */
|
||||
typedef __I int8_t vsc8; /* Read Only */
|
||||
|
||||
typedef const int64_t sc64; /* Read Only */
|
||||
typedef const int32_t sc32; /* Read Only */
|
||||
typedef const int16_t sc16; /* Read Only */
|
||||
typedef const int8_t sc8; /* Read Only */
|
||||
|
||||
typedef __IO uint64_t vu64;
|
||||
typedef __IO uint32_t vu32;
|
||||
typedef __IO uint16_t vu16;
|
||||
typedef __IO uint8_t vu8;
|
||||
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef __IO int64_t vs64;
|
||||
typedef __IO int32_t vs32;
|
||||
typedef __IO int16_t vs16;
|
||||
typedef __IO int8_t vs8;
|
||||
|
||||
typedef int64_t s64;
|
||||
typedef int32_t s32;
|
||||
typedef int16_t s16;
|
||||
typedef int8_t s8;
|
||||
|
||||
typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus;
|
||||
|
||||
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
|
||||
|
||||
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
|
||||
|
||||
#define RV_STATIC_INLINE static inline
|
||||
|
||||
/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
|
||||
typedef struct{
|
||||
__I uint32_t ISR[8];
|
||||
__I uint32_t IPR[8];
|
||||
__IO uint32_t ITHRESDR;
|
||||
__IO uint32_t RESERVED;
|
||||
__IO uint32_t CFGR;
|
||||
__I uint32_t GISR;
|
||||
__IO uint8_t VTFIDR[4];
|
||||
uint8_t RESERVED0[12];
|
||||
__IO uint32_t VTFADDR[4];
|
||||
uint8_t RESERVED1[0x90];
|
||||
__O uint32_t IENR[8];
|
||||
uint8_t RESERVED2[0x60];
|
||||
__O uint32_t IRER[8];
|
||||
uint8_t RESERVED3[0x60];
|
||||
__O uint32_t IPSR[8];
|
||||
uint8_t RESERVED4[0x60];
|
||||
__O uint32_t IPRR[8];
|
||||
uint8_t RESERVED5[0x60];
|
||||
__IO uint32_t IACTR[8];
|
||||
uint8_t RESERVED6[0xE0];
|
||||
__IO uint8_t IPRIOR[256];
|
||||
uint8_t RESERVED7[0x810];
|
||||
__IO uint32_t SCTLR;
|
||||
}PFIC_Type;
|
||||
|
||||
/* memory mapped structure for SysTick */
|
||||
typedef struct
|
||||
{
|
||||
__IO u32 CTLR;
|
||||
__IO u32 SR;
|
||||
__IO u64 CNT;
|
||||
__IO u64 CMP;
|
||||
}SysTick_Type;
|
||||
|
||||
|
||||
#define PFIC ((PFIC_Type *) 0xE000E000 )
|
||||
#define NVIC PFIC
|
||||
#define NVIC_KEY1 ((uint32_t)0xFA050000)
|
||||
#define NVIC_KEY2 ((uint32_t)0xBCAF0000)
|
||||
#define NVIC_KEY3 ((uint32_t)0xBEEF0000)
|
||||
|
||||
#define SysTick ((SysTick_Type *) 0xE000F000)
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __enable_irq
|
||||
*
|
||||
* @brief Enable Global Interrupt
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
RV_STATIC_INLINE void __enable_irq()
|
||||
{
|
||||
__asm volatile ("csrw 0x800, %0" : : "r" (0x6088) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __disable_irq
|
||||
*
|
||||
* @brief Disable Global Interrupt
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
RV_STATIC_INLINE void __disable_irq()
|
||||
{
|
||||
__asm volatile ("csrw 0x800, %0" : : "r" (0x6000) );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __NOP
|
||||
*
|
||||
* @brief nop
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
RV_STATIC_INLINE void __NOP()
|
||||
{
|
||||
__asm volatile ("nop");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_EnableIRQ
|
||||
*
|
||||
* @brief Enable Interrupt
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_DisableIRQ
|
||||
*
|
||||
* @brief Disable Interrupt
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_GetStatusIRQ
|
||||
*
|
||||
* @brief Get Interrupt Enable State
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return 1 - Interrupt Enable
|
||||
* 0 - Interrupt Disable
|
||||
*/
|
||||
RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_GetPendingIRQ
|
||||
*
|
||||
* @brief Get Interrupt Pending State
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return 1 - Interrupt Pending Enable
|
||||
* 0 - Interrupt Pending Disable
|
||||
*/
|
||||
RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_SetPendingIRQ
|
||||
*
|
||||
* @brief Set Interrupt Pending
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_ClearPendingIRQ
|
||||
*
|
||||
* @brief Clear Interrupt Pending
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_GetActive
|
||||
*
|
||||
* @brief Get Interrupt Active State
|
||||
*
|
||||
* @param IRQn: Interrupt Numbers
|
||||
*
|
||||
* @return 1 - Interrupt Active
|
||||
* 0 - Interrupt No Active
|
||||
*/
|
||||
RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_SetPriority
|
||||
*
|
||||
* @brief Set Interrupt Priority
|
||||
*
|
||||
* @param IRQn - Interrupt Numbers
|
||||
* priority -
|
||||
* bit7 - pre-emption priority
|
||||
* bit6~bit4 - subpriority
|
||||
* @return None
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
|
||||
{
|
||||
NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __WFI
|
||||
*
|
||||
* @brief Wait for Interrupt
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
NVIC->SCTLR &= ~(1<<3); // wfi
|
||||
asm volatile ("wfi");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn __WFE
|
||||
*
|
||||
* @brief Wait for Events
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
t = NVIC->SCTLR;
|
||||
NVIC->SCTLR |= (1<<3)|(1<<5); // (wfi->wfe)+(__sev)
|
||||
NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5));
|
||||
asm volatile ("wfi");
|
||||
asm volatile ("wfi");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetVTFIRQ
|
||||
*
|
||||
* @brief Set VTF Interrupt
|
||||
*
|
||||
* @param add - VTF interrupt service function base address.
|
||||
* IRQn -Interrupt Numbers
|
||||
* num - VTF Interrupt Numbers
|
||||
* NewState - DISABLE or ENABLE
|
||||
* @return None
|
||||
*/
|
||||
RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){
|
||||
if(num > 3) return ;
|
||||
|
||||
if (NewState != DISABLE)
|
||||
{
|
||||
NVIC->VTFIDR[num] = IRQn;
|
||||
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1);
|
||||
}
|
||||
else{
|
||||
NVIC->VTFIDR[num] = IRQn;
|
||||
NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NVIC_SystemReset
|
||||
*
|
||||
* @brief Initiate a system reset request
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
RV_STATIC_INLINE void NVIC_SystemReset(void)
|
||||
{
|
||||
NVIC->CFGR = NVIC_KEY3|(1<<7);
|
||||
}
|
||||
|
||||
|
||||
/* Core_Exported_Functions */
|
||||
extern uint32_t __get_FFLAGS(void);
|
||||
extern void __set_FFLAGS(uint32_t value);
|
||||
extern uint32_t __get_FRM(void);
|
||||
extern void __set_FRM(uint32_t value);
|
||||
extern uint32_t __get_FCSR(void);
|
||||
extern void __set_FCSR(uint32_t value);
|
||||
extern uint32_t __get_MSTATUS(void);
|
||||
extern void __set_MSTATUS(uint32_t value);
|
||||
extern uint32_t __get_MISA(void);
|
||||
extern void __set_MISA(uint32_t value);
|
||||
extern uint32_t __get_MTVEC(void);
|
||||
extern void __set_MTVEC(uint32_t value);
|
||||
extern uint32_t __get_MSCRATCH(void);
|
||||
extern void __set_MSCRATCH(uint32_t value);
|
||||
extern uint32_t __get_MEPC(void);
|
||||
extern void __set_MEPC(uint32_t value);
|
||||
extern uint32_t __get_MCAUSE(void);
|
||||
extern void __set_MCAUSE(uint32_t value);
|
||||
extern uint32_t __get_MTVAL(void);
|
||||
extern void __set_MTVAL(uint32_t value);
|
||||
extern uint32_t __get_MVENDORID(void);
|
||||
extern uint32_t __get_MARCHID(void);
|
||||
extern uint32_t __get_MIMPID(void);
|
||||
extern uint32_t __get_MHARTID(void);
|
||||
extern uint32_t __get_SP(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
1
examples/wch/ch32v307-make-baremetal-builtin/vendor/link.ld
vendored
Normal file
1
examples/wch/ch32v307-make-baremetal-builtin/vendor/link.ld
vendored
Normal file
@ -0,0 +1 @@
|
||||
ENTRY( _start )
__stack_size = 2048;
PROVIDE( _stack_size = __stack_size );
MEMORY
{
/* CH32V30x_D8C - CH32V305RB-CH32V305FB
CH32V30x_D8 - CH32V303CB-CH32V303RB
*/
/*
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
*/
/* CH32V30x_D8C - CH32V307VC-CH32V307WC-CH32V307RC
CH32V30x_D8 - CH32V303VC-CH32V303RC
FLASH + RAM supports the following configuration
FLASH-192K + RAM-128K
FLASH-224K + RAM-96K
FLASH-256K + RAM-64K
FLASH-288K + RAM-32K
*/
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 288K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
SECTIONS
{
.init :
{
_sinit = .;
. = ALIGN(4);
KEEP(*(SORT_NONE(.init)))
. = ALIGN(4);
_einit = .;
} >FLASH AT>FLASH
.vector :
{
*(.vector);
. = ALIGN(64);
} >FLASH AT>FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text.*)
*(.rodata)
*(.rodata*)
*(.gnu.linkonce.t.*)
. = ALIGN(4);
} >FLASH AT>FLASH
.fini :
{
KEEP(*(SORT_NONE(.fini)))
. = ALIGN(4);
} >FLASH AT>FLASH
PROVIDE( _etext = . );
PROVIDE( _eitcm = . );
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH AT>FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH AT>FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH AT>FLASH
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >FLASH AT>FLASH
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >FLASH AT>FLASH
.dalign :
{
. = ALIGN(4);
PROVIDE(_data_vma = .);
} >RAM AT>FLASH
.dlalign :
{
. = ALIGN(4);
PROVIDE(_data_lma = .);
} >FLASH AT>FLASH
.data :
{
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.sdata2.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
PROVIDE( _edata = .);
} >RAM AT>FLASH
.bss :
{
. = ALIGN(4);
PROVIDE( _sbss = .);
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss*)
*(.gnu.linkonce.b.*)
*(COMMON*)
. = ALIGN(4);
PROVIDE( _ebss = .);
} >RAM AT>FLASH
PROVIDE( _end = _ebss);
PROVIDE( end = . );
.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
{
PROVIDE( _heap_end = . );
. = ALIGN(4);
PROVIDE(_susrstack = . );
. = . + __stack_size;
PROVIDE( _eusrstack = .);
} >RAM
}
|
369
examples/wch/ch32v307-make-baremetal-builtin/vendor/startup_ch32v30x_D8.S
vendored
Normal file
369
examples/wch/ch32v307-make-baremetal-builtin/vendor/startup_ch32v30x_D8.S
vendored
Normal file
@ -0,0 +1,369 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : startup_ch32v30x_D8.s
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V303x vector table for eclipse toolchain.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
.global _start
|
||||
.align 1
|
||||
_start:
|
||||
j handle_reset
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00100073
|
||||
.section .vector,"ax",@progbits
|
||||
.align 1
|
||||
_vector_base:
|
||||
.option norvc;
|
||||
.word _start
|
||||
.word 0
|
||||
.word NMI_Handler /* NMI */
|
||||
.word HardFault_Handler /* Hard Fault */
|
||||
.word 0
|
||||
.word Ecall_M_Mode_Handler /* Ecall M Mode */
|
||||
.word 0
|
||||
.word 0
|
||||
.word Ecall_U_Mode_Handler /* Ecall U Mode */
|
||||
.word Break_Point_Handler /* Break Point */
|
||||
.word 0
|
||||
.word 0
|
||||
.word SysTick_Handler /* SysTick */
|
||||
.word 0
|
||||
.word SW_Handler /* SW */
|
||||
.word 0
|
||||
/* External Interrupts */
|
||||
.word WWDG_IRQHandler /* Window Watchdog */
|
||||
.word PVD_IRQHandler /* PVD through EXTI Line detect */
|
||||
.word TAMPER_IRQHandler /* TAMPER */
|
||||
.word RTC_IRQHandler /* RTC */
|
||||
.word FLASH_IRQHandler /* Flash */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_IRQHandler /* EXTI Line 0 */
|
||||
.word EXTI1_IRQHandler /* EXTI Line 1 */
|
||||
.word EXTI2_IRQHandler /* EXTI Line 2 */
|
||||
.word EXTI3_IRQHandler /* EXTI Line 3 */
|
||||
.word EXTI4_IRQHandler /* EXTI Line 4 */
|
||||
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
||||
.word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
|
||||
.word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
|
||||
.word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
|
||||
.word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
|
||||
.word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
|
||||
.word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
|
||||
.word ADC1_2_IRQHandler /* ADC1_2 */
|
||||
.word USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */
|
||||
.word USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */
|
||||
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.word CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.word EXTI9_5_IRQHandler /* EXTI Line 9..5 */
|
||||
.word TIM1_BRK_IRQHandler /* TIM1 Break */
|
||||
.word TIM1_UP_IRQHandler /* TIM1 Update */
|
||||
.word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word TIM4_IRQHandler /* TIM4 */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word USART3_IRQHandler /* USART3 */
|
||||
.word EXTI15_10_IRQHandler /* EXTI Line 15..10 */
|
||||
.word RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */
|
||||
.word 0
|
||||
.word TIM8_BRK_IRQHandler /* TIM8 Break */
|
||||
.word TIM8_UP_IRQHandler /* TIM8 Update */
|
||||
.word TIM8_TRG_COM_IRQHandler /* TIM8 Trigger and Commutation */
|
||||
.word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.word RNG_IRQHandler /* RNG */
|
||||
.word FSMC_IRQHandler /* FSMC */
|
||||
.word SDIO_IRQHandler /* SDIO */
|
||||
.word TIM5_IRQHandler /* TIM5 */
|
||||
.word SPI3_IRQHandler /* SPI3 */
|
||||
.word UART4_IRQHandler /* UART4 */
|
||||
.word UART5_IRQHandler /* UART5 */
|
||||
.word TIM6_IRQHandler /* TIM6 */
|
||||
.word TIM7_IRQHandler /* TIM7 */
|
||||
.word DMA2_Channel1_IRQHandler /* DMA2 Channel 1 */
|
||||
.word DMA2_Channel2_IRQHandler /* DMA2 Channel 2 */
|
||||
.word DMA2_Channel3_IRQHandler /* DMA2 Channel 3 */
|
||||
.word DMA2_Channel4_IRQHandler /* DMA2 Channel 4 */
|
||||
.word DMA2_Channel5_IRQHandler /* DMA2 Channel 5 */
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word OTG_FS_IRQHandler /* OTGFS */
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word UART6_IRQHandler /* UART6 */
|
||||
.word UART7_IRQHandler /* UART7 */
|
||||
.word UART8_IRQHandler /* UART8 */
|
||||
.word TIM9_BRK_IRQHandler /* TIM9 Break */
|
||||
.word TIM9_UP_IRQHandler /* TIM9 Update */
|
||||
.word TIM9_TRG_COM_IRQHandler /* TIM9 Trigger and Commutation */
|
||||
.word TIM9_CC_IRQHandler /* TIM9 Capture Compare */
|
||||
.word TIM10_BRK_IRQHandler /* TIM10 Break */
|
||||
.word TIM10_UP_IRQHandler /* TIM10 Update */
|
||||
.word TIM10_TRG_COM_IRQHandler /* TIM10 Trigger and Commutation */
|
||||
.word TIM10_CC_IRQHandler /* TIM10 Capture Compare */
|
||||
.word DMA2_Channel6_IRQHandler /* DMA2 Channel 6 */
|
||||
.word DMA2_Channel7_IRQHandler /* DMA2 Channel 7 */
|
||||
.word DMA2_Channel8_IRQHandler /* DMA2 Channel 8 */
|
||||
.word DMA2_Channel9_IRQHandler /* DMA2 Channel 9 */
|
||||
.word DMA2_Channel10_IRQHandler /* DMA2 Channel 10 */
|
||||
.word DMA2_Channel11_IRQHandler /* DMA2 Channel 11 */
|
||||
|
||||
.option rvc;
|
||||
|
||||
.section .text.vector_handler, "ax", @progbits
|
||||
.weak NMI_Handler /* NMI */
|
||||
.weak HardFault_Handler /* Hard Fault */
|
||||
.weak Ecall_M_Mode_Handler /* Ecall M Mode */
|
||||
.weak Ecall_U_Mode_Handler /* Ecall U Mode */
|
||||
.weak Break_Point_Handler /* Break Point */
|
||||
.weak SysTick_Handler /* SysTick */
|
||||
.weak SW_Handler /* SW */
|
||||
.weak WWDG_IRQHandler /* Window Watchdog */
|
||||
.weak PVD_IRQHandler /* PVD through EXTI Line detect */
|
||||
.weak TAMPER_IRQHandler /* TAMPER */
|
||||
.weak RTC_IRQHandler /* RTC */
|
||||
.weak FLASH_IRQHandler /* Flash */
|
||||
.weak RCC_IRQHandler /* RCC */
|
||||
.weak EXTI0_IRQHandler /* EXTI Line 0 */
|
||||
.weak EXTI1_IRQHandler /* EXTI Line 1 */
|
||||
.weak EXTI2_IRQHandler /* EXTI Line 2 */
|
||||
.weak EXTI3_IRQHandler /* EXTI Line 3 */
|
||||
.weak EXTI4_IRQHandler /* EXTI Line 4 */
|
||||
.weak DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
||||
.weak DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
|
||||
.weak DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
|
||||
.weak DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
|
||||
.weak DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
|
||||
.weak DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
|
||||
.weak DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
|
||||
.weak ADC1_2_IRQHandler /* ADC1_2 */
|
||||
.weak USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */
|
||||
.weak USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */
|
||||
.weak CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.weak CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.weak EXTI9_5_IRQHandler /* EXTI Line 9..5 */
|
||||
.weak TIM1_BRK_IRQHandler /* TIM1 Break */
|
||||
.weak TIM1_UP_IRQHandler /* TIM1 Update */
|
||||
.weak TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
|
||||
.weak TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.weak TIM2_IRQHandler /* TIM2 */
|
||||
.weak TIM3_IRQHandler /* TIM3 */
|
||||
.weak TIM4_IRQHandler /* TIM4 */
|
||||
.weak I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.weak I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.weak I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.weak I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.weak SPI1_IRQHandler /* SPI1 */
|
||||
.weak SPI2_IRQHandler /* SPI2 */
|
||||
.weak USART1_IRQHandler /* USART1 */
|
||||
.weak USART2_IRQHandler /* USART2 */
|
||||
.weak USART3_IRQHandler /* USART3 */
|
||||
.weak EXTI15_10_IRQHandler /* EXTI Line 15..10 */
|
||||
.weak RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */
|
||||
.weak TIM8_BRK_IRQHandler /* TIM8 Break */
|
||||
.weak TIM8_UP_IRQHandler /* TIM8 Update */
|
||||
.weak TIM8_TRG_COM_IRQHandler /* TIM8 Trigger and Commutation */
|
||||
.weak TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.weak RNG_IRQHandler /* RNG */
|
||||
.weak FSMC_IRQHandler /* FSMC */
|
||||
.weak SDIO_IRQHandler /* SDIO */
|
||||
.weak TIM5_IRQHandler /* TIM5 */
|
||||
.weak SPI3_IRQHandler /* SPI3 */
|
||||
.weak UART4_IRQHandler /* UART4 */
|
||||
.weak UART5_IRQHandler /* UART5 */
|
||||
.weak TIM6_IRQHandler /* TIM6 */
|
||||
.weak TIM7_IRQHandler /* TIM7 */
|
||||
.weak DMA2_Channel1_IRQHandler /* DMA2 Channel 1 */
|
||||
.weak DMA2_Channel2_IRQHandler /* DMA2 Channel 2 */
|
||||
.weak DMA2_Channel3_IRQHandler /* DMA2 Channel 3 */
|
||||
.weak DMA2_Channel4_IRQHandler /* DMA2 Channel 4 */
|
||||
.weak DMA2_Channel5_IRQHandler /* DMA2 Channel 5 */
|
||||
.weak OTG_FS_IRQHandler /* OTGFS */
|
||||
.weak UART6_IRQHandler /* UART6 */
|
||||
.weak UART7_IRQHandler /* UART7 */
|
||||
.weak UART8_IRQHandler /* UART8 */
|
||||
.weak TIM9_BRK_IRQHandler /* TIM9 Break */
|
||||
.weak TIM9_UP_IRQHandler /* TIM9 Update */
|
||||
.weak TIM9_TRG_COM_IRQHandler /* TIM9 Trigger and Commutation */
|
||||
.weak TIM9_CC_IRQHandler /* TIM9 Capture Compare */
|
||||
.weak TIM10_BRK_IRQHandler /* TIM10 Break */
|
||||
.weak TIM10_UP_IRQHandler /* TIM10 Update */
|
||||
.weak TIM10_TRG_COM_IRQHandler /* TIM10 Trigger and Commutation */
|
||||
.weak TIM10_CC_IRQHandler /* TIM10 Capture Compare */
|
||||
.weak DMA2_Channel6_IRQHandler /* DMA2 Channel 6 */
|
||||
.weak DMA2_Channel7_IRQHandler /* DMA2 Channel 7 */
|
||||
.weak DMA2_Channel8_IRQHandler /* DMA2 Channel 8 */
|
||||
.weak DMA2_Channel9_IRQHandler /* DMA2 Channel 9 */
|
||||
.weak DMA2_Channel10_IRQHandler /* DMA2 Channel 10 */
|
||||
.weak DMA2_Channel11_IRQHandler /* DMA2 Channel 11 */
|
||||
|
||||
NMI_Handler: 1: j 1b
|
||||
HardFault_Handler: 1: j 1b
|
||||
Ecall_M_Mode_Handler: 1: j 1b
|
||||
Ecall_U_Mode_Handler: 1: j 1b
|
||||
Break_Point_Handler: 1: j 1b
|
||||
SysTick_Handler: 1: j 1b
|
||||
SW_Handler: 1: j 1b
|
||||
WWDG_IRQHandler: 1: j 1b
|
||||
PVD_IRQHandler: 1: j 1b
|
||||
TAMPER_IRQHandler: 1: j 1b
|
||||
RTC_IRQHandler: 1: j 1b
|
||||
FLASH_IRQHandler: 1: j 1b
|
||||
RCC_IRQHandler: 1: j 1b
|
||||
EXTI0_IRQHandler: 1: j 1b
|
||||
EXTI1_IRQHandler: 1: j 1b
|
||||
EXTI2_IRQHandler: 1: j 1b
|
||||
EXTI3_IRQHandler: 1: j 1b
|
||||
EXTI4_IRQHandler: 1: j 1b
|
||||
DMA1_Channel1_IRQHandler: 1: j 1b
|
||||
DMA1_Channel2_IRQHandler: 1: j 1b
|
||||
DMA1_Channel3_IRQHandler: 1: j 1b
|
||||
DMA1_Channel4_IRQHandler: 1: j 1b
|
||||
DMA1_Channel5_IRQHandler: 1: j 1b
|
||||
DMA1_Channel6_IRQHandler: 1: j 1b
|
||||
DMA1_Channel7_IRQHandler: 1: j 1b
|
||||
ADC1_2_IRQHandler: 1: j 1b
|
||||
USB_HP_CAN1_TX_IRQHandler: 1: j 1b
|
||||
USB_LP_CAN1_RX0_IRQHandler: 1: j 1b
|
||||
CAN1_RX1_IRQHandler: 1: j 1b
|
||||
CAN1_SCE_IRQHandler: 1: j 1b
|
||||
EXTI9_5_IRQHandler: 1: j 1b
|
||||
TIM1_BRK_IRQHandler: 1: j 1b
|
||||
TIM1_UP_IRQHandler: 1: j 1b
|
||||
TIM1_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM1_CC_IRQHandler: 1: j 1b
|
||||
TIM2_IRQHandler: 1: j 1b
|
||||
TIM3_IRQHandler: 1: j 1b
|
||||
TIM4_IRQHandler: 1: j 1b
|
||||
I2C1_EV_IRQHandler: 1: j 1b
|
||||
I2C1_ER_IRQHandler: 1: j 1b
|
||||
I2C2_EV_IRQHandler: 1: j 1b
|
||||
I2C2_ER_IRQHandler: 1: j 1b
|
||||
SPI1_IRQHandler: 1: j 1b
|
||||
SPI2_IRQHandler: 1: j 1b
|
||||
USART1_IRQHandler: 1: j 1b
|
||||
USART2_IRQHandler: 1: j 1b
|
||||
USART3_IRQHandler: 1: j 1b
|
||||
EXTI15_10_IRQHandler: 1: j 1b
|
||||
RTCAlarm_IRQHandler: 1: j 1b
|
||||
TIM8_BRK_IRQHandler: 1: j 1b
|
||||
TIM8_UP_IRQHandler: 1: j 1b
|
||||
TIM8_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM8_CC_IRQHandler: 1: j 1b
|
||||
RNG_IRQHandler: 1: j 1b
|
||||
FSMC_IRQHandler: 1: j 1b
|
||||
SDIO_IRQHandler: 1: j 1b
|
||||
TIM5_IRQHandler: 1: j 1b
|
||||
SPI3_IRQHandler: 1: j 1b
|
||||
UART4_IRQHandler: 1: j 1b
|
||||
UART5_IRQHandler: 1: j 1b
|
||||
TIM6_IRQHandler: 1: j 1b
|
||||
TIM7_IRQHandler: 1: j 1b
|
||||
DMA2_Channel1_IRQHandler: 1: j 1b
|
||||
DMA2_Channel2_IRQHandler: 1: j 1b
|
||||
DMA2_Channel3_IRQHandler: 1: j 1b
|
||||
DMA2_Channel4_IRQHandler: 1: j 1b
|
||||
DMA2_Channel5_IRQHandler: 1: j 1b
|
||||
OTG_FS_IRQHandler: 1: j 1b
|
||||
UART6_IRQHandler: 1: j 1b
|
||||
UART7_IRQHandler: 1: j 1b
|
||||
UART8_IRQHandler: 1: j 1b
|
||||
TIM9_BRK_IRQHandler: 1: j 1b
|
||||
TIM9_UP_IRQHandler: 1: j 1b
|
||||
TIM9_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM9_CC_IRQHandler: 1: j 1b
|
||||
TIM10_BRK_IRQHandler: 1: j 1b
|
||||
TIM10_UP_IRQHandler: 1: j 1b
|
||||
TIM10_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM10_CC_IRQHandler: 1: j 1b
|
||||
DMA2_Channel6_IRQHandler: 1: j 1b
|
||||
DMA2_Channel7_IRQHandler: 1: j 1b
|
||||
DMA2_Channel8_IRQHandler: 1: j 1b
|
||||
DMA2_Channel9_IRQHandler: 1: j 1b
|
||||
DMA2_Channel10_IRQHandler: 1: j 1b
|
||||
DMA2_Channel11_IRQHandler: 1: j 1b
|
||||
|
||||
|
||||
.section .text.handle_reset,"ax",@progbits
|
||||
.weak handle_reset
|
||||
.align 1
|
||||
handle_reset:
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
1:
|
||||
la sp, _eusrstack
|
||||
2:
|
||||
/* Load data section from flash to RAM */
|
||||
la a0, _data_lma
|
||||
la a1, _data_vma
|
||||
la a2, _edata
|
||||
bgeu a1, a2, 2f
|
||||
1:
|
||||
lw t0, (a0)
|
||||
sw t0, (a1)
|
||||
addi a0, a0, 4
|
||||
addi a1, a1, 4
|
||||
bltu a1, a2, 1b
|
||||
2:
|
||||
/* Clear bss section */
|
||||
la a0, _sbss
|
||||
la a1, _ebss
|
||||
bgeu a0, a1, 2f
|
||||
1:
|
||||
sw zero, (a0)
|
||||
addi a0, a0, 4
|
||||
bltu a0, a1, 1b
|
||||
2:
|
||||
li t0, 0x1f
|
||||
csrw 0xbc0, t0
|
||||
|
||||
/* Enable nested and hardware stack */
|
||||
li t0, 0x0b
|
||||
csrw 0x804, t0
|
||||
|
||||
/* Enable floating point and interrupt */
|
||||
li t0, 0x6088
|
||||
csrs mstatus, t0
|
||||
|
||||
la t0, _vector_base
|
||||
ori t0, t0, 3
|
||||
csrw mtvec, t0
|
||||
|
||||
jal SystemInit
|
||||
la t0, main
|
||||
csrw mepc, t0
|
||||
mret
|
||||
|
||||
|
||||
|
||||
|
391
examples/wch/ch32v307-make-baremetal-builtin/vendor/startup_ch32v30x_D8C.S
vendored
Normal file
391
examples/wch/ch32v307-make-baremetal-builtin/vendor/startup_ch32v30x_D8C.S
vendored
Normal file
@ -0,0 +1,391 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : startup_ch32v30x_D8C.s
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V307x-CH32V305x vector table for eclipse toolchain.
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*******************************************************************************/
|
||||
|
||||
.section .init,"ax",@progbits
|
||||
.global _start
|
||||
.align 1
|
||||
_start:
|
||||
j handle_reset
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00000013
|
||||
.word 0x00100073
|
||||
.section .vector,"ax",@progbits
|
||||
.align 1
|
||||
_vector_base:
|
||||
.option norvc;
|
||||
.word _start
|
||||
.word 0
|
||||
.word NMI_Handler /* NMI */
|
||||
.word HardFault_Handler /* Hard Fault */
|
||||
.word 0
|
||||
.word Ecall_M_Mode_Handler /* Ecall M Mode */
|
||||
.word 0
|
||||
.word 0
|
||||
.word Ecall_U_Mode_Handler /* Ecall U Mode */
|
||||
.word Break_Point_Handler /* Break Point */
|
||||
.word 0
|
||||
.word 0
|
||||
.word SysTick_Handler /* SysTick */
|
||||
.word 0
|
||||
.word SW_Handler /* SW */
|
||||
.word 0
|
||||
/* External Interrupts */
|
||||
.word WWDG_IRQHandler /* Window Watchdog */
|
||||
.word PVD_IRQHandler /* PVD through EXTI Line detect */
|
||||
.word TAMPER_IRQHandler /* TAMPER */
|
||||
.word RTC_IRQHandler /* RTC */
|
||||
.word FLASH_IRQHandler /* Flash */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_IRQHandler /* EXTI Line 0 */
|
||||
.word EXTI1_IRQHandler /* EXTI Line 1 */
|
||||
.word EXTI2_IRQHandler /* EXTI Line 2 */
|
||||
.word EXTI3_IRQHandler /* EXTI Line 3 */
|
||||
.word EXTI4_IRQHandler /* EXTI Line 4 */
|
||||
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
||||
.word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
|
||||
.word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
|
||||
.word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
|
||||
.word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
|
||||
.word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
|
||||
.word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
|
||||
.word ADC1_2_IRQHandler /* ADC1_2 */
|
||||
.word USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */
|
||||
.word USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */
|
||||
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.word CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.word EXTI9_5_IRQHandler /* EXTI Line 9..5 */
|
||||
.word TIM1_BRK_IRQHandler /* TIM1 Break */
|
||||
.word TIM1_UP_IRQHandler /* TIM1 Update */
|
||||
.word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word TIM4_IRQHandler /* TIM4 */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word USART3_IRQHandler /* USART3 */
|
||||
.word EXTI15_10_IRQHandler /* EXTI Line 15..10 */
|
||||
.word RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */
|
||||
.word USBWakeUp_IRQHandler /* USB Wakeup from suspend */
|
||||
.word TIM8_BRK_IRQHandler /* TIM8 Break */
|
||||
.word TIM8_UP_IRQHandler /* TIM8 Update */
|
||||
.word TIM8_TRG_COM_IRQHandler /* TIM8 Trigger and Commutation */
|
||||
.word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.word RNG_IRQHandler /* RNG */
|
||||
.word FSMC_IRQHandler /* FSMC */
|
||||
.word SDIO_IRQHandler /* SDIO */
|
||||
.word TIM5_IRQHandler /* TIM5 */
|
||||
.word SPI3_IRQHandler /* SPI3 */
|
||||
.word UART4_IRQHandler /* UART4 */
|
||||
.word UART5_IRQHandler /* UART5 */
|
||||
.word TIM6_IRQHandler /* TIM6 */
|
||||
.word TIM7_IRQHandler /* TIM7 */
|
||||
.word DMA2_Channel1_IRQHandler /* DMA2 Channel 1 */
|
||||
.word DMA2_Channel2_IRQHandler /* DMA2 Channel 2 */
|
||||
.word DMA2_Channel3_IRQHandler /* DMA2 Channel 3 */
|
||||
.word DMA2_Channel4_IRQHandler /* DMA2 Channel 4 */
|
||||
.word DMA2_Channel5_IRQHandler /* DMA2 Channel 5 */
|
||||
.word ETH_IRQHandler /* ETH */
|
||||
.word ETH_WKUP_IRQHandler /* ETH WakeUp */
|
||||
.word CAN2_TX_IRQHandler /* CAN2 TX */
|
||||
.word CAN2_RX0_IRQHandler /* CAN2 RX0 */
|
||||
.word CAN2_RX1_IRQHandler /* CAN2 RX1 */
|
||||
.word CAN2_SCE_IRQHandler /* CAN2 SCE */
|
||||
.word OTG_FS_IRQHandler /* OTGFS */
|
||||
.word USBHSWakeup_IRQHandler /* USBHS Wakeup */
|
||||
.word USBHS_IRQHandler /* USBHS */
|
||||
.word DVP_IRQHandler /* DVP */
|
||||
.word UART6_IRQHandler /* UART6 */
|
||||
.word UART7_IRQHandler /* UART7 */
|
||||
.word UART8_IRQHandler /* UART8 */
|
||||
.word TIM9_BRK_IRQHandler /* TIM9 Break */
|
||||
.word TIM9_UP_IRQHandler /* TIM9 Update */
|
||||
.word TIM9_TRG_COM_IRQHandler /* TIM9 Trigger and Commutation */
|
||||
.word TIM9_CC_IRQHandler /* TIM9 Capture Compare */
|
||||
.word TIM10_BRK_IRQHandler /* TIM10 Break */
|
||||
.word TIM10_UP_IRQHandler /* TIM10 Update */
|
||||
.word TIM10_TRG_COM_IRQHandler /* TIM10 Trigger and Commutation */
|
||||
.word TIM10_CC_IRQHandler /* TIM10 Capture Compare */
|
||||
.word DMA2_Channel6_IRQHandler /* DMA2 Channel 6 */
|
||||
.word DMA2_Channel7_IRQHandler /* DMA2 Channel 7 */
|
||||
.word DMA2_Channel8_IRQHandler /* DMA2 Channel 8 */
|
||||
.word DMA2_Channel9_IRQHandler /* DMA2 Channel 9 */
|
||||
.word DMA2_Channel10_IRQHandler /* DMA2 Channel 10 */
|
||||
.word DMA2_Channel11_IRQHandler /* DMA2 Channel 11 */
|
||||
|
||||
.option rvc;
|
||||
|
||||
.section .text.vector_handler, "ax", @progbits
|
||||
.weak NMI_Handler /* NMI */
|
||||
.weak HardFault_Handler /* Hard Fault */
|
||||
.weak Ecall_M_Mode_Handler /* Ecall M Mode */
|
||||
.weak Ecall_U_Mode_Handler /* Ecall U Mode */
|
||||
.weak Break_Point_Handler /* Break Point */
|
||||
.weak SysTick_Handler /* SysTick */
|
||||
.weak SW_Handler /* SW */
|
||||
.weak WWDG_IRQHandler /* Window Watchdog */
|
||||
.weak PVD_IRQHandler /* PVD through EXTI Line detect */
|
||||
.weak TAMPER_IRQHandler /* TAMPER */
|
||||
.weak RTC_IRQHandler /* RTC */
|
||||
.weak FLASH_IRQHandler /* Flash */
|
||||
.weak RCC_IRQHandler /* RCC */
|
||||
.weak EXTI0_IRQHandler /* EXTI Line 0 */
|
||||
.weak EXTI1_IRQHandler /* EXTI Line 1 */
|
||||
.weak EXTI2_IRQHandler /* EXTI Line 2 */
|
||||
.weak EXTI3_IRQHandler /* EXTI Line 3 */
|
||||
.weak EXTI4_IRQHandler /* EXTI Line 4 */
|
||||
.weak DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
||||
.weak DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
|
||||
.weak DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
|
||||
.weak DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
|
||||
.weak DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
|
||||
.weak DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
|
||||
.weak DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
|
||||
.weak ADC1_2_IRQHandler /* ADC1_2 */
|
||||
.weak USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */
|
||||
.weak USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */
|
||||
.weak CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.weak CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.weak EXTI9_5_IRQHandler /* EXTI Line 9..5 */
|
||||
.weak TIM1_BRK_IRQHandler /* TIM1 Break */
|
||||
.weak TIM1_UP_IRQHandler /* TIM1 Update */
|
||||
.weak TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
|
||||
.weak TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.weak TIM2_IRQHandler /* TIM2 */
|
||||
.weak TIM3_IRQHandler /* TIM3 */
|
||||
.weak TIM4_IRQHandler /* TIM4 */
|
||||
.weak I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.weak I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.weak I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.weak I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.weak SPI1_IRQHandler /* SPI1 */
|
||||
.weak SPI2_IRQHandler /* SPI2 */
|
||||
.weak USART1_IRQHandler /* USART1 */
|
||||
.weak USART2_IRQHandler /* USART2 */
|
||||
.weak USART3_IRQHandler /* USART3 */
|
||||
.weak EXTI15_10_IRQHandler /* EXTI Line 15..10 */
|
||||
.weak RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */
|
||||
.weak USBWakeUp_IRQHandler /* USB Wakeup from suspend */
|
||||
.weak TIM8_BRK_IRQHandler /* TIM8 Break */
|
||||
.weak TIM8_UP_IRQHandler /* TIM8 Update */
|
||||
.weak TIM8_TRG_COM_IRQHandler /* TIM8 Trigger and Commutation */
|
||||
.weak TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.weak RNG_IRQHandler /* RNG */
|
||||
.weak FSMC_IRQHandler /* FSMC */
|
||||
.weak SDIO_IRQHandler /* SDIO */
|
||||
.weak TIM5_IRQHandler /* TIM5 */
|
||||
.weak SPI3_IRQHandler /* SPI3 */
|
||||
.weak UART4_IRQHandler /* UART4 */
|
||||
.weak UART5_IRQHandler /* UART5 */
|
||||
.weak TIM6_IRQHandler /* TIM6 */
|
||||
.weak TIM7_IRQHandler /* TIM7 */
|
||||
.weak DMA2_Channel1_IRQHandler /* DMA2 Channel 1 */
|
||||
.weak DMA2_Channel2_IRQHandler /* DMA2 Channel 2 */
|
||||
.weak DMA2_Channel3_IRQHandler /* DMA2 Channel 3 */
|
||||
.weak DMA2_Channel4_IRQHandler /* DMA2 Channel 4 */
|
||||
.weak DMA2_Channel5_IRQHandler /* DMA2 Channel 5 */
|
||||
.weak ETH_IRQHandler /* ETH */
|
||||
.weak ETH_WKUP_IRQHandler /* ETH WakeUp */
|
||||
.weak CAN2_TX_IRQHandler /* CAN2 TX */
|
||||
.weak CAN2_RX0_IRQHandler /* CAN2 RX0 */
|
||||
.weak CAN2_RX1_IRQHandler /* CAN2 RX1 */
|
||||
.weak CAN2_SCE_IRQHandler /* CAN2 SCE */
|
||||
.weak OTG_FS_IRQHandler /* OTGFS */
|
||||
.weak USBHSWakeup_IRQHandler /* USBHS Wakeup */
|
||||
.weak USBHS_IRQHandler /* USBHS */
|
||||
.weak DVP_IRQHandler /* DVP */
|
||||
.weak UART6_IRQHandler /* UART6 */
|
||||
.weak UART7_IRQHandler /* UART7 */
|
||||
.weak UART8_IRQHandler /* UART8 */
|
||||
.weak TIM9_BRK_IRQHandler /* TIM9 Break */
|
||||
.weak TIM9_UP_IRQHandler /* TIM9 Update */
|
||||
.weak TIM9_TRG_COM_IRQHandler /* TIM9 Trigger and Commutation */
|
||||
.weak TIM9_CC_IRQHandler /* TIM9 Capture Compare */
|
||||
.weak TIM10_BRK_IRQHandler /* TIM10 Break */
|
||||
.weak TIM10_UP_IRQHandler /* TIM10 Update */
|
||||
.weak TIM10_TRG_COM_IRQHandler /* TIM10 Trigger and Commutation */
|
||||
.weak TIM10_CC_IRQHandler /* TIM10 Capture Compare */
|
||||
.weak DMA2_Channel6_IRQHandler /* DMA2 Channel 6 */
|
||||
.weak DMA2_Channel7_IRQHandler /* DMA2 Channel 7 */
|
||||
.weak DMA2_Channel8_IRQHandler /* DMA2 Channel 8 */
|
||||
.weak DMA2_Channel9_IRQHandler /* DMA2 Channel 9 */
|
||||
.weak DMA2_Channel10_IRQHandler /* DMA2 Channel 10 */
|
||||
.weak DMA2_Channel11_IRQHandler /* DMA2 Channel 11 */
|
||||
|
||||
NMI_Handler: 1: j 1b
|
||||
HardFault_Handler: 1: j 1b
|
||||
Ecall_M_Mode_Handler: 1: j 1b
|
||||
Ecall_U_Mode_Handler: 1: j 1b
|
||||
Break_Point_Handler: 1: j 1b
|
||||
SysTick_Handler: 1: j 1b
|
||||
SW_Handler: 1: j 1b
|
||||
WWDG_IRQHandler: 1: j 1b
|
||||
PVD_IRQHandler: 1: j 1b
|
||||
TAMPER_IRQHandler: 1: j 1b
|
||||
RTC_IRQHandler: 1: j 1b
|
||||
FLASH_IRQHandler: 1: j 1b
|
||||
RCC_IRQHandler: 1: j 1b
|
||||
EXTI0_IRQHandler: 1: j 1b
|
||||
EXTI1_IRQHandler: 1: j 1b
|
||||
EXTI2_IRQHandler: 1: j 1b
|
||||
EXTI3_IRQHandler: 1: j 1b
|
||||
EXTI4_IRQHandler: 1: j 1b
|
||||
DMA1_Channel1_IRQHandler: 1: j 1b
|
||||
DMA1_Channel2_IRQHandler: 1: j 1b
|
||||
DMA1_Channel3_IRQHandler: 1: j 1b
|
||||
DMA1_Channel4_IRQHandler: 1: j 1b
|
||||
DMA1_Channel5_IRQHandler: 1: j 1b
|
||||
DMA1_Channel6_IRQHandler: 1: j 1b
|
||||
DMA1_Channel7_IRQHandler: 1: j 1b
|
||||
ADC1_2_IRQHandler: 1: j 1b
|
||||
USB_HP_CAN1_TX_IRQHandler: 1: j 1b
|
||||
USB_LP_CAN1_RX0_IRQHandler: 1: j 1b
|
||||
CAN1_RX1_IRQHandler: 1: j 1b
|
||||
CAN1_SCE_IRQHandler: 1: j 1b
|
||||
EXTI9_5_IRQHandler: 1: j 1b
|
||||
TIM1_BRK_IRQHandler: 1: j 1b
|
||||
TIM1_UP_IRQHandler: 1: j 1b
|
||||
TIM1_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM1_CC_IRQHandler: 1: j 1b
|
||||
TIM2_IRQHandler: 1: j 1b
|
||||
TIM3_IRQHandler: 1: j 1b
|
||||
TIM4_IRQHandler: 1: j 1b
|
||||
I2C1_EV_IRQHandler: 1: j 1b
|
||||
I2C1_ER_IRQHandler: 1: j 1b
|
||||
I2C2_EV_IRQHandler: 1: j 1b
|
||||
I2C2_ER_IRQHandler: 1: j 1b
|
||||
SPI1_IRQHandler: 1: j 1b
|
||||
SPI2_IRQHandler: 1: j 1b
|
||||
USART1_IRQHandler: 1: j 1b
|
||||
USART2_IRQHandler: 1: j 1b
|
||||
USART3_IRQHandler: 1: j 1b
|
||||
EXTI15_10_IRQHandler: 1: j 1b
|
||||
RTCAlarm_IRQHandler: 1: j 1b
|
||||
USBWakeUp_IRQHandler: 1: j 1b
|
||||
TIM8_BRK_IRQHandler: 1: j 1b
|
||||
TIM8_UP_IRQHandler: 1: j 1b
|
||||
TIM8_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM8_CC_IRQHandler: 1: j 1b
|
||||
RNG_IRQHandler: 1: j 1b
|
||||
FSMC_IRQHandler: 1: j 1b
|
||||
SDIO_IRQHandler: 1: j 1b
|
||||
TIM5_IRQHandler: 1: j 1b
|
||||
SPI3_IRQHandler: 1: j 1b
|
||||
UART4_IRQHandler: 1: j 1b
|
||||
UART5_IRQHandler: 1: j 1b
|
||||
TIM6_IRQHandler: 1: j 1b
|
||||
TIM7_IRQHandler: 1: j 1b
|
||||
DMA2_Channel1_IRQHandler: 1: j 1b
|
||||
DMA2_Channel2_IRQHandler: 1: j 1b
|
||||
DMA2_Channel3_IRQHandler: 1: j 1b
|
||||
DMA2_Channel4_IRQHandler: 1: j 1b
|
||||
DMA2_Channel5_IRQHandler: 1: j 1b
|
||||
ETH_IRQHandler: 1: j 1b
|
||||
ETH_WKUP_IRQHandler: 1: j 1b
|
||||
CAN2_TX_IRQHandler: 1: j 1b
|
||||
CAN2_RX0_IRQHandler: 1: j 1b
|
||||
CAN2_RX1_IRQHandler: 1: j 1b
|
||||
CAN2_SCE_IRQHandler: 1: j 1b
|
||||
OTG_FS_IRQHandler: 1: j 1b
|
||||
USBHSWakeup_IRQHandler: 1: j 1b
|
||||
USBHS_IRQHandler: 1: j 1b
|
||||
DVP_IRQHandler: 1: j 1b
|
||||
UART6_IRQHandler: 1: j 1b
|
||||
UART7_IRQHandler: 1: j 1b
|
||||
UART8_IRQHandler: 1: j 1b
|
||||
TIM9_BRK_IRQHandler: 1: j 1b
|
||||
TIM9_UP_IRQHandler: 1: j 1b
|
||||
TIM9_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM9_CC_IRQHandler: 1: j 1b
|
||||
TIM10_BRK_IRQHandler: 1: j 1b
|
||||
TIM10_UP_IRQHandler: 1: j 1b
|
||||
TIM10_TRG_COM_IRQHandler: 1: j 1b
|
||||
TIM10_CC_IRQHandler: 1: j 1b
|
||||
DMA2_Channel6_IRQHandler: 1: j 1b
|
||||
DMA2_Channel7_IRQHandler: 1: j 1b
|
||||
DMA2_Channel8_IRQHandler: 1: j 1b
|
||||
DMA2_Channel9_IRQHandler: 1: j 1b
|
||||
DMA2_Channel10_IRQHandler: 1: j 1b
|
||||
DMA2_Channel11_IRQHandler: 1: j 1b
|
||||
|
||||
|
||||
.section .text.handle_reset,"ax",@progbits
|
||||
.weak handle_reset
|
||||
.align 1
|
||||
handle_reset:
|
||||
.option push
|
||||
.option norelax
|
||||
la gp, __global_pointer$
|
||||
.option pop
|
||||
1:
|
||||
la sp, _eusrstack
|
||||
2:
|
||||
/* Load data section from flash to RAM */
|
||||
la a0, _data_lma
|
||||
la a1, _data_vma
|
||||
la a2, _edata
|
||||
bgeu a1, a2, 2f
|
||||
1:
|
||||
lw t0, (a0)
|
||||
sw t0, (a1)
|
||||
addi a0, a0, 4
|
||||
addi a1, a1, 4
|
||||
bltu a1, a2, 1b
|
||||
2:
|
||||
/* Clear bss section */
|
||||
la a0, _sbss
|
||||
la a1, _ebss
|
||||
bgeu a0, a1, 2f
|
||||
1:
|
||||
sw zero, (a0)
|
||||
addi a0, a0, 4
|
||||
bltu a0, a1, 1b
|
||||
2:
|
||||
li t0, 0x1f
|
||||
csrw 0xbc0, t0
|
||||
|
||||
/* Enable nested and hardware stack */
|
||||
li t0, 0x0b
|
||||
csrw 0x804, t0
|
||||
|
||||
/* Enable floating point and interrupt */
|
||||
li t0, 0x6088
|
||||
csrs mstatus, t0
|
||||
|
||||
la t0, _vector_base
|
||||
ori t0, t0, 3
|
||||
csrw mtvec, t0
|
||||
|
||||
la a0,__libc_fini_array
|
||||
call atexit
|
||||
call __libc_init_array
|
||||
|
||||
jal SystemInit
|
||||
la t0, main
|
||||
csrw mepc, t0
|
||||
mret
|
||||
|
||||
|
1012
examples/wch/ch32v307-make-baremetal-builtin/vendor/system_ch32v30x.c
vendored
Normal file
1012
examples/wch/ch32v307-make-baremetal-builtin/vendor/system_ch32v30x.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
580
mongoose.c
580
mongoose.c
@ -4076,6 +4076,273 @@ struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
|
||||
return c;
|
||||
}
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "src/net.c"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list *ap) {
|
||||
size_t old = c->send.len;
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
return c->send.len - old;
|
||||
}
|
||||
|
||||
size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
|
||||
size_t len = 0;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
len = mg_vprintf(c, fmt, &ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
|
||||
uint32_t localhost = mg_htonl(0x7f000001);
|
||||
if (mg_vcasecmp(&str, "localhost") != 0) return false;
|
||||
memcpy(addr->ip, &localhost, sizeof(uint32_t));
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
|
||||
if (str.len > 0) return false;
|
||||
memset(addr->ip, 0, sizeof(addr->ip));
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
size_t i, num_dots = 0;
|
||||
for (i = 0; i < str.len; i++) {
|
||||
if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
||||
int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
|
||||
if (octet > 255) return false;
|
||||
data[num_dots] = (uint8_t) octet;
|
||||
} else if (str.ptr[i] == '.') {
|
||||
if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
|
||||
num_dots++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (num_dots != 3 || str.ptr[i - 1] == '.') return false;
|
||||
memcpy(&addr->ip, data, sizeof(data));
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
|
||||
int i;
|
||||
uint32_t ipv4;
|
||||
if (str.len < 14) return false;
|
||||
if (str.ptr[0] != ':' || str.ptr[1] != ':' || str.ptr[6] != ':') return false;
|
||||
for (i = 2; i < 6; i++) {
|
||||
if (str.ptr[i] != 'f' && str.ptr[i] != 'F') return false;
|
||||
}
|
||||
// struct mg_str s = mg_str_n(&str.ptr[7], str.len - 7);
|
||||
if (!mg_aton4(mg_str_n(&str.ptr[7], str.len - 7), addr)) return false;
|
||||
memcpy(&ipv4, addr->ip, sizeof(ipv4));
|
||||
memset(addr->ip, 0, sizeof(addr->ip));
|
||||
addr->ip[10] = addr->ip[11] = 255;
|
||||
memcpy(&addr->ip[12], &ipv4, 4);
|
||||
addr->is_ip6 = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
|
||||
size_t i, j = 0, n = 0, dc = 42;
|
||||
addr->scope_id = 0;
|
||||
if (str.len > 2 && str.ptr[0] == '[') str.ptr++, str.len -= 2;
|
||||
if (mg_v4mapped(str, addr)) return true;
|
||||
for (i = 0; i < str.len; i++) {
|
||||
if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') ||
|
||||
(str.ptr[i] >= 'a' && str.ptr[i] <= 'f') ||
|
||||
(str.ptr[i] >= 'A' && str.ptr[i] <= 'F')) {
|
||||
unsigned long val;
|
||||
if (i > j + 3) return false;
|
||||
// MG_DEBUG(("%lu %lu [%.*s]", i, j, (int) (i - j + 1), &str.ptr[j]));
|
||||
val = mg_unhexn(&str.ptr[j], i - j + 1);
|
||||
addr->ip[n] = (uint8_t) ((val >> 8) & 255);
|
||||
addr->ip[n + 1] = (uint8_t) (val & 255);
|
||||
} else if (str.ptr[i] == ':') {
|
||||
j = i + 1;
|
||||
if (i > 0 && str.ptr[i - 1] == ':') {
|
||||
dc = n; // Double colon
|
||||
if (i > 1 && str.ptr[i - 2] == ':') return false;
|
||||
} else if (i > 0) {
|
||||
n += 2;
|
||||
}
|
||||
if (n > 14) return false;
|
||||
addr->ip[n] = addr->ip[n + 1] = 0; // For trailing ::
|
||||
} else if (str.ptr[i] == '%') { // Scope ID
|
||||
for (i = i + 1; i < str.len; i++) {
|
||||
if (str.ptr[i] < '0' || str.ptr[i] > '9') return false;
|
||||
addr->scope_id *= 10, addr->scope_id += (uint8_t) (str.ptr[i] - '0');
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (n < 14 && dc == 42) return false;
|
||||
if (n < 14) {
|
||||
memmove(&addr->ip[dc + (14 - n)], &addr->ip[dc], n - dc + 2);
|
||||
memset(&addr->ip[dc], 0, 14 - n);
|
||||
}
|
||||
|
||||
addr->is_ip6 = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mg_aton(struct mg_str str, struct mg_addr *addr) {
|
||||
// MG_INFO(("[%.*s]", (int) str.len, str.ptr));
|
||||
return mg_atone(str, addr) || mg_atonl(str, addr) || mg_aton4(str, addr) ||
|
||||
mg_aton6(str, addr);
|
||||
}
|
||||
|
||||
struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) {
|
||||
struct mg_connection *c =
|
||||
(struct mg_connection *) calloc(1, sizeof(*c) + mgr->extraconnsize);
|
||||
if (c != NULL) {
|
||||
c->mgr = mgr;
|
||||
c->send.align = c->recv.align = MG_IO_SIZE;
|
||||
c->id = ++mgr->nextid;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void mg_close_conn(struct mg_connection *c) {
|
||||
mg_resolve_cancel(c); // Close any pending DNS query
|
||||
LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
|
||||
if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
|
||||
if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
|
||||
// Order of operations is important. `MG_EV_CLOSE` event must be fired
|
||||
// before we deallocate received data, see #1331
|
||||
mg_call(c, MG_EV_CLOSE, NULL);
|
||||
MG_DEBUG(("%lu %ld closed", c->id, c->fd));
|
||||
|
||||
mg_tls_free(c);
|
||||
mg_iobuf_free(&c->recv);
|
||||
mg_iobuf_free(&c->send);
|
||||
mg_bzero((unsigned char *) c, sizeof(*c));
|
||||
free(c);
|
||||
}
|
||||
|
||||
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
|
||||
mg_event_handler_t fn, void *fn_data) {
|
||||
struct mg_connection *c = NULL;
|
||||
if (url == NULL || url[0] == '\0') {
|
||||
MG_ERROR(("null url"));
|
||||
} else if ((c = mg_alloc_conn(mgr)) == NULL) {
|
||||
MG_ERROR(("OOM"));
|
||||
} else {
|
||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||
c->is_udp = (strncmp(url, "udp:", 4) == 0);
|
||||
c->fd = (void *) (size_t) MG_INVALID_SOCKET;
|
||||
c->fn = fn;
|
||||
c->is_client = true;
|
||||
c->fn_data = fn_data;
|
||||
MG_DEBUG(("%lu %ld %s", c->id, c->fd, url));
|
||||
mg_call(c, MG_EV_OPEN, (void *) url);
|
||||
mg_resolve(c, url);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
|
||||
mg_event_handler_t fn, void *fn_data) {
|
||||
struct mg_connection *c = NULL;
|
||||
if ((c = mg_alloc_conn(mgr)) == NULL) {
|
||||
MG_ERROR(("OOM %s", url));
|
||||
} else if (!mg_open_listener(c, url)) {
|
||||
MG_ERROR(("Failed: %s, errno %d", url, errno));
|
||||
free(c);
|
||||
c = NULL;
|
||||
} else {
|
||||
c->is_listening = 1;
|
||||
c->is_udp = strncmp(url, "udp:", 4) == 0;
|
||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||
c->fn = fn;
|
||||
c->fn_data = fn_data;
|
||||
mg_call(c, MG_EV_OPEN, NULL);
|
||||
if (mg_url_is_ssl(url)) c->is_tls = 1; // Accepted connection must
|
||||
MG_DEBUG(("%lu %ld %s", c->id, c->fd, url));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
|
||||
mg_event_handler_t fn, void *fn_data) {
|
||||
struct mg_connection *c = mg_alloc_conn(mgr);
|
||||
if (c != NULL) {
|
||||
c->fd = (void *) (size_t) fd;
|
||||
c->fn = fn;
|
||||
c->fn_data = fn_data;
|
||||
MG_EPOLL_ADD(c);
|
||||
mg_call(c, MG_EV_OPEN, NULL);
|
||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
||||
unsigned flags, void (*fn)(void *), void *arg) {
|
||||
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
||||
if (t != NULL) {
|
||||
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
||||
t->id = mgr->timerid++;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void mg_mgr_free(struct mg_mgr *mgr) {
|
||||
struct mg_connection *c;
|
||||
struct mg_timer *tmp, *t = mgr->timers;
|
||||
while (t != NULL) tmp = t->next, free(t), t = tmp;
|
||||
mgr->timers = NULL; // Important. Next call to poll won't touch timers
|
||||
for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
|
||||
mg_mgr_poll(mgr, 0);
|
||||
#if MG_ENABLE_FREERTOS_TCP
|
||||
FreeRTOS_DeleteSocketSet(mgr->ss);
|
||||
#endif
|
||||
MG_DEBUG(("All connections closed"));
|
||||
#if MG_ENABLE_EPOLL
|
||||
if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
|
||||
#endif
|
||||
mg_tls_ctx_free(mgr);
|
||||
}
|
||||
|
||||
void mg_mgr_init(struct mg_mgr *mgr) {
|
||||
memset(mgr, 0, sizeof(*mgr));
|
||||
#if MG_ENABLE_EPOLL
|
||||
if ((mgr->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
|
||||
MG_ERROR(("epoll_create1 errno %d", errno));
|
||||
#else
|
||||
mgr->epoll_fd = -1;
|
||||
#endif
|
||||
#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
|
||||
// clang-format off
|
||||
{ WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
|
||||
// clang-format on
|
||||
#elif MG_ENABLE_FREERTOS_TCP
|
||||
mgr->ss = FreeRTOS_CreateSocketSet();
|
||||
#elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
||||
// Ignore SIGPIPE signal, so if client cancels the request, it
|
||||
// won't kill the whole process.
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
mgr->dnstimeout = 3000;
|
||||
mgr->dns4.url = "udp://8.8.8.8:53";
|
||||
mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
|
||||
mg_tls_ctx_init(mgr);
|
||||
}
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "src/net_builtin.c"
|
||||
#endif
|
||||
@ -5192,273 +5459,6 @@ bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
}
|
||||
#endif // MG_ENABLE_TCPIP
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "src/net.c"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list *ap) {
|
||||
size_t old = c->send.len;
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
return c->send.len - old;
|
||||
}
|
||||
|
||||
size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
|
||||
size_t len = 0;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
len = mg_vprintf(c, fmt, &ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
|
||||
uint32_t localhost = mg_htonl(0x7f000001);
|
||||
if (mg_vcasecmp(&str, "localhost") != 0) return false;
|
||||
memcpy(addr->ip, &localhost, sizeof(uint32_t));
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
|
||||
if (str.len > 0) return false;
|
||||
memset(addr->ip, 0, sizeof(addr->ip));
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
size_t i, num_dots = 0;
|
||||
for (i = 0; i < str.len; i++) {
|
||||
if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
||||
int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
|
||||
if (octet > 255) return false;
|
||||
data[num_dots] = (uint8_t) octet;
|
||||
} else if (str.ptr[i] == '.') {
|
||||
if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
|
||||
num_dots++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (num_dots != 3 || str.ptr[i - 1] == '.') return false;
|
||||
memcpy(&addr->ip, data, sizeof(data));
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
|
||||
int i;
|
||||
uint32_t ipv4;
|
||||
if (str.len < 14) return false;
|
||||
if (str.ptr[0] != ':' || str.ptr[1] != ':' || str.ptr[6] != ':') return false;
|
||||
for (i = 2; i < 6; i++) {
|
||||
if (str.ptr[i] != 'f' && str.ptr[i] != 'F') return false;
|
||||
}
|
||||
// struct mg_str s = mg_str_n(&str.ptr[7], str.len - 7);
|
||||
if (!mg_aton4(mg_str_n(&str.ptr[7], str.len - 7), addr)) return false;
|
||||
memcpy(&ipv4, addr->ip, sizeof(ipv4));
|
||||
memset(addr->ip, 0, sizeof(addr->ip));
|
||||
addr->ip[10] = addr->ip[11] = 255;
|
||||
memcpy(&addr->ip[12], &ipv4, 4);
|
||||
addr->is_ip6 = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
|
||||
size_t i, j = 0, n = 0, dc = 42;
|
||||
addr->scope_id = 0;
|
||||
if (str.len > 2 && str.ptr[0] == '[') str.ptr++, str.len -= 2;
|
||||
if (mg_v4mapped(str, addr)) return true;
|
||||
for (i = 0; i < str.len; i++) {
|
||||
if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') ||
|
||||
(str.ptr[i] >= 'a' && str.ptr[i] <= 'f') ||
|
||||
(str.ptr[i] >= 'A' && str.ptr[i] <= 'F')) {
|
||||
unsigned long val;
|
||||
if (i > j + 3) return false;
|
||||
// MG_DEBUG(("%lu %lu [%.*s]", i, j, (int) (i - j + 1), &str.ptr[j]));
|
||||
val = mg_unhexn(&str.ptr[j], i - j + 1);
|
||||
addr->ip[n] = (uint8_t) ((val >> 8) & 255);
|
||||
addr->ip[n + 1] = (uint8_t) (val & 255);
|
||||
} else if (str.ptr[i] == ':') {
|
||||
j = i + 1;
|
||||
if (i > 0 && str.ptr[i - 1] == ':') {
|
||||
dc = n; // Double colon
|
||||
if (i > 1 && str.ptr[i - 2] == ':') return false;
|
||||
} else if (i > 0) {
|
||||
n += 2;
|
||||
}
|
||||
if (n > 14) return false;
|
||||
addr->ip[n] = addr->ip[n + 1] = 0; // For trailing ::
|
||||
} else if (str.ptr[i] == '%') { // Scope ID
|
||||
for (i = i + 1; i < str.len; i++) {
|
||||
if (str.ptr[i] < '0' || str.ptr[i] > '9') return false;
|
||||
addr->scope_id *= 10, addr->scope_id += (uint8_t) (str.ptr[i] - '0');
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (n < 14 && dc == 42) return false;
|
||||
if (n < 14) {
|
||||
memmove(&addr->ip[dc + (14 - n)], &addr->ip[dc], n - dc + 2);
|
||||
memset(&addr->ip[dc], 0, 14 - n);
|
||||
}
|
||||
|
||||
addr->is_ip6 = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mg_aton(struct mg_str str, struct mg_addr *addr) {
|
||||
// MG_INFO(("[%.*s]", (int) str.len, str.ptr));
|
||||
return mg_atone(str, addr) || mg_atonl(str, addr) || mg_aton4(str, addr) ||
|
||||
mg_aton6(str, addr);
|
||||
}
|
||||
|
||||
struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) {
|
||||
struct mg_connection *c =
|
||||
(struct mg_connection *) calloc(1, sizeof(*c) + mgr->extraconnsize);
|
||||
if (c != NULL) {
|
||||
c->mgr = mgr;
|
||||
c->send.align = c->recv.align = MG_IO_SIZE;
|
||||
c->id = ++mgr->nextid;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void mg_close_conn(struct mg_connection *c) {
|
||||
mg_resolve_cancel(c); // Close any pending DNS query
|
||||
LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
|
||||
if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
|
||||
if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
|
||||
// Order of operations is important. `MG_EV_CLOSE` event must be fired
|
||||
// before we deallocate received data, see #1331
|
||||
mg_call(c, MG_EV_CLOSE, NULL);
|
||||
MG_DEBUG(("%lu %ld closed", c->id, c->fd));
|
||||
|
||||
mg_tls_free(c);
|
||||
mg_iobuf_free(&c->recv);
|
||||
mg_iobuf_free(&c->send);
|
||||
mg_bzero((unsigned char *) c, sizeof(*c));
|
||||
free(c);
|
||||
}
|
||||
|
||||
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *url,
|
||||
mg_event_handler_t fn, void *fn_data) {
|
||||
struct mg_connection *c = NULL;
|
||||
if (url == NULL || url[0] == '\0') {
|
||||
MG_ERROR(("null url"));
|
||||
} else if ((c = mg_alloc_conn(mgr)) == NULL) {
|
||||
MG_ERROR(("OOM"));
|
||||
} else {
|
||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||
c->is_udp = (strncmp(url, "udp:", 4) == 0);
|
||||
c->fd = (void *) (size_t) MG_INVALID_SOCKET;
|
||||
c->fn = fn;
|
||||
c->is_client = true;
|
||||
c->fn_data = fn_data;
|
||||
MG_DEBUG(("%lu %ld %s", c->id, c->fd, url));
|
||||
mg_call(c, MG_EV_OPEN, (void *) url);
|
||||
mg_resolve(c, url);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
|
||||
mg_event_handler_t fn, void *fn_data) {
|
||||
struct mg_connection *c = NULL;
|
||||
if ((c = mg_alloc_conn(mgr)) == NULL) {
|
||||
MG_ERROR(("OOM %s", url));
|
||||
} else if (!mg_open_listener(c, url)) {
|
||||
MG_ERROR(("Failed: %s, errno %d", url, errno));
|
||||
free(c);
|
||||
c = NULL;
|
||||
} else {
|
||||
c->is_listening = 1;
|
||||
c->is_udp = strncmp(url, "udp:", 4) == 0;
|
||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||
c->fn = fn;
|
||||
c->fn_data = fn_data;
|
||||
mg_call(c, MG_EV_OPEN, NULL);
|
||||
if (mg_url_is_ssl(url)) c->is_tls = 1; // Accepted connection must
|
||||
MG_DEBUG(("%lu %ld %s", c->id, c->fd, url));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
struct mg_connection *mg_wrapfd(struct mg_mgr *mgr, int fd,
|
||||
mg_event_handler_t fn, void *fn_data) {
|
||||
struct mg_connection *c = mg_alloc_conn(mgr);
|
||||
if (c != NULL) {
|
||||
c->fd = (void *) (size_t) fd;
|
||||
c->fn = fn;
|
||||
c->fn_data = fn_data;
|
||||
MG_EPOLL_ADD(c);
|
||||
mg_call(c, MG_EV_OPEN, NULL);
|
||||
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
struct mg_timer *mg_timer_add(struct mg_mgr *mgr, uint64_t milliseconds,
|
||||
unsigned flags, void (*fn)(void *), void *arg) {
|
||||
struct mg_timer *t = (struct mg_timer *) calloc(1, sizeof(*t));
|
||||
if (t != NULL) {
|
||||
mg_timer_init(&mgr->timers, t, milliseconds, flags, fn, arg);
|
||||
t->id = mgr->timerid++;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void mg_mgr_free(struct mg_mgr *mgr) {
|
||||
struct mg_connection *c;
|
||||
struct mg_timer *tmp, *t = mgr->timers;
|
||||
while (t != NULL) tmp = t->next, free(t), t = tmp;
|
||||
mgr->timers = NULL; // Important. Next call to poll won't touch timers
|
||||
for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
|
||||
mg_mgr_poll(mgr, 0);
|
||||
#if MG_ENABLE_FREERTOS_TCP
|
||||
FreeRTOS_DeleteSocketSet(mgr->ss);
|
||||
#endif
|
||||
MG_DEBUG(("All connections closed"));
|
||||
#if MG_ENABLE_EPOLL
|
||||
if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
|
||||
#endif
|
||||
mg_tls_ctx_free(mgr);
|
||||
}
|
||||
|
||||
void mg_mgr_init(struct mg_mgr *mgr) {
|
||||
memset(mgr, 0, sizeof(*mgr));
|
||||
#if MG_ENABLE_EPOLL
|
||||
if ((mgr->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
|
||||
MG_ERROR(("epoll_create1 errno %d", errno));
|
||||
#else
|
||||
mgr->epoll_fd = -1;
|
||||
#endif
|
||||
#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
|
||||
// clang-format off
|
||||
{ WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
|
||||
// clang-format on
|
||||
#elif MG_ENABLE_FREERTOS_TCP
|
||||
mgr->ss = FreeRTOS_CreateSocketSet();
|
||||
#elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
||||
// Ignore SIGPIPE signal, so if client cancels the request, it
|
||||
// won't kill the whole process.
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
mgr->dnstimeout = 3000;
|
||||
mgr->dns4.url = "udp://8.8.8.8:53";
|
||||
mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
|
||||
mg_tls_ctx_init(mgr);
|
||||
}
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "src/ota_dummy.c"
|
||||
#endif
|
||||
@ -9200,8 +9200,8 @@ static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
|
||||
|
||||
// Init RX descriptors
|
||||
for (int i = 0; i < ETH_DESC_CNT; i++) {
|
||||
s_rxdesc[i][0] = MG_BIT(31); // Own
|
||||
s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | MG_BIT(14); // 2nd address chained
|
||||
s_rxdesc[i][0] = MG_BIT(31); // Own
|
||||
s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | MG_BIT(14); // 2nd address chained
|
||||
s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
|
||||
s_rxdesc[i][3] =
|
||||
(uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
|
||||
@ -9223,17 +9223,20 @@ static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
|
||||
|
||||
// NOTE(cpq): we do not use extended descriptor bit 7, and do not use
|
||||
// hardware checksum. Therefore, descriptor size is 4, not 8
|
||||
// ETH->DMABMR = MG_BIT(13) | MG_BIT(16) | MG_BIT(22) | MG_BIT(23) | MG_BIT(25);
|
||||
// ETH->DMABMR = MG_BIT(13) | MG_BIT(16) | MG_BIT(22) | MG_BIT(23) |
|
||||
// MG_BIT(25);
|
||||
ETH->MACIMR = MG_BIT(3) | MG_BIT(9); // Mask timestamp & PMT IT
|
||||
ETH->MACFCR = MG_BIT(7); // Disable zero quarta pause
|
||||
ETH->MACFCR = MG_BIT(7); // Disable zero quarta pause
|
||||
// ETH->MACFFR = MG_BIT(31); // Receive all
|
||||
eth_write_phy(PHY_ADDR, PHY_BCR, MG_BIT(15)); // Reset PHY
|
||||
eth_write_phy(PHY_ADDR, PHY_BCR, MG_BIT(12)); // Set autonegotiation
|
||||
ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
|
||||
ETH->DMATDLAR = (uint32_t) (uintptr_t) s_txdesc; // RX descriptors
|
||||
ETH->DMAIER = MG_BIT(6) | MG_BIT(16); // RIE, NISE
|
||||
ETH->MACCR = MG_BIT(2) | MG_BIT(3) | MG_BIT(11) | MG_BIT(14); // RE, TE, Duplex, Fast
|
||||
ETH->DMAOMR = MG_BIT(1) | MG_BIT(13) | MG_BIT(21) | MG_BIT(25); // SR, ST, TSF, RSF
|
||||
eth_write_phy(PHY_ADDR, PHY_BCR, MG_BIT(15)); // Reset PHY
|
||||
eth_write_phy(PHY_ADDR, PHY_BCR, MG_BIT(12)); // Set autonegotiation
|
||||
ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
|
||||
ETH->DMATDLAR = (uint32_t) (uintptr_t) s_txdesc; // RX descriptors
|
||||
ETH->DMAIER = MG_BIT(6) | MG_BIT(16); // RIE, NISE
|
||||
ETH->MACCR =
|
||||
MG_BIT(2) | MG_BIT(3) | MG_BIT(11) | MG_BIT(14); // RE, TE, Duplex, Fast
|
||||
ETH->DMAOMR =
|
||||
MG_BIT(1) | MG_BIT(13) | MG_BIT(21) | MG_BIT(25); // SR, ST, TSF, RSF
|
||||
|
||||
// MAC address filtering
|
||||
ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
|
||||
@ -9254,15 +9257,15 @@ static size_t mg_tcpip_driver_stm32_tx(const void *buf, size_t len,
|
||||
// printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) ETH->DMASR);
|
||||
len = 0; // All descriptors are busy, fail
|
||||
} else {
|
||||
memcpy(s_txbuf[s_txno], buf, len); // Copy data
|
||||
s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
|
||||
memcpy(s_txbuf[s_txno], buf, len); // Copy data
|
||||
s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
|
||||
s_txdesc[s_txno][0] = MG_BIT(20) | MG_BIT(28) | MG_BIT(29); // Chain,FS,LS
|
||||
s_txdesc[s_txno][0] |= MG_BIT(31); // Set OWN bit - let DMA take over
|
||||
if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
|
||||
}
|
||||
MG_DSB(); // ensure descriptors have been written
|
||||
MG_DSB(); // ensure descriptors have been written
|
||||
ETH->DMASR = MG_BIT(2) | MG_BIT(5); // Clear any prior TBUS/TUS
|
||||
ETH->DMATPDR = 0; // and resume
|
||||
ETH->DMATPDR = 0; // and resume
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -9284,13 +9287,16 @@ static bool mg_tcpip_driver_stm32_up(struct mg_tcpip_if *ifp) {
|
||||
return up;
|
||||
}
|
||||
|
||||
#ifdef __riscv
|
||||
__attribute__((interrupt())) // For RISCV CH32V307, which share the same MAC
|
||||
#endif
|
||||
void ETH_IRQHandler(void);
|
||||
void ETH_IRQHandler(void) {
|
||||
if (ETH->DMASR & MG_BIT(6)) { // Frame received, loop
|
||||
ETH->DMASR = MG_BIT(16) | MG_BIT(6); // Clear flag
|
||||
if (ETH->DMASR & MG_BIT(6)) { // Frame received, loop
|
||||
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
||||
if (s_rxdesc[s_rxno][0] & MG_BIT(31)) break; // exit when done
|
||||
if (((s_rxdesc[s_rxno][0] & (MG_BIT(8) | MG_BIT(9))) == (MG_BIT(8) | MG_BIT(9))) &&
|
||||
if (((s_rxdesc[s_rxno][0] & (MG_BIT(8) | MG_BIT(9))) ==
|
||||
(MG_BIT(8) | MG_BIT(9))) &&
|
||||
!(s_rxdesc[s_rxno][0] & MG_BIT(15))) { // skip partial/errored frames
|
||||
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (MG_BIT(14) - 1));
|
||||
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
|
||||
@ -9301,8 +9307,8 @@ void ETH_IRQHandler(void) {
|
||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||
}
|
||||
}
|
||||
ETH->DMASR = MG_BIT(7); // Clear possible RBUS while processing
|
||||
ETH->DMARPDR = 0; // and resume RX
|
||||
ETH->DMASR = ~0; // Clear flags
|
||||
ETH->DMARPDR = 0; // and resume RX
|
||||
}
|
||||
|
||||
struct mg_tcpip_driver mg_tcpip_driver_stm32 = {mg_tcpip_driver_stm32_init,
|
||||
|
@ -108,8 +108,8 @@ static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
|
||||
|
||||
// Init RX descriptors
|
||||
for (int i = 0; i < ETH_DESC_CNT; i++) {
|
||||
s_rxdesc[i][0] = MG_BIT(31); // Own
|
||||
s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | MG_BIT(14); // 2nd address chained
|
||||
s_rxdesc[i][0] = MG_BIT(31); // Own
|
||||
s_rxdesc[i][1] = sizeof(s_rxbuf[i]) | MG_BIT(14); // 2nd address chained
|
||||
s_rxdesc[i][2] = (uint32_t) (uintptr_t) s_rxbuf[i]; // Point to data buffer
|
||||
s_rxdesc[i][3] =
|
||||
(uint32_t) (uintptr_t) s_rxdesc[(i + 1) % ETH_DESC_CNT]; // Chain
|
||||
@ -131,17 +131,20 @@ static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
|
||||
|
||||
// NOTE(cpq): we do not use extended descriptor bit 7, and do not use
|
||||
// hardware checksum. Therefore, descriptor size is 4, not 8
|
||||
// ETH->DMABMR = MG_BIT(13) | MG_BIT(16) | MG_BIT(22) | MG_BIT(23) | MG_BIT(25);
|
||||
// ETH->DMABMR = MG_BIT(13) | MG_BIT(16) | MG_BIT(22) | MG_BIT(23) |
|
||||
// MG_BIT(25);
|
||||
ETH->MACIMR = MG_BIT(3) | MG_BIT(9); // Mask timestamp & PMT IT
|
||||
ETH->MACFCR = MG_BIT(7); // Disable zero quarta pause
|
||||
ETH->MACFCR = MG_BIT(7); // Disable zero quarta pause
|
||||
// ETH->MACFFR = MG_BIT(31); // Receive all
|
||||
eth_write_phy(PHY_ADDR, PHY_BCR, MG_BIT(15)); // Reset PHY
|
||||
eth_write_phy(PHY_ADDR, PHY_BCR, MG_BIT(12)); // Set autonegotiation
|
||||
ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
|
||||
ETH->DMATDLAR = (uint32_t) (uintptr_t) s_txdesc; // RX descriptors
|
||||
ETH->DMAIER = MG_BIT(6) | MG_BIT(16); // RIE, NISE
|
||||
ETH->MACCR = MG_BIT(2) | MG_BIT(3) | MG_BIT(11) | MG_BIT(14); // RE, TE, Duplex, Fast
|
||||
ETH->DMAOMR = MG_BIT(1) | MG_BIT(13) | MG_BIT(21) | MG_BIT(25); // SR, ST, TSF, RSF
|
||||
eth_write_phy(PHY_ADDR, PHY_BCR, MG_BIT(15)); // Reset PHY
|
||||
eth_write_phy(PHY_ADDR, PHY_BCR, MG_BIT(12)); // Set autonegotiation
|
||||
ETH->DMARDLAR = (uint32_t) (uintptr_t) s_rxdesc; // RX descriptors
|
||||
ETH->DMATDLAR = (uint32_t) (uintptr_t) s_txdesc; // RX descriptors
|
||||
ETH->DMAIER = MG_BIT(6) | MG_BIT(16); // RIE, NISE
|
||||
ETH->MACCR =
|
||||
MG_BIT(2) | MG_BIT(3) | MG_BIT(11) | MG_BIT(14); // RE, TE, Duplex, Fast
|
||||
ETH->DMAOMR =
|
||||
MG_BIT(1) | MG_BIT(13) | MG_BIT(21) | MG_BIT(25); // SR, ST, TSF, RSF
|
||||
|
||||
// MAC address filtering
|
||||
ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
|
||||
@ -162,15 +165,15 @@ static size_t mg_tcpip_driver_stm32_tx(const void *buf, size_t len,
|
||||
// printf("D0 %lx SR %lx\n", (long) s_txdesc[0][0], (long) ETH->DMASR);
|
||||
len = 0; // All descriptors are busy, fail
|
||||
} else {
|
||||
memcpy(s_txbuf[s_txno], buf, len); // Copy data
|
||||
s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
|
||||
memcpy(s_txbuf[s_txno], buf, len); // Copy data
|
||||
s_txdesc[s_txno][1] = (uint32_t) len; // Set data len
|
||||
s_txdesc[s_txno][0] = MG_BIT(20) | MG_BIT(28) | MG_BIT(29); // Chain,FS,LS
|
||||
s_txdesc[s_txno][0] |= MG_BIT(31); // Set OWN bit - let DMA take over
|
||||
if (++s_txno >= ETH_DESC_CNT) s_txno = 0;
|
||||
}
|
||||
MG_DSB(); // ensure descriptors have been written
|
||||
MG_DSB(); // ensure descriptors have been written
|
||||
ETH->DMASR = MG_BIT(2) | MG_BIT(5); // Clear any prior TBUS/TUS
|
||||
ETH->DMATPDR = 0; // and resume
|
||||
ETH->DMATPDR = 0; // and resume
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -192,13 +195,16 @@ static bool mg_tcpip_driver_stm32_up(struct mg_tcpip_if *ifp) {
|
||||
return up;
|
||||
}
|
||||
|
||||
#ifdef __riscv
|
||||
__attribute__((interrupt())) // For RISCV CH32V307, which share the same MAC
|
||||
#endif
|
||||
void ETH_IRQHandler(void);
|
||||
void ETH_IRQHandler(void) {
|
||||
if (ETH->DMASR & MG_BIT(6)) { // Frame received, loop
|
||||
ETH->DMASR = MG_BIT(16) | MG_BIT(6); // Clear flag
|
||||
if (ETH->DMASR & MG_BIT(6)) { // Frame received, loop
|
||||
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
||||
if (s_rxdesc[s_rxno][0] & MG_BIT(31)) break; // exit when done
|
||||
if (((s_rxdesc[s_rxno][0] & (MG_BIT(8) | MG_BIT(9))) == (MG_BIT(8) | MG_BIT(9))) &&
|
||||
if (((s_rxdesc[s_rxno][0] & (MG_BIT(8) | MG_BIT(9))) ==
|
||||
(MG_BIT(8) | MG_BIT(9))) &&
|
||||
!(s_rxdesc[s_rxno][0] & MG_BIT(15))) { // skip partial/errored frames
|
||||
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (MG_BIT(14) - 1));
|
||||
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
|
||||
@ -209,8 +215,8 @@ void ETH_IRQHandler(void) {
|
||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||
}
|
||||
}
|
||||
ETH->DMASR = MG_BIT(7); // Clear possible RBUS while processing
|
||||
ETH->DMARPDR = 0; // and resume RX
|
||||
ETH->DMASR = ~0; // Clear flags
|
||||
ETH->DMARPDR = 0; // and resume RX
|
||||
}
|
||||
|
||||
struct mg_tcpip_driver mg_tcpip_driver_stm32 = {mg_tcpip_driver_stm32_init,
|
||||
|
Loading…
Reference in New Issue
Block a user