mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-09 16:21:45 +00:00
Add ek-ra6m4 example
This commit is contained in:
1 parent
d7754516f0
commit
ebfa5f0ba7
11 files changed
+447
No files matched your search
@@ -0,0 +1,56 @@
|
|||||||
|
CFLAGS = -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion
|
||||||
|
CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion
|
||||||
|
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
|
||||||
|
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include
|
||||||
|
CFLAGS += -Icmsis_mcu/ra/fsp/src/bsp/cmsis/Device/RENESAS/Include
|
||||||
|
CFLAGS += -Icmsis_mcu/ra/fsp/src/bsp/mcu/all
|
||||||
|
#CFLAGS += -Icmsis_mcu/ra/fsp/inc
|
||||||
|
#CFLAGS += -Icmsis_mcu/ra/fsp/inc/api
|
||||||
|
CFLAGS += -mcpu=cortex-m33 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard $(CFLAGS_EXTRA)
|
||||||
|
LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
||||||
|
|
||||||
|
SOURCES = main.c hal.c mongoose.c net.c packed_fs.c
|
||||||
|
#SOURCES += cmsis_mcu/Files/startup_RA.c
|
||||||
|
#SOURCES += cmsis_mcu/Files/system_RA.c
|
||||||
|
|
||||||
|
# Example specific build options. See README.md
|
||||||
|
CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" -DHTTPS_URL=\"https://0.0.0.0/\"
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
RM = cmd /C del /Q /F /S
|
||||||
|
else
|
||||||
|
RM = rm -rf
|
||||||
|
endif
|
||||||
|
|
||||||
|
all build example: firmware.bin
|
||||||
|
|
||||||
|
firmware.bin: firmware.elf
|
||||||
|
arm-none-eabi-objcopy -O binary $< $@
|
||||||
|
|
||||||
|
firmware.elf: cmsis_core cmsis_mcu $(SOURCES) hal.h link.ld Makefile
|
||||||
|
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
|
||||||
|
arm-none-eabi-size $@
|
||||||
|
|
||||||
|
flash: firmware.bin
|
||||||
|
rfp-cli -d ra -t jlink -v -p -bin 0x0000000 $<
|
||||||
|
rfp-cli -d ra -t jlink -rv 0x8000000 256
|
||||||
|
|
||||||
|
cmsis_core: # ARM CMSIS core headers
|
||||||
|
git clone -q --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
||||||
|
cmsis_mcu:
|
||||||
|
git clone -q --depth 1 -b v5.1.0 https://github.com/renesas/fsp $@
|
||||||
|
|
||||||
|
|
||||||
|
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
||||||
|
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/13
|
||||||
|
update: firmware.bin
|
||||||
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||||
|
|
||||||
|
update: CFLAGS += -DUART_DEBUG=LPUART3
|
||||||
|
|
||||||
|
test: update
|
||||||
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
||||||
|
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) firmware.* *.su cmsis_core cmsis_mcu mbedtls *.zip
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
// Copyright (c) 2024 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h> // For _fstat()
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
uint32_t SystemCoreClock = SYS_FREQUENCY;
|
||||||
|
static volatile uint64_t s_ticks; // Milliseconds since boot
|
||||||
|
|
||||||
|
extern void _estack(void); // Defined in link.ld
|
||||||
|
void Reset_Handler(void);
|
||||||
|
void SysTick_Handler(void);
|
||||||
|
|
||||||
|
// 16 ARM and 200 peripheral handlers
|
||||||
|
__attribute__((section(".vectors"))) void (*const tab[16 + 10])(void) = {
|
||||||
|
_estack, Reset_Handler, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, SysTick_Handler};
|
||||||
|
|
||||||
|
void Reset_Handler(void) {
|
||||||
|
extern long _sbss[], _ebss[], _sdata[], _edata[], _sidata[];
|
||||||
|
extern int main(void);
|
||||||
|
|
||||||
|
SCB->VTOR = (uint32_t) tab;
|
||||||
|
for (long *dst = _sbss; dst < _ebss; dst++) *dst = 0;
|
||||||
|
for (long *dst = _sdata, *src = _sidata; dst < _edata;) *dst++ = *src++;
|
||||||
|
|
||||||
|
SystemInit();
|
||||||
|
main();
|
||||||
|
while (1) (void) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemInit(void) { // Called automatically by startup code
|
||||||
|
clock_init(); // Set system clock to SYS_FREQUENCY
|
||||||
|
rng_init(); // Initialise random number generator
|
||||||
|
SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
|
||||||
|
s_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mg_millis(void) { // Let Mongoose use our uptime function
|
||||||
|
return s_ticks; // Return number of milliseconds since boot
|
||||||
|
}
|
||||||
|
|
||||||
|
void hal_init(void) {
|
||||||
|
uart_init(UART_DEBUG, 115200); // Initialise UART
|
||||||
|
gpio_output(LED1); // Initialise LED
|
||||||
|
gpio_output(LED2); // Initialise LED
|
||||||
|
gpio_output(LED3); // Initialise LED
|
||||||
|
ethernet_init(); // Initialise Ethernet pins
|
||||||
|
}
|
||||||
|
|
||||||
|
// Newlib syscalls. Implemented are: _sbrk() for malloc, and _write()
|
||||||
|
int _fstat(int fd, struct stat *st) {
|
||||||
|
(void) fd, (void) st;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern unsigned char _end[]; // End of data section, start of heap. See link.ld
|
||||||
|
static unsigned char *s_current_heap_end = _end;
|
||||||
|
|
||||||
|
size_t hal_ram_used(void) {
|
||||||
|
return (size_t) (s_current_heap_end - _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t hal_ram_free(void) {
|
||||||
|
unsigned char endofstack;
|
||||||
|
return (size_t) (&endofstack - s_current_heap_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *_sbrk(int incr) {
|
||||||
|
unsigned char *prev_heap;
|
||||||
|
unsigned char *heap_end = (unsigned char *) ((size_t) &heap_end - 256);
|
||||||
|
prev_heap = s_current_heap_end;
|
||||||
|
// Check how much space we got from the heap end to the stack end
|
||||||
|
if (s_current_heap_end + incr > heap_end) return (void *) -1;
|
||||||
|
s_current_heap_end += incr;
|
||||||
|
return prev_heap;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _open(const char *path) {
|
||||||
|
(void) path;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _close(int fd) {
|
||||||
|
(void) fd;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _isatty(int fd) {
|
||||||
|
(void) fd;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _lseek(int fd, int ptr, int dir) {
|
||||||
|
(void) fd, (void) ptr, (void) dir;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _exit(int status) {
|
||||||
|
(void) status;
|
||||||
|
for (;;) asm volatile("BKPT #0");
|
||||||
|
}
|
||||||
|
|
||||||
|
void _kill(int pid, int sig) {
|
||||||
|
(void) pid, (void) sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _getpid(void) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _write(int fd, char *ptr, int len) {
|
||||||
|
(void) fd, (void) ptr, (void) len;
|
||||||
|
if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _read(int fd, char *ptr, int len) {
|
||||||
|
(void) fd, (void) ptr, (void) len;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _link(const char *a, const char *b) {
|
||||||
|
(void) a, (void) b;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _unlink(const char *a) {
|
||||||
|
(void) a;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _stat(const char *path, struct stat *st) {
|
||||||
|
(void) path, (void) st;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mkdir(const char *path, mode_t mode) {
|
||||||
|
(void) path, (void) mode;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init(void) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
// Copyright (c) 2024 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// MCU and ek-ra6m4 eval board datasheets:
|
||||||
|
// https://www.renesas.com/us/en/document/man/ra6m4-group-user-s-manual-hardware
|
||||||
|
// https://www.renesas.com/us/en/document/man/ek-ra6m5-v1-users-manual
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "bsp_exceptions.h"
|
||||||
|
|
||||||
|
#include "R7FA6M4AF.h"
|
||||||
|
|
||||||
|
extern void hal_init(void);
|
||||||
|
|
||||||
|
#define LED1 PIN('E', 15)
|
||||||
|
#define LED2 PIN('E', 4)
|
||||||
|
#define LED3 PIN('E', 0)
|
||||||
|
#define UART_DEBUG R_SCI0
|
||||||
|
#define UART_TX PIN('G', 13)
|
||||||
|
#define UART_RX PIN('G', 12)
|
||||||
|
|
||||||
|
#define BIT(x) (1UL << (x))
|
||||||
|
#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set))
|
||||||
|
#define PIN(port, num) ((((port) - 'A') << 8) | (num))
|
||||||
|
#define PIN_NUM(pin) (pin & 255)
|
||||||
|
#define PIN_PORT(pin) (pin >> 8)
|
||||||
|
|
||||||
|
// No-op HAL API implementation for a device with GPIO and UART
|
||||||
|
#define rng_read() 0
|
||||||
|
#define rng_init()
|
||||||
|
#define uart_read_ready(uart) 0
|
||||||
|
#define GENERATE_MAC_ADDRESS() \
|
||||||
|
{ 2, 3, 4, 5, 6, 7 }
|
||||||
|
|
||||||
|
// Clock
|
||||||
|
#define SYS_FREQUENCY 2000000
|
||||||
|
static inline void clock_init(void) {
|
||||||
|
SCB->CPACR = (uint32_t) 15U << 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GPIO
|
||||||
|
#define GPIO(N) ((R_PORT0_Type *) (R_PORT0_BASE + 0x20 * (N)))
|
||||||
|
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF };
|
||||||
|
|
||||||
|
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t af) {
|
||||||
|
R_PORT0_Type *gpio = GPIO(PIN_PORT(pin));
|
||||||
|
if (mode == GPIO_MODE_OUTPUT) {
|
||||||
|
gpio->PCNTR1 |= BIT(PIN_NUM(pin));
|
||||||
|
} else if (mode == GPIO_MODE_INPUT) {
|
||||||
|
gpio->PCNTR1 &= ~BIT(PIN_NUM(pin));
|
||||||
|
} else {
|
||||||
|
(void) af;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gpio_output(uint16_t pin) {
|
||||||
|
gpio_init(pin, GPIO_MODE_OUTPUT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gpio_input(uint16_t pin) {
|
||||||
|
gpio_init(pin, GPIO_MODE_INPUT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool gpio_read(uint16_t pin) {
|
||||||
|
R_PORT0_Type *gpio = GPIO(PIN_PORT(pin));
|
||||||
|
return gpio->PCNTR2 & BIT(PIN_NUM(pin)) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gpio_write(uint16_t pin, bool val) {
|
||||||
|
R_PORT0_Type *gpio = GPIO(PIN_PORT(pin));
|
||||||
|
gpio->PCNTR3 = BIT(PIN_NUM(pin)) << (val ? 0 : 16U);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gpio_toggle(uint16_t pin) {
|
||||||
|
gpio_write(pin, !gpio_read(pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
// UART
|
||||||
|
static inline void uart_init(R_SCI0_Type *uart, unsigned baud) {
|
||||||
|
gpio_output(UART_TX);
|
||||||
|
gpio_input(UART_RX);
|
||||||
|
(void) uart, (void) baud;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void uart_write_byte(void *uart, uint8_t byte) {
|
||||||
|
uint16_t pin = UART_TX;
|
||||||
|
uint32_t baud = 9600;
|
||||||
|
uint32_t interval = SYS_FREQUENCY / baud; // Time to send 1 bit
|
||||||
|
uint8_t bits[] = {
|
||||||
|
0, // Start bit
|
||||||
|
(byte >> 0) & 1U,
|
||||||
|
(byte >> 1) & 1U,
|
||||||
|
(byte >> 2) & 1U,
|
||||||
|
(byte >> 3) & 1U,
|
||||||
|
(byte >> 4) & 1U,
|
||||||
|
(byte >> 5) & 1U,
|
||||||
|
(byte >> 6) & 1U,
|
||||||
|
(byte >> 7) & 1U,
|
||||||
|
1, // Stop bit
|
||||||
|
};
|
||||||
|
uint32_t t = SysTick->VAL; // Current timer value
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 10; i++) {
|
||||||
|
gpio_write(pin, bits[i]);
|
||||||
|
if (t <= interval) {
|
||||||
|
while (SysTick->VAL <= t) (void) 0;
|
||||||
|
t = SysTick->LOAD + 1 - interval;
|
||||||
|
while (SysTick->VAL > t) (void) 0;
|
||||||
|
} else {
|
||||||
|
t -= interval;
|
||||||
|
while (SysTick->VAL > t) (void) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(void) uart;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void uart_write_buf(void *uart, char *buf, size_t len) {
|
||||||
|
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ethernet
|
||||||
|
static inline void ethernet_init(void) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
ENTRY(Reset_Handler);
|
||||||
|
MEMORY {
|
||||||
|
flash(rx) : ORIGIN = 0x00000000, LENGTH = 1024k
|
||||||
|
sram(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
|
||||||
|
}
|
||||||
|
_estack = ORIGIN(sram) + LENGTH(sram); /* End of RAM. stack points here */
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.vectors : { KEEP(*(.isr_vector)) } > flash
|
||||||
|
.text : { *(.text* .text.*) } > flash
|
||||||
|
.rodata : { *(.rodata*) } > flash
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
_sdata = .;
|
||||||
|
*(.first_data)
|
||||||
|
*(.ram)
|
||||||
|
*(.data SORT(.data.*))
|
||||||
|
_edata = .;
|
||||||
|
} > sram AT > flash
|
||||||
|
_sidata = LOADADDR(.data);
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
_sbss = .;
|
||||||
|
*(.bss SORT(.bss.*) COMMON)
|
||||||
|
_ebss = .;
|
||||||
|
} > sram
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
_end = .;
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (c) 2023 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
#include "mongoose.h"
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
|
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis
|
||||||
|
|
||||||
|
static void timer_fn(void *arg) {
|
||||||
|
gpio_toggle(LED2); // Blink LED
|
||||||
|
#if 0
|
||||||
|
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));
|
||||||
|
#endif
|
||||||
|
(void) arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
hal_init();
|
||||||
|
|
||||||
|
struct mg_mgr mgr; // Initialise
|
||||||
|
mg_mgr_init(&mgr); // Mongoose event manager
|
||||||
|
mg_log_set(MG_LL_DEBUG); // Set log level
|
||||||
|
|
||||||
|
MG_INFO(("Starting, CPU freq %g MHz", (double) SystemCoreClock / 1000000));
|
||||||
|
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mgr);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Initialise Mongoose network stack
|
||||||
|
struct mg_tcpip_driver_stm32h_data driver_data = {.mdc_cr = 4};
|
||||||
|
struct mg_tcpip_if mif = {.mac = GENERATE_MAC_ADDRESS(),
|
||||||
|
// 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_stm32h,
|
||||||
|
.driver_data = &driver_data};
|
||||||
|
mg_tcpip_init(&mgr, &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..."));
|
||||||
|
web_init(&mgr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MG_INFO(("Starting event loop"));
|
||||||
|
for (;;) {
|
||||||
|
mg_mgr_poll(&mgr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../mongoose.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../mongoose.h
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// See https://mongoose.ws/documentation/#build-options
|
||||||
|
#define MG_ARCH MG_ARCH_NEWLIB
|
||||||
|
#define MG_OTA MG_OTA_FLASH
|
||||||
|
#define MG_DEVICE MG_DEVICE_STM32H5
|
||||||
|
|
||||||
|
#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_DRIVER_STM32H 1
|
||||||
|
//#define MG_ENABLE_LINES 1
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../device-dashboard/net.c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../device-dashboard/net.h
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../device-dashboard/packed_fs.c
|
||||||
Reference in new issue
Block a user