| @@ -0,0 +1,173 @@ | |||||
| /*- | |||||
| * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
| * | |||||
| * Copyright (c) 1999 John D. Polstra | |||||
| * Copyright (c) 1999,2001 Peter Wemm <peter@FreeBSD.org> | |||||
| * All rights reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * | |||||
| * $FreeBSD$ | |||||
| */ | |||||
| #ifndef _SYS_LINKER_SET_H_ | |||||
| #define _SYS_LINKER_SET_H_ | |||||
| #include <sys/cdefs.h> | |||||
| /* START cdefs.h direct import from FreeBSD */ | |||||
| /* This section has the follwing copyright */ | |||||
| /*- | |||||
| * SPDX-License-Identifier: BSD-3-Clause | |||||
| * | |||||
| * Copyright (c) 1991, 1993 | |||||
| * The Regents of the University of California. All rights reserved. | |||||
| * | |||||
| * This code is derived from software contributed to Berkeley by | |||||
| * Berkeley Software Design, Inc. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * 3. Neither the name of the University nor the names of its contributors | |||||
| * may be used to endorse or promote products derived from this software | |||||
| * without specific prior written permission. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * | |||||
| * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 | |||||
| * $FreeBSD$ | |||||
| */ | |||||
| #define __CONCAT1(x,y) x ## y | |||||
| #define __CONCAT(x,y) __CONCAT1(x,y) | |||||
| #define __STRING(x) #x /* stringify without expanding x */ | |||||
| #define __XSTRING(x) __STRING(x) /* expand x, then stringify */ | |||||
| #define __nosanitizeaddress | |||||
| #define __nosanitizememory | |||||
| #define __used __attribute__((__used__)) | |||||
| #define __weak_symbol __attribute__((__weak__)) | |||||
| /* END cdefs.h direct import */ | |||||
| /* | |||||
| * The following macros are used to declare global sets of objects, which | |||||
| * are collected by the linker into a `linker_set' as defined below. | |||||
| * For ELF, this is done by constructing a separate segment for each set. | |||||
| */ | |||||
| #if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) | |||||
| /* | |||||
| * ELFv1 pointers to functions are actaully pointers to function | |||||
| * descriptors. | |||||
| * | |||||
| * Move the symbol pointer from ".text" to ".data" segment, to make | |||||
| * the GCC compiler happy: | |||||
| */ | |||||
| #define __MAKE_SET_CONST | |||||
| #else | |||||
| #define __MAKE_SET_CONST const | |||||
| #endif | |||||
| /* | |||||
| * Private macros, not to be used outside this header file. | |||||
| */ | |||||
| #ifdef __GNUCLIKE___SECTION | |||||
| /* | |||||
| * The userspace address sanitizer inserts redzones around global variables, | |||||
| * violating the assumption that linker set elements are packed. | |||||
| */ | |||||
| #ifdef _KERNEL | |||||
| #define __NOASAN | |||||
| #else | |||||
| #define __NOASAN __nosanitizeaddress | |||||
| #endif | |||||
| #define __MAKE_SET_QV(set, sym, qv) \ | |||||
| void *__WEAK(__CONCAT(__start_set_,set)); \ | |||||
| void *__WEAK(__CONCAT(__stop_set_,set)); \ | |||||
| static void const * qv \ | |||||
| __NOASAN \ | |||||
| __set_##set##_sym_##sym __section("set_" #set) \ | |||||
| __used = &(sym) | |||||
| #define __MAKE_SET(set, sym) __MAKE_SET_QV(set, sym, __MAKE_SET_CONST) | |||||
| #else /* !__GNUCLIKE___SECTION */ | |||||
| #error this file needs to be ported to your compiler | |||||
| #endif /* __GNUCLIKE___SECTION */ | |||||
| /* | |||||
| * Public macros. | |||||
| */ | |||||
| #define TEXT_SET(set, sym) __MAKE_SET(set, sym) | |||||
| #define DATA_SET(set, sym) __MAKE_SET(set, sym) | |||||
| #define DATA_WSET(set, sym) __MAKE_SET_QV(set, sym, ) | |||||
| #define BSS_SET(set, sym) __MAKE_SET(set, sym) | |||||
| #define ABS_SET(set, sym) __MAKE_SET(set, sym) | |||||
| #define SET_ENTRY(set, sym) __MAKE_SET(set, sym) | |||||
| /* | |||||
| * Initialize before referring to a given linker set. | |||||
| */ | |||||
| #define SET_DECLARE(set, ptype) \ | |||||
| extern ptype __weak_symbol __section("set_" #set)*__CONCAT(__start_set_,set); \ | |||||
| extern ptype __weak_symbol *__CONCAT(__stop_set_,set) __section("set_" #set) | |||||
| #define SET_BEGIN(set) \ | |||||
| (&__CONCAT(__start_set_,set)) | |||||
| #define SET_LIMIT(set) \ | |||||
| (&__CONCAT(__stop_set_,set)) | |||||
| /* | |||||
| * Iterate over all the elements of a set. | |||||
| * | |||||
| * Sets always contain addresses of things, and "pvar" points to words | |||||
| * containing those addresses. Thus is must be declared as "type **pvar", | |||||
| * and the address of each set item is obtained inside the loop by "*pvar". | |||||
| */ | |||||
| #define SET_FOREACH(pvar, set) \ | |||||
| for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++) | |||||
| #define SET_ITEM(set, i) \ | |||||
| ((SET_BEGIN(set))[i]) | |||||
| /* | |||||
| * Provide a count of the items in a set. | |||||
| */ | |||||
| #define SET_COUNT(set) \ | |||||
| (SET_LIMIT(set) - SET_BEGIN(set)) | |||||
| #endif /* _SYS_LINKER_SET_H_ */ | |||||
| @@ -1,6 +1,10 @@ | |||||
| SRCS.NODE151+= board.c | SRCS.NODE151+= board.c | ||||
| SRCS.NODE151+= misc.c | SRCS.NODE151+= misc.c | ||||
| _SRCTOPDIR:= $(.PARSEDIR)/.. | |||||
| SRCTOP?=$(_SRCTOPDIR:tA) | |||||
| STM32?=$(SRCTOP)/stm32 | |||||
| ARMOBJDUMP?= arm-none-eabi-objdump | ARMOBJDUMP?= arm-none-eabi-objdump | ||||
| ARMCC?= arm-none-eabi-gcc | ARMCC?= arm-none-eabi-gcc | ||||
| @@ -10,17 +14,22 @@ ARMCC?= arm-none-eabi-gcc | |||||
| .include <$(.PARSEDIR)/mu.opts.mk> | .include <$(.PARSEDIR)/mu.opts.mk> | ||||
| .if ${MK_SYSINIT} == "yes" | |||||
| .PATH: $(SRCTOP) | |||||
| SRCS+= sysinit.c | |||||
| .endif | |||||
| # Strobe | # Strobe | ||||
| .if ${MK_STROBE} == "yes" | .if ${MK_STROBE} == "yes" | ||||
| .PATH: $(.CURDIR)/strobe | |||||
| CFLAGS+= -I$(.CURDIR)/strobe -DSTROBE_SINGLE_THREAD=1 | |||||
| .PATH: $(SRCTOP)/strobe | |||||
| CFLAGS+= -I$(SRCTOP)/strobe -DSTROBE_SINGLE_THREAD=1 | |||||
| STROBE_SRCS+= strobe.c \ | STROBE_SRCS+= strobe.c \ | ||||
| x25519.c | x25519.c | ||||
| .endif | .endif | ||||
| # LoRamac (SX1276) radio code | # LoRamac (SX1276) radio code | ||||
| .if ${MK_SX1276} == "yes" | .if ${MK_SX1276} == "yes" | ||||
| LORAMAC_SRC = $(.CURDIR)/loramac/src | |||||
| LORAMAC_SRC = $(SRCTOP)/loramac/src | |||||
| .PATH: $(LORAMAC_SRC)/radio/sx1276 $(LORAMAC_SRC)/system $(LORAMAC_SRC)/boards/mcu $(LORAMAC_SRC)/boards/NucleoL152 | .PATH: $(LORAMAC_SRC)/radio/sx1276 $(LORAMAC_SRC)/system $(LORAMAC_SRC)/boards/mcu $(LORAMAC_SRC)/boards/NucleoL152 | ||||
| CFLAGS+= -I$(LORAMAC_SRC)/boards | CFLAGS+= -I$(LORAMAC_SRC)/boards | ||||
| CFLAGS+= -I$(LORAMAC_SRC)/system | CFLAGS+= -I$(LORAMAC_SRC)/system | ||||
| @@ -32,12 +41,37 @@ SRCS+= adc.c timer.c delay.c gpio.c uart.c fifo.c | |||||
| SRCS+= adc-board.c delay-board.c gpio-board.c rtc-board.c lpm-board.c sx1276mb1las-board.c spi-board.c uart-board.c | SRCS+= adc-board.c delay-board.c gpio-board.c rtc-board.c lpm-board.c sx1276mb1las-board.c spi-board.c uart-board.c | ||||
| .endif | .endif | ||||
| # Generic STM32F103 Microcontroller | |||||
| .if ${MK_STM32F103} == "yes" | |||||
| ARMTARGET?= -mcpu=cortex-m3 -mthumb | |||||
| .PATH: $(STM32)/f103c8t6 | |||||
| LINKER_SCRIPT=$(STM32)/f103c8t6/STM32F103C8T6_FLASH.ld | |||||
| SRCS+= \ | |||||
| startup_stm32f103xb.s \ | |||||
| stm32f1xx_hal.c \ | |||||
| stm32f1xx_hal_cortex.c \ | |||||
| stm32f1xx_hal_gpio.c \ | |||||
| stm32f1xx_hal_pcd.c \ | |||||
| stm32f1xx_hal_pcd_ex.c \ | |||||
| stm32f1xx_ll_usb.c \ | |||||
| system_stm32f1xx.c | |||||
| CFLAGS+= -I$(STM32) | |||||
| CFLAGS+= -I$(STM32)/f103c8t6 | |||||
| CFLAGS+= -DSTM32F103xB | |||||
| .endif | |||||
| # NODE151 Microcontroller | # NODE151 Microcontroller | ||||
| .if ${MK_NODE151} == "yes" | .if ${MK_NODE151} == "yes" | ||||
| ARMTARGET?= -mcpu=cortex-m3 -mthumb | ARMTARGET?= -mcpu=cortex-m3 -mthumb | ||||
| STM32=$(.CURDIR)/stm32 | |||||
| .PATH: $(STM32)/l151ccux | .PATH: $(STM32)/l151ccux | ||||
| LINKER_SCRIPT=$(STM32)/l151ccux/STM32L151CCUX_FLASH.ld | LINKER_SCRIPT=$(STM32)/l151ccux/STM32L151CCUX_FLASH.ld | ||||
| SRCS+= \ | SRCS+= \ | ||||
| startup_stm32l151ccux.s \ | startup_stm32l151ccux.s \ | ||||
| stm32l1xx_hal.c \ | stm32l1xx_hal.c \ | ||||
| @@ -3,10 +3,12 @@ | |||||
| # | # | ||||
| # See bsd.mkopt.mk for more information. | # See bsd.mkopt.mk for more information. | ||||
| __DEFAULT_YES_OPTIONS = STROBE | |||||
| __DEFAULT_YES_OPTIONS = STROBE \ | |||||
| SYSINIT | |||||
| __DEFAULT_NO_OPTIONS = \ | __DEFAULT_NO_OPTIONS = \ | ||||
| NODE151 \ | NODE151 \ | ||||
| STM32F103 \ | |||||
| SX1276 \ | SX1276 \ | ||||
| USB_CDC | USB_CDC | ||||
| @@ -0,0 +1,39 @@ | |||||
| # Copyright 2022 John-Mark Gurney. | |||||
| # | |||||
| # Redistribution and use in source and binary forms, with or without | |||||
| # modification, are permitted provided that the following conditions | |||||
| # are met: | |||||
| # 1. Redistributions of source code must retain the above copyright | |||||
| # notice, this list of conditions and the following disclaimer. | |||||
| # 2. Redistributions in binary form must reproduce the above copyright | |||||
| # notice, this list of conditions and the following disclaimer in the | |||||
| # documentation and/or other materials provided with the distribution. | |||||
| # | |||||
| # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
| # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
| # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| # SUCH DAMAGE. | |||||
| # | |||||
| PROGS = rs485gw # lora.irr | |||||
| SRCS.rs485gw = rs485gw.c | |||||
| SRCS.rs485gw+= misc.c | |||||
| .PATH: $(.CURDIR)/.. | |||||
| CFLAGS += -I$(.CURDIR)/.. | |||||
| WITH_STM32F103 = yes | |||||
| WITH_USB_CDC = yes | |||||
| .include <../mk/boards.mk> | |||||
| .include <../mk/mu.progs.mk> | |||||
| @@ -0,0 +1,346 @@ | |||||
| /*- | |||||
| * Copyright 2022 John-Mark Gurney. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * | |||||
| */ | |||||
| #include <usbd_cdc_if.h> | |||||
| #include <misc.h> | |||||
| #include <stdbool.h> | |||||
| #include <stdint.h> | |||||
| #include <string.h> | |||||
| #include <sysinit.h> | |||||
| SYSINIT(hal_init, SI_SUB_HAL, SI_ORDER_FIRST, (void (*)(const void *))HAL_Init, NULL); | |||||
| void | |||||
| clkenable(const void *none) | |||||
| { | |||||
| GPIO_InitTypeDef GPIO_InitStruct; | |||||
| __HAL_RCC_GPIOB_CLK_ENABLE(); | |||||
| __HAL_RCC_GPIOC_CLK_ENABLE(); | |||||
| GPIO_InitStruct = (GPIO_InitTypeDef){ | |||||
| .Pin = GPIO_PIN_13, | |||||
| .Mode = GPIO_MODE_OUTPUT_PP, | |||||
| .Pull = GPIO_NOPULL, | |||||
| .Speed = GPIO_SPEED_FREQ_LOW, | |||||
| }; | |||||
| HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); | |||||
| HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); | |||||
| } | |||||
| SYSINIT(clkenable, SI_SUB_HAL, SI_ORDER_SECOND, clkenable, NULL); | |||||
| void | |||||
| oscconfig(const void *none) | |||||
| { | |||||
| RCC_ClkInitTypeDef clkinitstruct; | |||||
| RCC_OscInitTypeDef oscinitstruct; | |||||
| RCC_PeriphCLKInitTypeDef rccperiphclkinit; | |||||
| __HAL_RCC_PWR_CLK_ENABLE(); | |||||
| oscinitstruct = (RCC_OscInitTypeDef){ | |||||
| .OscillatorType = RCC_OSCILLATORTYPE_HSE, | |||||
| .HSEState = RCC_HSE_ON, | |||||
| .HSEPredivValue = RCC_HSE_PREDIV_DIV1, | |||||
| .PLL.PLLMUL = RCC_PLL_MUL9, | |||||
| .PLL.PLLState = RCC_PLL_ON, | |||||
| .PLL.PLLSource = RCC_PLLSOURCE_HSE, | |||||
| }; | |||||
| HAL_RCC_OscConfig(&oscinitstruct); | |||||
| /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 | |||||
| * clocks dividers */ | |||||
| clkinitstruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | | |||||
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; | |||||
| clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; | |||||
| clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1; | |||||
| clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; | |||||
| clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1; | |||||
| HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); | |||||
| /* USB clock selection */ | |||||
| rccperiphclkinit = (RCC_PeriphCLKInitTypeDef){ | |||||
| .PeriphClockSelection = RCC_PERIPHCLK_USB, | |||||
| .UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5, | |||||
| }; | |||||
| HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit); | |||||
| /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 | |||||
| clocks dividers */ | |||||
| clkinitstruct = (RCC_ClkInitTypeDef){ | |||||
| .ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2), | |||||
| .SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK, | |||||
| .AHBCLKDivider = RCC_SYSCLK_DIV1, | |||||
| .APB1CLKDivider = RCC_HCLK_DIV2, | |||||
| .APB2CLKDivider = RCC_HCLK_DIV1, | |||||
| }; | |||||
| HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2); | |||||
| } | |||||
| SYSINIT(oscconfig, SI_SUB_HAL, SI_ORDER_THIRD, oscconfig, NULL); | |||||
| char * | |||||
| findeol(char *pos, size_t len) | |||||
| { | |||||
| while (len) { | |||||
| if (*pos == '\r' || *pos == '\n') | |||||
| return pos; | |||||
| pos++; | |||||
| len--; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| void | |||||
| hexdump(const uint8_t *ptr, size_t len) | |||||
| { | |||||
| int i; | |||||
| for (i = 0; i < len; i++) | |||||
| usb_printf("%02x", ptr[i]); | |||||
| } | |||||
| void | |||||
| txdone(void) | |||||
| { | |||||
| usb_printf("txdone\r\n"); | |||||
| //Radio.Rx(0); | |||||
| } | |||||
| void | |||||
| txtimeout(void) | |||||
| { | |||||
| usb_printf("txtimeout\r\n"); | |||||
| } | |||||
| void | |||||
| rxdone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) | |||||
| { | |||||
| usb_printf("rxdone: size: %hu, rssi: %hd, snr: %d\r\ndata: ", size, rssi, snr); | |||||
| hexdump(payload, size); | |||||
| usb_printf("\r\n"); | |||||
| } | |||||
| void | |||||
| rxtimeout(void) | |||||
| { | |||||
| usb_printf("rxtimeout\r\n"); | |||||
| } | |||||
| void | |||||
| rxerr(void) | |||||
| { | |||||
| usb_printf("rxerr\r\n"); | |||||
| } | |||||
| static uint8_t | |||||
| hexchartonib(char s) | |||||
| { | |||||
| switch (s) { | |||||
| case '0'...'9': | |||||
| return s - '0'; | |||||
| case 'a'...'f': | |||||
| return s - 'a' + 10; | |||||
| case 'A'...'F': | |||||
| return s - 'A' + 10; | |||||
| default: | |||||
| return -1; | |||||
| } | |||||
| } | |||||
| static bool | |||||
| hexdecode(char *buf, size_t len, uint8_t *out) | |||||
| { | |||||
| uint8_t topchr, botchr; | |||||
| if (len % 2) | |||||
| return false; | |||||
| /* NB: only needed to silence a bad gcc warning */ | |||||
| topchr = -1; | |||||
| while (len) { | |||||
| if (len % 2) { | |||||
| /* bottom nibble */ | |||||
| botchr = hexchartonib(*buf); | |||||
| if (topchr == -1 || botchr == -1) | |||||
| return false; | |||||
| *out = topchr << 4 | botchr; | |||||
| out++; | |||||
| } else { | |||||
| /* top nibble */ | |||||
| topchr = hexchartonib(*buf); | |||||
| } | |||||
| len--; | |||||
| buf++; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| static const char pktstart[] = "pkt:"; | |||||
| static const size_t pktstartlen = sizeof pktstart - 1; | |||||
| static uint8_t pktbuf[128]; | |||||
| static void | |||||
| process_line(char *start, char *end) | |||||
| { | |||||
| size_t len; | |||||
| /* trim off leading CR/NL */ | |||||
| while (start < end && (*start == '\r' || *start == '\n')) | |||||
| start++; | |||||
| len = end - start; | |||||
| if (len >= pktstartlen && memcmp(start, pktstart, sizeof pktstart - 1) == 0) { | |||||
| start += pktstartlen; | |||||
| len -= pktstartlen; | |||||
| if (len % 2) { | |||||
| usb_printf("invalid pkt len\r\n"); | |||||
| return; | |||||
| } | |||||
| if (!hexdecode(start, len, pktbuf)) { | |||||
| usb_printf("invalid pkt\r\n"); | |||||
| return; | |||||
| } | |||||
| //Radio.Send(pktbuf, len / 2); | |||||
| return; | |||||
| } | |||||
| usb_printf("line: %.*s", end - start, start); | |||||
| fflush(vcp_usb); | |||||
| } | |||||
| int | |||||
| main(void) | |||||
| { | |||||
| //debug_printf("starting...\n"); | |||||
| //clkenable(NULL); | |||||
| sysinit_run(); | |||||
| //Radio.Init(&revents); | |||||
| setlinebuf(vcp_usb); | |||||
| #if 1 | |||||
| wait_for_vcp(); | |||||
| /* | |||||
| * This is required to use w/ FreeBSD. This is an issue w/ the | |||||
| * STM32 Core USB library: | |||||
| * https://github.com/STMicroelectronics/STM32CubeL1/issues/10 | |||||
| */ | |||||
| HAL_Delay(50); | |||||
| usb_printf("starting...\r\n"); | |||||
| #endif | |||||
| uint32_t v; | |||||
| char inpbuf[1024]; | |||||
| char *lastcheck; | |||||
| char *endchr; | |||||
| int inpbufpos = 0; | |||||
| int cpylen; | |||||
| loop: | |||||
| //BoardLowPowerHandler(); | |||||
| /* while we have data */ | |||||
| while (CDC_RX_LEN) { | |||||
| /* store last position */ | |||||
| lastcheck = &inpbuf[inpbufpos]; | |||||
| /* calculate how much space left */ | |||||
| cpylen = MIN(sizeof inpbuf - inpbufpos, CDC_RX_LEN); | |||||
| /* copy into buffer */ | |||||
| memcpy(&inpbuf[inpbufpos], CDC_RX_BUFFER, cpylen); | |||||
| /* and point to end of buffer */ | |||||
| inpbufpos += cpylen; | |||||
| do { | |||||
| /* find first end of line characters */ | |||||
| endchr = findeol(lastcheck, cpylen); | |||||
| if (endchr != NULL) { | |||||
| /* if so, process it */ | |||||
| process_line(inpbuf, endchr); | |||||
| /* skip end of line char */ | |||||
| endchr++; | |||||
| /* move remaining buffer to the beginning */ | |||||
| memmove(inpbuf, endchr, inpbufpos - (endchr - inpbuf)); | |||||
| /* and store new length */ | |||||
| inpbufpos = inpbufpos - (endchr - inpbuf); | |||||
| /* mark begining of stream as last checked */ | |||||
| lastcheck = inpbuf; | |||||
| /* and try to process another line */ | |||||
| continue; | |||||
| } else if (inpbufpos == sizeof inpbuf) { | |||||
| /* we overflowed the buffer */ | |||||
| /* XXX - best way is to throw away this line */ | |||||
| inpbufpos = 0; | |||||
| } | |||||
| } while (0); | |||||
| /* if we copied all the data */ | |||||
| if (cpylen == CDC_RX_LEN) { | |||||
| /* declare that we are ready to receive more data */ | |||||
| CDC_RX_LEN = 0; | |||||
| USBD_CDC_ReceivePacket(&hUsbDeviceFS); | |||||
| } else { | |||||
| /* if not, move the remaining to the begining and try again */ | |||||
| memmove(CDC_RX_BUFFER, &CDC_RX_BUFFER[cpylen], CDC_RX_LEN - cpylen); | |||||
| CDC_RX_LEN -= cpylen; | |||||
| } | |||||
| } | |||||
| goto loop; | |||||
| } | |||||
| @@ -0,0 +1,120 @@ | |||||
| /*- | |||||
| * Copyright 2022 John-Mark Gurney. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * | |||||
| */ | |||||
| #include <stdbool.h> | |||||
| #include <stdint.h> | |||||
| #include <stdlib.h> | |||||
| #include <sysinit.h> | |||||
| SET_DECLARE(sysinit_set, struct sysinit); | |||||
| void | |||||
| sysinit_run(void) | |||||
| { | |||||
| const int cnt = SET_COUNT(sysinit_set); | |||||
| uint16_t *idxarray = alloca(sizeof(uint16_t) * cnt); | |||||
| #if defined(VERBOSE_SYSINIT) | |||||
| uint16_t last; | |||||
| bool verbose; | |||||
| #endif | |||||
| int i; | |||||
| for (i = 0; i < cnt; i++) | |||||
| idxarray[i] = i; | |||||
| /* | |||||
| * following mostly copied from FreeBSD sys/kern/init_main.c | |||||
| * which has license: | |||||
| * SPDX-License-Identifier: BSD-4-Clause | |||||
| * | |||||
| * Copyright (c) 1995 Terrence R. Lambert | |||||
| * All rights reserved. | |||||
| * | |||||
| * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 | |||||
| * The Regents of the University of California. All rights reserved. | |||||
| * (c) UNIX System Laboratories, Inc. | |||||
| * | |||||
| * as copying this to RAM might be expensive, use a stack | |||||
| * allocated indirection array to do the sorting instead. | |||||
| */ | |||||
| uint16_t *sipp; | |||||
| uint16_t *xipp; | |||||
| uint16_t save; | |||||
| /* | |||||
| * Perform a bubble sort of the system initialization objects by | |||||
| * their subsystem (primary key) and order (secondary key). | |||||
| */ | |||||
| #define GI(x) (SET_BEGIN(sysinit_set)[(x)]) | |||||
| #define GI_SUBSYSORDER(x) (GI((x))->si_subsys_order) | |||||
| #define GI_SUBSYS(x) (GET_SUBSYS(GI_SUBSYSORDER(x))) | |||||
| #define GI_ORDER(x) (GET_ORDER(GI_SUBSYSORDER(x))) | |||||
| for (sipp = &idxarray[0]; sipp < &idxarray[cnt]; sipp++) { | |||||
| for (xipp = sipp + 1; xipp < &idxarray[cnt]; xipp++) { | |||||
| if (GI_SUBSYS(*sipp) < GI_SUBSYS(*xipp) || | |||||
| (GI_SUBSYS(*sipp) == GI_SUBSYS(*xipp) && | |||||
| GI_ORDER(*sipp) <= GI_ORDER(*xipp))) | |||||
| continue; /* skip*/ | |||||
| save = *sipp; | |||||
| *sipp = *xipp; | |||||
| *xipp = save; | |||||
| } | |||||
| } | |||||
| #if defined(VERBOSE_SYSINIT) | |||||
| last = SI_SUB_COPYRIGHT; | |||||
| verbose = 0; | |||||
| #endif | |||||
| /* | |||||
| * Traverse the (now) ordered list of system initialization tasks. | |||||
| * Perform each task, and continue on to the next task. | |||||
| */ | |||||
| for (sipp = &idxarray[0]; sipp < &idxarray[cnt]; sipp++) { | |||||
| if (GI_SUBSYS(*sipp) == SI_SUB_DUMMY) | |||||
| continue; /* skip dummy task(s)*/ | |||||
| #if defined(VERBOSE_SYSINIT) | |||||
| if (GI_SUBSYS(*sipp) > last && verbose_sysinit != 0) { | |||||
| verbose = 1; | |||||
| last = GI_SUBSYS(*sipp); | |||||
| printf("subsystem %x\n", last); | |||||
| } | |||||
| if (verbose) { | |||||
| printf(" %p(%p)... ", GI(*sipp)->func, | |||||
| GI(*sipp)->udata); | |||||
| } | |||||
| #endif | |||||
| /* Call function */ | |||||
| (GI(*sipp)->si_func)(GI(*sipp)->si_udata); | |||||
| #if defined(VERBOSE_SYSINIT) | |||||
| if (verbose) | |||||
| printf("done.\n"); | |||||
| #endif | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,115 @@ | |||||
| /*- | |||||
| * SPDX-License-Identifier: BSD-4-Clause | |||||
| * | |||||
| * Copyright (c) 1995 Terrence R. Lambert | |||||
| * Copyright 2022 John-Mark Gurney | |||||
| * All rights reserved. | |||||
| * | |||||
| * Copyright (c) 1990, 1993 | |||||
| * The Regents of the University of California. All rights reserved. | |||||
| * (c) UNIX System Laboratories, Inc. | |||||
| * All or some portions of this file are derived from material licensed | |||||
| * to the University of California by American Telephone and Telegraph | |||||
| * Co. or Unix System Laboratories, Inc. and are reproduced herein with | |||||
| * the permission of UNIX System Laboratories, Inc. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * 3. All advertising materials mentioning features or use of this software | |||||
| * must display the following acknowledgement: | |||||
| * This product includes software developed by the University of | |||||
| * California, Berkeley and its contributors. | |||||
| * 4. Neither the name of the University nor the names of its contributors | |||||
| * may be used to endorse or promote products derived from this software | |||||
| * without specific prior written permission. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * | |||||
| * @(#)kernel.h 8.3 (Berkeley) 1/21/94 | |||||
| * $FreeBSD$ | |||||
| */ | |||||
| /* | |||||
| * This system is similar to FreeBSD's SYSINIT(9), but w/ minor | |||||
| * modifications. | |||||
| */ | |||||
| #ifndef _SYSINIT_H_ | |||||
| #define _SYSINIT_H_ 1 | |||||
| #include <linker_set.h> | |||||
| /* from FreeBSD sys/systm.h */ | |||||
| #define CTASSERT(x) _Static_assert(x, "compile-time assertion failed") | |||||
| #define MAKE_SUBORDER(subsys, order) ((uint32_t)((subsys) << 16) | (order)) | |||||
| #define GET_SUBSYS(x) (((x) >> 16) & 0xffff) | |||||
| #define GET_ORDER(x) ((x) & 0xffff) | |||||
| enum sysinit_sub_id { | |||||
| SI_SUB_DUMMY = 0x0000, /* not executed; for linker*/ | |||||
| SI_SUB_HAL = 0x0010, /* Early HAL init */ | |||||
| SI_SUB_GPIO = 0x0030, /* Early GPIO */ | |||||
| SI_SUB_CONSOLE = 0x0700, /* Setup console/debug prints */ | |||||
| SI_SUB_COPYRIGHT = 0x0800, /* start of when printf works */ | |||||
| SI_SUB_STANDARD = 0x8000, /* standard later initalization */ | |||||
| SI_SUB_LAST = 0xffff /* final initialization */ | |||||
| }; | |||||
| /* | |||||
| * Some enumerated orders; "ANY" sorts last. | |||||
| */ | |||||
| enum sysinit_elem_order { | |||||
| SI_ORDER_FIRST = 0x0000, /* first*/ | |||||
| SI_ORDER_SECOND = 0x0001, /* second*/ | |||||
| SI_ORDER_THIRD = 0x0002, /* third*/ | |||||
| SI_ORDER_FOURTH = 0x0003, /* fourth*/ | |||||
| SI_ORDER_FIFTH = 0x0004, /* fifth*/ | |||||
| SI_ORDER_SIXTH = 0x0005, /* sixth*/ | |||||
| SI_ORDER_SEVENTH = 0x0006, /* seventh*/ | |||||
| SI_ORDER_EIGHTH = 0x0007, /* eighth*/ | |||||
| SI_ORDER_MIDDLE = 0x1000, /* somewhere in the middle */ | |||||
| SI_ORDER_ANY = 0xffff /* last*/ | |||||
| }; | |||||
| typedef void (*sysinit_cfunc_t)(const void *); | |||||
| struct sysinit { | |||||
| uint32_t si_subsys_order; | |||||
| sysinit_cfunc_t si_func; | |||||
| const void *si_udata; | |||||
| }; | |||||
| #define SYSINIT(uniquifier, subsystem, order, func, udata) \ | |||||
| CTASSERT((subsystem & 0xffff) == subsystem); \ | |||||
| CTASSERT((order & 0xffff) == order); \ | |||||
| static struct sysinit uniquifier ## _sys_init = { \ | |||||
| .si_subsys_order = MAKE_SUBORDER((subsystem), (order)), \ | |||||
| .si_func = (func), \ | |||||
| .si_udata = (udata), \ | |||||
| }; \ | |||||
| DATA_SET(sysinit_set,uniquifier ## _sys_init) | |||||
| void sysinit_run(void); | |||||
| #endif /* _SYSINIT_H_ */ | |||||