Add driver for CMSIS-Driver

This commit is contained in:
Sergio R. Caprile 2023-10-12 19:52:18 -03:00
parent b357485523
commit b792304cf8
21 changed files with 1016 additions and 0 deletions

View File

@ -359,6 +359,7 @@ jobs:
- path: stm32/nucleo-f746zg-make-freertos-builtin
- path: stm32/nucleo-f746zg-make-freertos-tcp
- path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
- path: stm32/nucleo-g031-make-baremetal-builtin
- path: stm32/nucleo-h563zi-make-baremetal-builtin
- path: stm32/nucleo-h563zi-make-freertos-builtin

View File

@ -0,0 +1,212 @@
/******************************************************************************
* File Name : MX_Device.h
* Date : 14/03/2023 13:27:52
* Description : STM32Cube MX parameter definitions
* Note : This file is generated by STM32CubeMX (DO NOT EDIT!)
******************************************************************************/
#ifndef __MX_DEVICE_H
#define __MX_DEVICE_H
/*---------------------------- Clock Configuration ---------------------------*/
#define MX_LSI_VALUE 32000
#define MX_LSE_VALUE 32768
#define MX_HSI_VALUE 16000000
#define MX_HSE_VALUE 25000000
#define MX_EXTERNAL_CLOCK_VALUE 12288000
#define MX_SYSCLKFreq_VALUE 216000000
#define MX_HCLKFreq_Value 216000000
#define MX_FCLKCortexFreq_Value 216000000
#define MX_CortexFreq_Value 216000000
#define MX_AHBFreq_Value 216000000
#define MX_APB1Freq_Value 54000000
#define MX_APB2Freq_Value 108000000
#define MX_APB1TimFreq_Value 108000000
#define MX_APB2TimFreq_Value 216000000
#define MX_EthernetFreq_Value 216000000
#define MX_CECFreq_Value 32786
#define MX_LCDTFToutputFreq_Value 96000000
#define MX_I2C1Freq_Value 54000000
#define MX_I2C2Freq_Value 54000000
#define MX_I2C3Freq_Value 54000000
#define MX_I2C4Freq_Value 54000000
#define MX_I2SFreq_Value 192000000
#define MX_SAI1Freq_Value 192000000
#define MX_SAI2Freq_Value 192000000
#define MX_SDMMCFreq_Value 216000000
#define MX_RTCFreq_Value 32000
#define MX_USART1Freq_Value 108000000
#define MX_USART2Freq_Value 54000000
#define MX_USART3Freq_Value 54000000
#define MX_UART4Freq_Value 54000000
#define MX_UART5Freq_Value 54000000
#define MX_UART8Freq_Value 54000000
#define MX_UART7Freq_Value 54000000
#define MX_USART6Freq_Value 108000000
#define MX_USBFreq_Value 48000000
#define MX_WatchDogFreq_Value 32000
#define MX_LPTIM1Freq_Value 54000000
#define MX_SPDIFRXFreq_Value 192000000
#define MX_MCO1PinFreq_Value 16000000
#define MX_MCO2PinFreq_Value 216000000
/*-------------------------------- CORTEX_M7 --------------------------------*/
#define MX_CORTEX_M7 1
/* GPIO Configuration */
/*-------------------------------- ETH --------------------------------*/
#define MX_ETH 1
/* GPIO Configuration */
/* Pin PA1 */
#define MX_ETH_REF_CLK_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_REF_CLK_Pin PA1
#define MX_ETH_REF_CLK_GPIOx GPIOA
#define MX_ETH_REF_CLK_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_REF_CLK_GPIO_Pin GPIO_PIN_1
#define MX_ETH_REF_CLK_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_REF_CLK_GPIO_Mode GPIO_MODE_AF_PP
/* Pin PA7 */
#define MX_ETH_CRS_DV_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_CRS_DV_Pin PA7
#define MX_ETH_CRS_DV_GPIOx GPIOA
#define MX_ETH_CRS_DV_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_CRS_DV_GPIO_Pin GPIO_PIN_7
#define MX_ETH_CRS_DV_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_CRS_DV_GPIO_Mode GPIO_MODE_AF_PP
/* Pin PC4 */
#define MX_ETH_RXD0_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_RXD0_Pin PC4
#define MX_ETH_RXD0_GPIOx GPIOC
#define MX_ETH_RXD0_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_RXD0_GPIO_Pin GPIO_PIN_4
#define MX_ETH_RXD0_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_RXD0_GPIO_Mode GPIO_MODE_AF_PP
/* Pin PC5 */
#define MX_ETH_RXD1_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_RXD1_Pin PC5
#define MX_ETH_RXD1_GPIOx GPIOC
#define MX_ETH_RXD1_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_RXD1_GPIO_Pin GPIO_PIN_5
#define MX_ETH_RXD1_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_RXD1_GPIO_Mode GPIO_MODE_AF_PP
/* Pin PG11 */
#define MX_ETH_TX_EN_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_TX_EN_Pin PG11
#define MX_ETH_TX_EN_GPIOx GPIOG
#define MX_ETH_TX_EN_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_TX_EN_GPIO_Pin GPIO_PIN_11
#define MX_ETH_TX_EN_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_TX_EN_GPIO_Mode GPIO_MODE_AF_PP
/* Pin PA2 */
#define MX_ETH_MDIO_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_MDIO_Pin PA2
#define MX_ETH_MDIO_GPIOx GPIOA
#define MX_ETH_MDIO_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_MDIO_GPIO_Pin GPIO_PIN_2
#define MX_ETH_MDIO_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_MDIO_GPIO_Mode GPIO_MODE_AF_PP
/* Pin PB13 */
#define MX_ETH_TXD1_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_TXD1_Pin PB13
#define MX_ETH_TXD1_GPIOx GPIOB
#define MX_ETH_TXD1_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_TXD1_GPIO_Pin GPIO_PIN_13
#define MX_ETH_TXD1_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_TXD1_GPIO_Mode GPIO_MODE_AF_PP
/* Pin PG13 */
#define MX_ETH_TXD0_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_TXD0_Pin PG13
#define MX_ETH_TXD0_GPIOx GPIOG
#define MX_ETH_TXD0_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_TXD0_GPIO_Pin GPIO_PIN_13
#define MX_ETH_TXD0_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_TXD0_GPIO_Mode GPIO_MODE_AF_PP
/* Pin PC1 */
#define MX_ETH_MDC_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_ETH_MDC_Pin PC1
#define MX_ETH_MDC_GPIOx GPIOC
#define MX_ETH_MDC_GPIO_PuPd GPIO_NOPULL
#define MX_ETH_MDC_GPIO_Pin GPIO_PIN_1
#define MX_ETH_MDC_GPIO_AF GPIO_AF11_ETH
#define MX_ETH_MDC_GPIO_Mode GPIO_MODE_AF_PP
/* NVIC Configuration */
/* NVIC ETH_IRQn */
#define MX_ETH_IRQn_interruptPremptionPriority 0
#define MX_ETH_IRQn_PriorityGroup NVIC_PRIORITYGROUP_4
#define MX_ETH_IRQn_Subriority 0
/*-------------------------------- RNG --------------------------------*/
#define MX_RNG 1
/* GPIO Configuration */
/*-------------------------------- SYS --------------------------------*/
#define MX_SYS 1
/* GPIO Configuration */
/*-------------------------------- USART3 --------------------------------*/
#define MX_USART3 1
#define MX_USART3_VM VM_ASYNC
/* GPIO Configuration */
/* Pin PD8 */
#define MX_USART3_TX_GPIO_ModeDefaultPP GPIO_MODE_AF_PP
#define MX_USART3_TX_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_USART3_TX_Pin PD8
#define MX_USART3_TX_GPIOx GPIOD
#define MX_USART3_TX_GPIO_PuPd GPIO_NOPULL
#define MX_USART3_TX_GPIO_Pin GPIO_PIN_8
#define MX_USART3_TX_GPIO_AF GPIO_AF7_USART3
/* Pin PD9 */
#define MX_USART3_RX_GPIO_ModeDefaultPP GPIO_MODE_AF_PP
#define MX_USART3_RX_GPIO_Speed GPIO_SPEED_FREQ_VERY_HIGH
#define MX_USART3_RX_Pin PD9
#define MX_USART3_RX_GPIOx GPIOD
#define MX_USART3_RX_GPIO_PuPd GPIO_NOPULL
#define MX_USART3_RX_GPIO_Pin GPIO_PIN_9
#define MX_USART3_RX_GPIO_AF GPIO_AF7_USART3
/*-------------------------------- NVIC --------------------------------*/
#define MX_NVIC 1
/*-------------------------------- GPIO --------------------------------*/
#define MX_GPIO 1
/* GPIO Configuration */
/* Pin PB7 */
#define MX_PB7_GPIO_Speed GPIO_SPEED_FREQ_LOW
#define MX_PB7_Pin PB7
#define MX_PB7_GPIOx GPIOB
#define MX_PB7_PinState GPIO_PIN_RESET
#define MX_PB7_GPIO_PuPd GPIO_NOPULL
#define MX_PB7_GPIO_Pin GPIO_PIN_7
#define MX_PB7_GPIO_ModeDefaultOutputPP GPIO_MODE_OUTPUT_PP
#endif /* __MX_DEVICE_H */

View File

@ -0,0 +1,82 @@
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.
# CMSIS Driver specifics, and its dependencies
CFLAGS += -Icmsis_core/CMSIS/Core/Include # CMSIS core headers
CFLAGS += -Icmsis_core/CMSIS/Driver/Include -Icmsis_driver/ETH # CMSIS Driver core and ETH headers
CFLAGS += -Icmsis_mcu/CMSIS/Driver # CMSIS Driver device driver headers
CFLAGS += -D__MEMORY_AT\(x\)= # disable using specific memory address for Eth buffers
CFLAGS += -Icmsis_mcu/Drivers/CMSIS/Device/ST/STM32F7xx/Include -DSTM32F746xx # CMSIS device headers
CFLAGS += -Icmsis_mcu/Drivers/STM32F7xx_HAL_Driver/Inc/ # HAL headers, required by CMSIS Driver device driver (HAL-based)
CFLAGS += -Icmsis_mcu/MDK/Templates/Inc/ # pull stm32f7xx_hal_conf.h (HAL configuration)
CFLAGS += -DRTE_DEVICE_HAL_ETH -DRTE_DEVICE_HAL_GPIO -DRTE_DEVICE_HAL_RCC # configure it
CFLAGS += -DRTE_DEVICE_HAL_COMMON -DRTE_DEVICE_FRAMEWORK_CUBE_MX
CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16
LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
SOURCES = main.c syscalls.c sysinit.c
# CMSIS Driver specifics, and its dependencies
SOURCES += cmsis_driver/ETH/PHY_LAN8742A.c # CMSIS Driver for the PHY present in this board
CFLAGS += -Wno-conversion # avoid warnings when building it
SOURCES += cmsis_mcu/CMSIS/Driver/EMAC_STM32F7xx.c # CMSIS Driver for EMAC peripheral
SOURCES += cmsis_mcu/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_eth.c # HAL sources required by the driver
SOURCES += cmsis_mcu/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c
SOURCES += cmsis_mcu/Drivers/CMSIS/Device/ST/STM32F7xx/Source/Templates/gcc/startup_stm32f746xx.s # ST startup file. Compiler-dependent!
# Mongoose-specific. See https://mongoose.ws/documentation/#build-options
SOURCES += mongoose.c net.c packed_fs.c
CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1
CFLAGS += -DMG_ENABLE_CUSTOM_RANDOM=1 -DMG_ENABLE_PACKED_FS=1
CFLAGS += -DMG_ENABLE_DRIVER_CMSIS=1 $(CFLAGS_EXTRA)
# 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_driver cmsis_mcu $(SOURCES) hal.h link.ld Makefile
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
flash: firmware.bin
st-flash --reset write $< 0x8000000
cmsis_core: # ARM CMSIS core headers
git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
cmsis_driver: # ARM CMSIS Driver code and headers
git clone --depth 1 -b 2.7.2 https://github.com/ARM-software/CMSIS-Driver $@
cmsis_mcu: # Keil CMSIS headers and drivers for STM32F7 series (CMSIS-pack)
curl -sL https://www.keil.com/pack/Keil.STM32F7xx_DFP.2.15.2.pack -o $@.zip
mkdir $@ && cd $@ && unzip -q ../$@.zip
mbedtls: # mbedTLS library
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
ifeq ($(TLS), mbedtls)
CFLAGS += -DMG_TLS=MG_TLS_MBED -Wno-conversion -Imbedtls/include
CFLAGS += -DMBEDTLS_CONFIG_FILE=\"mbedtls_config.h\" mbedtls/library/*.c
firmware.elf: mbedtls
endif
# 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/5
update: firmware.bin
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
test update: CFLAGS += -DUART_DEBUG=USART1
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
# grep 'MQTT connected' /tmp/output.txt # Check for MQTT connection success
clean:
$(RM) firmware.* *.su cmsis_core cmsis_driver cmsis_mcu* mbedtls

View File

@ -0,0 +1,17 @@
# CMSIS-Driver example
Mongoose includes a driver for CMSIS-Driver, that is, Mongoose built-in TCP/IP stack can run over any (ARM) chip that has a CMSIS Driver for its Ethernet controller, and uses a PHY that also has a CMSIS Driver. You can follow this example to use Mongoose there, the Makefile in this example performs the following list of actions.
Actions:
- Pull CMSIS core, this also includes the basic support for CMSIS Driver
- Pull CMSIS Driver, this repository has driver code for several widely used PHYs and some Ethernet chips (stand-alone controllers, not MCUs)
- Pull the device family CMSIS Pack, this includes CMSIS headers and also includes CMSIS Drivers for those peripherals that have Middleware (Ethernet, CAN, UART...) available
- The rest of the job is to find and solve the driver dependencies. In this example, the CMSIS Driver for the STM32F746 uses the STM32 HAL, so we have copied some files from an STM32CubeMX generated project in order to have some defines available, then picked the correct sources to compile, and provided a HAL_GetTick() function to satisfy those parts of the HAL that use it, without having to include more pieces of the HAL, as we already have a time base in place.
- Finally,
- enable the driver by defining `MG_ENABLE_DRIVER_CMSIS=1`
- select it in your `main.c`
```c
struct mg_tcpip_if mif = {.driver = &mg_tcpip_driver_cmsis}
```

View File

@ -0,0 +1,164 @@
// Copyright (c) 2022 Cesanta Software Limited
// All rights reserved
// https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf
// https://www.st.com/resource/en/datasheet/stm32f746zg.pdf
#pragma once
#include <stm32f746xx.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define BIT(x) (1UL << (x))
#define SETBITS(R, CLEARMASK, SETMASK) (R) = ((R) & ~(CLEARMASK)) | (SETMASK)
#define PIN(bank, num) ((((bank) - 'A') << 8) | (num))
#define PINNO(pin) (pin & 255)
#define PINBANK(pin) (pin >> 8)
#define LED1 PIN('B', 0) // On-board LED pin (green)
#define LED2 PIN('B', 7) // On-board LED pin (blue)
#define LED3 PIN('B', 14) // On-board LED pin (red)
#define LED LED2 // Use blue LED for blinking
/* System clock
5.3.3: APB1 clock <= 54MHz; APB2 clock <= 108MHz
3.3.2, Table 5: configure flash latency (WS) in accordance to clock freq
38.4: The AHB clock frequency must be at least 25 MHz when the Ethernet
controller is used */
enum { APB1_PRE = 5 /* AHB clock / 4 */, APB2_PRE = 4 /* AHB clock / 2 */ };
enum { PLL_HSI = 16, PLL_M = 8, PLL_N = 216, PLL_P = 2 }; // Run at 216 Mhz
#define FLASH_LATENCY 7
#define SYS_FREQUENCY ((PLL_HSI * PLL_N / PLL_M / PLL_P) * 1000000)
#define APB2_FREQUENCY (SYS_FREQUENCY / (BIT(APB2_PRE - 3)))
#define APB1_FREQUENCY (SYS_FREQUENCY / (BIT(APB1_PRE - 3)))
static inline void spin(volatile uint32_t count) {
while (count--) (void) 0;
}
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG };
enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN };
enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_HIGH, GPIO_SPEED_INSANE };
enum { GPIO_PULL_NONE, GPIO_PULL_UP, GPIO_PULL_DOWN };
#define GPIO(N) ((GPIO_TypeDef *) (0x40020000 + 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->BSRR = mask << (gpio->ODR & mask ? 16 : 0);
}
static inline int gpio_read(uint16_t pin) {
return gpio_bank(pin)->IDR & BIT(PINNO(pin)) ? 1 : 0;
}
static inline void gpio_write(uint16_t pin, bool val) {
GPIO_TypeDef *gpio = gpio_bank(pin);
gpio->BSRR = BIT(PINNO(pin)) << (val ? 0 : 16);
}
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type,
uint8_t speed, uint8_t pull, uint8_t af) {
GPIO_TypeDef *gpio = gpio_bank(pin);
uint8_t n = (uint8_t) (PINNO(pin));
RCC->AHB1ENR |= BIT(PINBANK(pin)); // Enable GPIO clock
SETBITS(gpio->OTYPER, 1UL << n, ((uint32_t) type) << n);
SETBITS(gpio->OSPEEDR, 3UL << (n * 2), ((uint32_t) speed) << (n * 2));
SETBITS(gpio->PUPDR, 3UL << (n * 2), ((uint32_t) pull) << (n * 2));
SETBITS(gpio->AFR[n >> 3], 15UL << ((n & 7) * 4),
((uint32_t) af) << ((n & 7) * 4));
SETBITS(gpio->MODER, 3UL << (n * 2), ((uint32_t) mode) << (n * 2));
}
static inline void gpio_input(uint16_t pin) {
gpio_init(pin, GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH,
GPIO_PULL_NONE, 0);
}
static inline void gpio_output(uint16_t pin) {
gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH,
GPIO_PULL_NONE, 0);
}
static inline void irq_exti_attach(uint16_t pin) {
uint8_t bank = (uint8_t) (PINBANK(pin)), n = (uint8_t) (PINNO(pin));
SYSCFG->EXTICR[n / 4] &= ~(15UL << ((n % 4) * 4));
SYSCFG->EXTICR[n / 4] |= (uint32_t) (bank << ((n % 4) * 4));
EXTI->IMR |= BIT(n);
EXTI->RTSR |= BIT(n);
EXTI->FTSR |= BIT(n);
int irqvec = n < 5 ? 6 + n : n < 10 ? 23 : 40; // IRQ vector index, 10.1.2
NVIC_SetPriority(irqvec, 3);
NVIC_EnableIRQ(irqvec);
}
#ifndef UART_DEBUG
#define UART_DEBUG USART3
#endif
static inline void uart_init(USART_TypeDef *uart, unsigned long baud) {
uint8_t af = 7; // Alternate function
uint16_t rx = 0, tx = 0; // pins
uint32_t freq = 0; // Bus frequency. UART1 is on APB2, rest on APB1
if (uart == USART1) freq = APB2_FREQUENCY, RCC->APB2ENR |= BIT(4);
if (uart == USART2) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(17);
if (uart == USART3) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(18);
if (uart == USART1) tx = PIN('A', 9), rx = PIN('A', 10);
if (uart == USART2) tx = PIN('A', 2), rx = PIN('A', 3);
if (uart == USART3) tx = PIN('D', 8), rx = PIN('D', 9);
gpio_init(tx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af);
gpio_init(rx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af);
uart->CR1 = 0; // Disable this UART
uart->BRR = freq / baud; // Set baud rate
uart->CR1 |= BIT(0) | BIT(2) | BIT(3); // Set UE, RE, TE
}
static inline void uart_write_byte(USART_TypeDef *uart, uint8_t byte) {
uart->TDR = byte;
while ((uart->ISR & BIT(7)) == 0) 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->ISR & BIT(5); // If RXNE bit is set, data is ready
}
static inline uint8_t uart_read_byte(USART_TypeDef *uart) {
return (uint8_t) (uart->RDR & 255);
}
static inline void rng_init(void) {
RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
RNG->CR |= RNG_CR_RNGEN;
}
static inline uint32_t rng_read(void) {
while ((RNG->SR & RNG_SR_DRDY) == 0) (void) 0;
return RNG->DR;
}
static inline void ethernet_init(void) {
// Initialise Ethernet. Enable MAC GPIO pins, see
// https://www.farnell.com/datasheets/2014265.pdf section 6.10
uint16_t pins[] = {PIN('A', 1), PIN('A', 2), PIN('A', 7),
PIN('B', 13), PIN('C', 1), PIN('C', 4),
PIN('C', 5), PIN('G', 11), PIN('G', 13)};
for (size_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) {
gpio_init(pins[i], GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_INSANE,
GPIO_PULL_NONE, 11); // 11 is the Ethernet function
}
NVIC_EnableIRQ(ETH_IRQn); // Setup Ethernet IRQ handler
SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; // Use RMII. Goes first!
RCC->AHB1ENR |=
RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN;
}
#define UUID ((uint8_t *) UID_BASE) // Unique 96-bit chip ID. TRM 41.1
// Helper macro for MAC generation
#define GENERATE_LOCALLY_ADMINISTERED_MAC() \
{ \
2, UUID[0] ^ UUID[1], UUID[2] ^ UUID[3], UUID[4] ^ UUID[5], \
UUID[6] ^ UUID[7] ^ UUID[8], UUID[9] ^ UUID[10] ^ UUID[11] \
}

View File

@ -0,0 +1,29 @@
ENTRY(Reset_Handler);
MEMORY {
flash(rx) : ORIGIN = 0x08000000, LENGTH = 1024k
sram(rwx) : ORIGIN = 0x20000000, LENGTH = 320k
}
_estack = ORIGIN(sram) + LENGTH(sram); /* stack points to end of SRAM */
SECTIONS {
.vectors : { KEEP(*(.isr_vector)) } > flash
.text : { *(.text* .text.*) } > flash
.rodata : { *(.rodata*) } > flash
.data : {
_sdata = .; /* for init_ram() */
*(.first_data)
*(.data SORT(.data.*))
_edata = .; /* for init_ram() */
} > sram AT > flash
_sidata = LOADADDR(.data);
.bss : {
_sbss = .; /* for init_ram() */
*(.bss SORT(.bss.*) COMMON)
_ebss = .; /* for init_ram() */
} > sram
. = ALIGN(8);
_end = .; /* for cmsis_gcc.h and init_ram() */
}

View File

@ -0,0 +1,76 @@
// 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 volatile uint64_t s_ticks; // Milliseconds since boot
void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
s_ticks++;
}
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); // Blink LED
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));
}
int main(void) {
gpio_output(LED); // Setup blue LED
uart_init(UART_DEBUG, 115200); // Initialise debug printf
ethernet_init(); // Initialise ethernet pins
MG_INFO(("Starting, CPU freq %g MHz", (double) SystemCoreClock / 1000000));
struct mg_mgr mgr; // Initialise
mg_mgr_init(&mgr); // Mongoose event manager
mg_log_set(MG_LL_DEBUG); // Set log level
// Initialise Mongoose network stack
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_cmsis};
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..."));
web_init(&mgr);
MG_INFO(("Starting event loop"));
for (;;) {
mg_mgr_poll(&mgr, 0);
}
return 0;
}
#include "stm32f7xx_hal.h"
ETH_HandleTypeDef heth;
uint32_t HAL_GetTick(void) { // we already have a time base function
return (uint32_t) s_ticks;
}

View File

@ -0,0 +1,53 @@
/* Workaround for some mbedtls source files using INT_MAX without including limits.h */
#include <limits.h>
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_SSL_OUT_CONTENT_LEN 2048
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
#define MBEDTLS_HAVE_TIME
#define MBEDTLS_SSL_SESSION_TICKETS
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_SHA256_SMALLER
#define MBEDTLS_SSL_SERVER_NAME_INDICATION
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_ERROR_C
#define MBEDTLS_MD_C
#define MBEDTLS_MD5_C
#define MBEDTLS_OID_C
#define MBEDTLS_PKCS5_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_PLATFORM_C
#define MBEDTLS_RSA_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_BASE64_C
#define MBEDTLS_SSL_TICKET_C
#define MBEDTLS_SSL_PROTO_TLS1_2
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#define MBEDTLS_GCM_C
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ASN1_WRITE_C

View File

@ -0,0 +1 @@
../../../mongoose.c

View File

@ -0,0 +1 @@
../../../mongoose.h

View File

@ -0,0 +1 @@
../../device-dashboard/net.c

View File

@ -0,0 +1 @@
../../device-dashboard/net.h

View File

@ -0,0 +1 @@
../../device-dashboard/packed_fs.c

View File

@ -0,0 +1,98 @@
#include <sys/stat.h>
#include "hal.h"
int _fstat(int fd, struct stat *st) {
if (fd < 0) return -1;
st->st_mode = S_IFCHR;
return 0;
}
void *_sbrk(int incr) {
extern char _end;
static unsigned char *heap = NULL;
unsigned char *prev_heap;
unsigned char x = 0, *heap_end = (unsigned char *)((size_t) &x - 512);
(void) x;
if (heap == NULL) heap = (unsigned char *) &_end;
prev_heap = heap;
if (heap + incr > heap_end) return (void *) -1;
heap += 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) {}
extern uint64_t mg_now(void);
int _gettimeofday(struct timeval *tv, void *tz) {
uint64_t now = mg_now();
(void) tz;
tv->tv_sec = (time_t) (now / 1000);
tv->tv_usec = (unsigned long) ((now % 1000) * 1000);
return 0;
}

View File

@ -0,0 +1,29 @@
// Copyright (c) 2023 Cesanta Software Limited
// All rights reserved
//
// This file contains essentials required by the CMSIS:
// uint32_t SystemCoreClock - holds the system core clock value
// SystemInit() - initialises the system, e.g. sets up clocks
#include "hal.h"
uint32_t SystemCoreClock = SYS_FREQUENCY;
void SystemInit(void) { // Called automatically by startup code
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU
asm("DSB");
asm("ISB");
FLASH->ACR |= FLASH_LATENCY | BIT(8) | BIT(9); // Flash latency, prefetch
RCC->PLLCFGR &= ~((BIT(17) - 1)); // Clear PLL multipliers
RCC->PLLCFGR |= (((PLL_P - 2) / 2) & 3) << 16; // Set PLL_P
RCC->PLLCFGR |= PLL_M | (PLL_N << 6); // Set PLL_M and PLL_N
RCC->CR |= BIT(24); // Enable PLL
while ((RCC->CR & BIT(25)) == 0) spin(1); // Wait until done
RCC->CFGR = (APB1_PRE << 10) | (APB2_PRE << 13); // Set prescalers
RCC->CFGR |= 2; // Set clock source to PLL
while ((RCC->CFGR & 12) == 0) spin(1); // Wait until done
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Enable SYSCFG
rng_init(); // Initialise random number generator
SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms
}

View File

@ -8433,6 +8433,124 @@ size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
return c->send.len;
}
#ifdef MG_ENABLE_LINES
#line 1 "src/drivers/cmsis.c"
#endif
// https://arm-software.github.io/CMSIS_5/Driver/html/index.html
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CMSIS) && MG_ENABLE_DRIVER_CMSIS
extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0;
extern ARM_DRIVER_ETH_PHY Driver_ETH_PHY0;
static struct mg_tcpip_if *s_ifp;
static void mac_cb(uint32_t);
static bool cmsis_init(struct mg_tcpip_if *);
static bool cmsis_up(struct mg_tcpip_if *);
static size_t cmsis_tx(const void *, size_t, struct mg_tcpip_if *);
static size_t cmsis_rx(void *, size_t, struct mg_tcpip_if *);
struct mg_tcpip_driver mg_tcpip_driver_cmsis = {cmsis_init, cmsis_tx, NULL,
cmsis_up};
static bool cmsis_init(struct mg_tcpip_if *ifp) {
ARM_ETH_MAC_ADDR addr;
s_ifp = ifp;
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
ARM_DRIVER_ETH_PHY *phy = &Driver_ETH_PHY0;
ARM_ETH_MAC_CAPABILITIES cap = mac->GetCapabilities();
if (mac->Initialize(mac_cb) != ARM_DRIVER_OK) return false;
if (phy->Initialize(mac->PHY_Read, mac->PHY_Write) != ARM_DRIVER_OK)
return false;
if (cap.event_rx_frame == 0) // polled mode driver
mg_tcpip_driver_cmsis.rx = cmsis_rx;
mac->PowerControl(ARM_POWER_FULL);
if (cap.mac_address) { // driver provides MAC address
mac->GetMacAddress(&addr);
memcpy(ifp->mac, &addr, sizeof(ifp->mac));
} else { // we provide MAC address
memcpy(&addr, ifp->mac, sizeof(addr));
mac->SetMacAddress(&addr);
}
phy->PowerControl(ARM_POWER_FULL);
phy->SetInterface(cap.media_interface);
phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE);
return true;
}
static size_t cmsis_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
if (mac->SendFrame(buf, (uint32_t) len, 0) != ARM_DRIVER_OK) {
ifp->nerr++;
return 0;
}
ifp->nsent++;
return len;
}
static bool cmsis_up(struct mg_tcpip_if *ifp) {
ARM_DRIVER_ETH_PHY *phy = &Driver_ETH_PHY0;
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
bool up = (phy->GetLinkState() == ARM_ETH_LINK_UP) ? 1 : 0; // link state
if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // just went up
ARM_ETH_LINK_INFO st = phy->GetLinkInfo();
mac->Control(ARM_ETH_MAC_CONFIGURE,
(st.speed << ARM_ETH_MAC_SPEED_Pos) |
(st.duplex << ARM_ETH_MAC_DUPLEX_Pos) |
ARM_ETH_MAC_ADDRESS_BROADCAST);
MG_DEBUG(("Link is %uM %s-duplex",
(st.speed == 2) ? 1000
: st.speed ? 100
: 10,
st.duplex ? "full" : "half"));
mac->Control(ARM_ETH_MAC_CONTROL_TX, 1);
mac->Control(ARM_ETH_MAC_CONTROL_RX, 1);
} else if ((ifp->state != MG_TCPIP_STATE_DOWN) && !up) { // just went down
mac->Control(ARM_ETH_MAC_FLUSH,
ARM_ETH_MAC_FLUSH_TX | ARM_ETH_MAC_FLUSH_RX);
mac->Control(ARM_ETH_MAC_CONTROL_TX, 0);
mac->Control(ARM_ETH_MAC_CONTROL_RX, 0);
}
return up;
}
static void mac_cb(uint32_t ev) {
if ((ev & ARM_ETH_MAC_EVENT_RX_FRAME) == 0) return;
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
uint32_t len = mac->GetRxFrameSize(); // CRC already stripped
if (len >= 60 && len <= 1518) { // proper frame
char *p;
if (mg_queue_book(&s_ifp->recv_queue, &p, len) >= len) { // have room
if ((len = mac->ReadFrame((uint8_t *) p, len)) > 0) { // copy succeeds
mg_queue_add(&s_ifp->recv_queue, len);
s_ifp->nrecv++;
}
return;
}
s_ifp->ndrop++;
}
mac->ReadFrame(NULL, 0); // otherwise, discard
}
static size_t cmsis_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
uint32_t len = mac->GetRxFrameSize(); // CRC already stripped
if (len >= 60 && len <= 1518 &&
((len = mac->ReadFrame(buf, (uint32_t) buflen)) > 0))
return len;
if (len > 0) mac->ReadFrame(NULL, 0); // discard bad frames
(void) ifp;
return 0;
}
#endif
#ifdef MG_ENABLE_LINES
#line 1 "src/drivers/rt1020.c"
#endif

View File

@ -1791,6 +1791,7 @@ extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
extern struct mg_tcpip_driver mg_tcpip_driver_rt1020;
extern struct mg_tcpip_driver mg_tcpip_driver_same54;
extern struct mg_tcpip_driver mg_tcpip_driver_cmsis;
// Drivers that require SPI, can use this SPI abstraction
struct mg_tcpip_spi {
@ -1802,6 +1803,14 @@ struct mg_tcpip_spi {
#endif
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CMSIS) && MG_ENABLE_DRIVER_CMSIS
#include "Driver_ETH_MAC.h" // keep this include
#include "Driver_ETH_PHY.h" // keep this include
#endif
struct mg_tcpip_driver_rt1020_data {
// MDC clock divider. MDC clock is derived from IPS Bus clock (ipg_clk),
// must not exceed 2.5MHz. Configuration for clock range 2.36~2.50 MHz

114
src/drivers/cmsis.c Normal file
View File

@ -0,0 +1,114 @@
// https://arm-software.github.io/CMSIS_5/Driver/html/index.html
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CMSIS) && MG_ENABLE_DRIVER_CMSIS
#include "cmsis.h"
#include "net_builtin.h"
#include "queue.h"
extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0;
extern ARM_DRIVER_ETH_PHY Driver_ETH_PHY0;
static struct mg_tcpip_if *s_ifp;
static void mac_cb(uint32_t);
static bool cmsis_init(struct mg_tcpip_if *);
static bool cmsis_up(struct mg_tcpip_if *);
static size_t cmsis_tx(const void *, size_t, struct mg_tcpip_if *);
static size_t cmsis_rx(void *, size_t, struct mg_tcpip_if *);
struct mg_tcpip_driver mg_tcpip_driver_cmsis = {cmsis_init, cmsis_tx, NULL,
cmsis_up};
static bool cmsis_init(struct mg_tcpip_if *ifp) {
ARM_ETH_MAC_ADDR addr;
s_ifp = ifp;
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
ARM_DRIVER_ETH_PHY *phy = &Driver_ETH_PHY0;
ARM_ETH_MAC_CAPABILITIES cap = mac->GetCapabilities();
if (mac->Initialize(mac_cb) != ARM_DRIVER_OK) return false;
if (phy->Initialize(mac->PHY_Read, mac->PHY_Write) != ARM_DRIVER_OK)
return false;
if (cap.event_rx_frame == 0) // polled mode driver
mg_tcpip_driver_cmsis.rx = cmsis_rx;
mac->PowerControl(ARM_POWER_FULL);
if (cap.mac_address) { // driver provides MAC address
mac->GetMacAddress(&addr);
memcpy(ifp->mac, &addr, sizeof(ifp->mac));
} else { // we provide MAC address
memcpy(&addr, ifp->mac, sizeof(addr));
mac->SetMacAddress(&addr);
}
phy->PowerControl(ARM_POWER_FULL);
phy->SetInterface(cap.media_interface);
phy->SetMode(ARM_ETH_PHY_AUTO_NEGOTIATE);
return true;
}
static size_t cmsis_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
if (mac->SendFrame(buf, (uint32_t) len, 0) != ARM_DRIVER_OK) {
ifp->nerr++;
return 0;
}
ifp->nsent++;
return len;
}
static bool cmsis_up(struct mg_tcpip_if *ifp) {
ARM_DRIVER_ETH_PHY *phy = &Driver_ETH_PHY0;
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
bool up = (phy->GetLinkState() == ARM_ETH_LINK_UP) ? 1 : 0; // link state
if ((ifp->state == MG_TCPIP_STATE_DOWN) && up) { // just went up
ARM_ETH_LINK_INFO st = phy->GetLinkInfo();
mac->Control(ARM_ETH_MAC_CONFIGURE,
(st.speed << ARM_ETH_MAC_SPEED_Pos) |
(st.duplex << ARM_ETH_MAC_DUPLEX_Pos) |
ARM_ETH_MAC_ADDRESS_BROADCAST);
MG_DEBUG(("Link is %uM %s-duplex",
(st.speed == 2) ? 1000
: st.speed ? 100
: 10,
st.duplex ? "full" : "half"));
mac->Control(ARM_ETH_MAC_CONTROL_TX, 1);
mac->Control(ARM_ETH_MAC_CONTROL_RX, 1);
} else if ((ifp->state != MG_TCPIP_STATE_DOWN) && !up) { // just went down
mac->Control(ARM_ETH_MAC_FLUSH,
ARM_ETH_MAC_FLUSH_TX | ARM_ETH_MAC_FLUSH_RX);
mac->Control(ARM_ETH_MAC_CONTROL_TX, 0);
mac->Control(ARM_ETH_MAC_CONTROL_RX, 0);
}
return up;
}
static void mac_cb(uint32_t ev) {
if ((ev & ARM_ETH_MAC_EVENT_RX_FRAME) == 0) return;
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
uint32_t len = mac->GetRxFrameSize(); // CRC already stripped
if (len >= 60 && len <= 1518) { // proper frame
char *p;
if (mg_queue_book(&s_ifp->recv_queue, &p, len) >= len) { // have room
if ((len = mac->ReadFrame((uint8_t *) p, len)) > 0) { // copy succeeds
mg_queue_add(&s_ifp->recv_queue, len);
s_ifp->nrecv++;
}
return;
}
s_ifp->ndrop++;
}
mac->ReadFrame(NULL, 0); // otherwise, discard
}
static size_t cmsis_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
ARM_DRIVER_ETH_MAC *mac = &Driver_ETH_MAC0;
uint32_t len = mac->GetRxFrameSize(); // CRC already stripped
if (len >= 60 && len <= 1518 &&
((len = mac->ReadFrame(buf, (uint32_t) buflen)) > 0))
return len;
if (len > 0) mac->ReadFrame(NULL, 0); // discard bad frames
(void) ifp;
return 0;
}
#endif

8
src/drivers/cmsis.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_CMSIS) && MG_ENABLE_DRIVER_CMSIS
#include "Driver_ETH_MAC.h" // keep this include
#include "Driver_ETH_PHY.h" // keep this include
#endif

View File

@ -57,6 +57,7 @@ extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
extern struct mg_tcpip_driver mg_tcpip_driver_rt1020;
extern struct mg_tcpip_driver mg_tcpip_driver_same54;
extern struct mg_tcpip_driver mg_tcpip_driver_cmsis;
// Drivers that require SPI, can use this SPI abstraction
struct mg_tcpip_spi {