1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:12:57 +01:00
19076: boards/hip-badge: add HiP Badge board definition r=maribu a=benpicco



Co-authored-by: Benjamin Valentin <benpicco@beuth-hochschule.de>
This commit is contained in:
bors[bot] 2023-01-09 13:33:40 +00:00 committed by GitHub
commit e2538a898a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 536 additions and 14 deletions

21
boards/hip-badge/Kconfig Normal file
View File

@ -0,0 +1,21 @@
# Copyright (c) 2023 Benjamin Valentin
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
config BOARD
default "hip-badge" if BOARD_HIP_BADGE
config BOARD_HIP_BADGE
bool
default y
select BOARD_COMMON_ESP32C3
select CPU_MODEL_ESP32C3
select HAS_ESP_JTAG
select HAS_PERIPH_I2C
select HAVE_SAUL_GPIO
select HAVE_SGP30
source "$(RIOTBOARD)/common/esp32c3/Kconfig"

View File

@ -0,0 +1,5 @@
MODULE = board
DIRS = $(RIOTBOARD)/common/esp32c3
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,9 @@
ifeq (,$(filter stdio_% slipdev_stdio,$(USEMODULE)))
USEMODULE += stdio_usb_serial_jtag
endif
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += sgp30
endif
include $(RIOTBOARD)/common/esp32c3/Makefile.dep

View File

@ -0,0 +1,10 @@
CPU_MODEL = esp32c3
# common board and CPU features
include $(RIOTBOARD)/common/esp32c3/Makefile.features
# additional features provided by the board
FEATURES_PROVIDED += periph_i2c
# unique features provided by the board
FEATURES_PROVIDED += esp_jtag

View File

@ -0,0 +1,3 @@
PORT_LINUX ?= /dev/ttyACM0
include $(RIOTBOARD)/common/esp32c3/Makefile.include

62
boards/hip-badge/doc.txt Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup boards_hip_badge HiP Badge
* @ingroup boards_esp32c3
* @brief Support for the Hacking in Parallel Badge
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*/
The HiP Badge is a board that was given to participants of the 2022 *Hacking in Parallel* event.
![Image of the HiP badge with custom frame and SAO (I2C) expander](https://camo.githubusercontent.com/834dbee4ed9a9a90480bd1a239e54718f3a9613b694d0a2e26a3b25e55ce2d82/68747470733a2f2f6d61747269782d636c69656e742e6d61747269782e6f72672f5f6d61747269782f6d656469612f72302f646f776e6c6f61642f6d6f6e65726f2e736f6369616c2f757351777a4f656957516e6671546247416845734b684a76)
# Features
- ESP32-C3FH4AZ SoC
- I2C via SAO headers
- UART via pin headers
- 16 WS2812B LEDs
- USB-C Serial/JTAG
- 3 User button / 1 Reset button
- ST25DV04K NFC/I2C EEPROM (TODO: driver)
# Flashing the device
The device can be programmed using the USB-C Serial/JTAG feature.
Just plug in a cable to your computer and flash the device with
make BOARD=hip-badge flash
This should automatically reset the ESP32C3 into bootloader mode and start the download process.
If for some reason this gets stuck or the badge does not register as a /dev/ttyACMx device, you
can manually force it into bootloader mode by pressing the reset button (SW3/blue) while holding
the BOOT button (SW4).
When doing this, the device will still be in bootloader mode after flashing, you have to press
the reset button (SW3/blue) again to start your application.
There is currently still a bug in the USB Serial stdio implementation: After flashing or a reboot,
there is no output. Do a manual reset (press the reset button) to restore output.
# Bugs
The event (and badge) were organized on short notice (6 Weeks), so there are some hardware issues:
- No WiFi/BLE antenna. There is a pad on the back of the PCB where a socket was supposed to be, but
nothing is connected. You can try solder something onto it yourself, but the trace is already long
and winded.
BLE works with the existing trace alone (on short range), WiFi/ESP Now does not.
- IR transceiver broken. Can be fixed with a steady hand?
- SGP30 air quality sensor is only populated on some boards (red case)
- MAX17048 fuel gauge not populated
# Resources
- [Badge Clinic](https://wiki.hip-berlin.de/index.php?title=Badge_Clinic)
- [Design files](https://gitlab.com/tidklaas/hip-badge/)

View File

@ -0,0 +1 @@
CONFIG_MODULE_STDIO_USB_SERIAL_JTAG=y

View File

@ -0,0 +1,117 @@
/*
* Copyright (C) 2023 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup boards_hip_badge
* @brief Board definitions for the HiP Badge
* @{
*
* @file
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*/
#ifndef BOARD_H
#define BOARD_H
#include <stdint.h>
/**
* @name Button pin definitions
* @{
*/
/**
* @brief Tact A GPIO pin definition
*/
#define BTN0_PIN GPIO2
/**
* @brief button GPIO mode definition
*
* Since the GPIO of the button is pulled up with an external resistor, the
* mode for the GPIO pin has to be GPIO_IN.
*/
#define BTN0_MODE GPIO_IN
/**
* @brief Default interrupt flank definition for the button GPIO
*/
#ifndef BTN0_INT_FLANK
#define BTN0_INT_FLANK GPIO_FALLING
#endif
/**
* @brief Tact B GPIO pin definition
*/
#define BTN1_PIN GPIO8
/**
* @brief Default button GPIO mode definition
*
* Since the GPIO of the button is pulled up with an external resistor, the
* mode for the GPIO pin has to be GPIO_IN.
*/
#define BTN1_MODE GPIO_IN
/**
* @brief Default interrupt flank definition for the button GPIO
*/
#ifndef BTN1_INT_FLANK
#define BTN1_INT_FLANK GPIO_FALLING
#endif
/**
* @brief BOOT button GPIO pin definition
*
* The HiP-Badge has a BOOT button connected to GPIO9, which can be
* used as button during normal operation. Since the GPIO9 pin is pulled up,
* the button signal is inverted, i.e., pressing the button will give a
* low signal.
*/
#define BTN2_PIN GPIO9
/**
* @brief Default button GPIO mode definition
*/
#define BTN2_MODE GPIO_IN_PU
/**
* @brief Default interrupt flank definition for the button GPIO
*/
#ifndef BTN2_INT_FLANK
#define BTN2_INT_FLANK GPIO_FALLING
#endif
/** @} */
/**
* @brief WS281x LEDs are connected to GPIO10
*/
#ifndef WS281X_PARAM_PIN
#define WS281X_PARAM_PIN GPIO10
#endif
/**
* @brief There are 16 WS281x LEDs
*/
#ifndef WS281X_PARAM_NUMOF
#define WS281X_PARAM_NUMOF 16
#endif
/* include common board definitions as last step */
#include "board_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* BOARD_H */
/** @} */

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2023 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup boards_hip_badge
* @brief Board specific configuration of direct mapped GPIOs
* @file
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
* @{
*/
#ifndef GPIO_PARAMS_H
#define GPIO_PARAMS_H
#include "board.h"
#include "saul/periph.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief LED and Button configuration
*/
static const saul_gpio_params_t saul_gpio_params[] =
{
{
.name = "SW1",
.pin = BTN0_PIN,
.mode = BTN0_MODE,
.flags = SAUL_GPIO_INVERTED
},
{
.name = "SW2",
.pin = BTN1_PIN,
.mode = BTN1_MODE,
.flags = SAUL_GPIO_INVERTED
},
{
.name = "Boot",
.pin = BTN2_PIN,
.mode = BTN2_MODE,
.flags = SAUL_GPIO_INVERTED
},
};
#ifdef __cplusplus
}
#endif
#endif /* GPIO_PARAMS_H */
/** @} */

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2023 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup boards_hip_badge
* @brief Peripheral configurations for the HiP Badge
* @{
*
* @file
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*/
#ifndef PERIPH_CONF_H
#define PERIPH_CONF_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name I2C configuration
*
* One I2C interface I2C_DEV(0) is defined and available via the SAO headers.
*
* The GPIOs listed in the configuration are only initialized as I2C signals
* when module `periph_i2c` is used. Otherwise they are not allocated and
* can be used for other purposes.
*
* @{
*/
#ifndef I2C0_SPEED
#define I2C0_SPEED I2C_SPEED_FAST /**< I2C bus speed of I2C_DEV(0) */
#endif
#ifndef I2C0_SCL
#define I2C0_SCL GPIO6 /**< SCL signal of I2C_DEV(0) */
#endif
#ifndef I2C0_SDA
#define I2C0_SDA GPIO5 /**< SDA signal of I2C_DEV(0) */
#endif
/** @} */
/**
* @name UART configuration
*
* ESP32-C3 provides 2 UART interfaces at maximum:
*
* UART_DEV(0) uses fixed standard configuration.<br>
* UART_DEV(1) is used for IrDA (untested).<br>
*
* @{
*/
#define UART0_TXD GPIO21 /**< direct I/O pin for UART_DEV(0) TxD, can't be changed */
#define UART0_RXD GPIO20 /**< direct I/O pin for UART_DEV(0) RxD, can't be changed */
#define UART1_TXD GPIO7 /**< IrDA TX - Bad Choice? */
#define UART1_RXD GPIO3 /**< IrDA RX - Bad Choice? */
/** @} */
#ifdef __cplusplus
} /* end extern "C" */
#endif
/* include common peripheral definitions as last step */
#include "periph_conf_common.h"
#endif /* PERIPH_CONF_H */
/** @} */

View File

@ -25,6 +25,10 @@ ifneq (, $(filter esp_freertos, $(USEMODULE)))
DIRS += freertos
endif
ifneq (, $(filter stdio_usb_serial_jtag, $(USEMODULE)))
DIRS += stdio_usb_serial_jtag
endif
ifneq (,$(filter esp_wifi% esp_eth, $(USEMODULE)))
SRC += esp_ztimer.c
endif

View File

@ -166,6 +166,17 @@ ifneq (,$(filter shell,$(USEMODULE)))
USEMODULE += ps
endif
ifneq (,$(filter stdio_usb_serial_jtag, $(USEMODULE)))
USEMODULE += tsrb
ifneq (,$(filter stdin,$(USEMODULE)))
USEMODULE += stdio_usb_serial_jtag_rx
endif
endif
ifneq (,$(filter stdio_usb_serial_jtag_rx, $(USEMODULE)))
USEMODULE += isrpipe
USEMODULE += stdio_available
endif
ifneq (,$(filter tinyusb_portable_espressif,$(USEMODULE)))
USEMODULE += esp_idf_usb
endif

View File

@ -50,6 +50,7 @@ PSEUDOMODULES += esp_rtc_timer_32k
PSEUDOMODULES += esp_spi_ram
PSEUDOMODULES += esp_spi_oct
PSEUDOMODULES += esp_wifi_enterprise
PSEUDOMODULES += stdio_usb_serial_jtag_rx
INCLUDES += -I$(RIOTCPU)/$(CPU)/esp-idf/include
INCLUDES += -I$(RIOTCPU)/$(CPU)/esp-idf/include/log

View File

@ -36,20 +36,21 @@ extern "C" {
*
* @{
*/
#define CPU_INUM_GPIO 2 /**< Level interrupt with low priority 1 */
#define CPU_INUM_CAN 3 /**< Level interrupt with low priority 1 */
#define CPU_INUM_UART 4 /**< Level interrupt with low priority 1 */
#define CPU_INUM_USB 8 /**< Level interrupt with low priority 1 */
#define CPU_INUM_RTT 9 /**< Level interrupt with low priority 1 */
#define CPU_INUM_I2C 12 /**< Level interrupt with low priority 1 */
#define CPU_INUM_WDT 13 /**< Level interrupt with low priority 1 */
#define CPU_INUM_SOFTWARE 17 /**< Level interrupt with low priority 1 */
#define CPU_INUM_ETH 18 /**< Level interrupt with low priority 1 */
#define CPU_INUM_TIMER 19 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_FRC2 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_SYSTIMER 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_BLE 21 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_CACHEERR 25 /**< Level interrupt with high priority 4 */
#define CPU_INUM_GPIO 2 /**< Level interrupt with low priority 1 */
#define CPU_INUM_CAN 3 /**< Level interrupt with low priority 1 */
#define CPU_INUM_UART 4 /**< Level interrupt with low priority 1 */
#define CPU_INUM_USB 8 /**< Level interrupt with low priority 1 */
#define CPU_INUM_RTT 9 /**< Level interrupt with low priority 1 */
#define CPU_INUM_SERIAL_JTAG 10 /**< Level interrupt with low priority 1 */
#define CPU_INUM_I2C 12 /**< Level interrupt with low priority 1 */
#define CPU_INUM_WDT 13 /**< Level interrupt with low priority 1 */
#define CPU_INUM_SOFTWARE 17 /**< Level interrupt with low priority 1 */
#define CPU_INUM_ETH 18 /**< Level interrupt with low priority 1 */
#define CPU_INUM_TIMER 19 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_FRC2 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_SYSTIMER 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_BLE 21 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_CACHEERR 25 /**< Level interrupt with high priority 4 */
/** @} */
/**

View File

@ -83,6 +83,9 @@ static const struct intr_handle_data_t _irq_data_table[] = {
#if defined(CPU_FAM_ESP32S2) || defined(CPU_FAM_ESP32S3)
{ ETS_USB_INTR_SOURCE, CPU_INUM_USB, 1 },
#endif
#if defined(ETS_USB_SERIAL_JTAG_INTR_SOURCE)
{ ETS_USB_SERIAL_JTAG_INTR_SOURCE, CPU_INUM_SERIAL_JTAG, 1 },
#endif
};
#define IRQ_DATA_TABLE_SIZE ARRAY_SIZE(_irq_data_table)

View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,126 @@
/*
* Copyright (C) 2023 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup cpu_esp32_usb_serial_jtag ESP32 USB Serial/JTAG interface
* @ingroup cpu_esp32
* @{
*
* @file
* @brief stdio via USB Serial JTAG debug interface
*
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*/
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
#include <sys/types.h>
#include "isrpipe.h"
#include "tsrb.h"
#include "irq_arch.h"
#include "esp_attr.h"
#include "hal/interrupt_controller_types.h"
#include "hal/interrupt_controller_ll.h"
#include "hal/usb_serial_jtag_ll.h"
#include "soc/periph_defs.h"
#include "rom/ets_sys.h"
static uint8_t _rx_buf_mem[USB_SERIAL_JTAG_PACKET_SZ_BYTES];
static isrpipe_t stdio_serial_isrpipe = ISRPIPE_INIT(_rx_buf_mem);
static tsrb_t serial_tx_rb;
static uint8_t serial_tx_rb_buf[USB_SERIAL_JTAG_PACKET_SZ_BYTES];
#define IRQ_MASK (USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | \
(IS_USED(MODULE_STDIO_USB_SERIAL_JTAG_RX) * USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT))
ssize_t stdio_write(const void *buffer, size_t len)
{
tsrb_add(&serial_tx_rb, buffer, len);
USB_SERIAL_JTAG.int_ena.val = IRQ_MASK;
return len;
}
ssize_t stdio_read(void* buffer, size_t count)
{
if (IS_USED(MODULE_STDIO_USB_SERIAL_JTAG_RX)) {
return (ssize_t)isrpipe_read(&stdio_serial_isrpipe, buffer, count);
}
return -ENOTSUP;
}
int stdio_available(void)
{
if (IS_USED(MODULE_STDIO_AVAILABLE)) {
return tsrb_avail(&stdio_serial_isrpipe.tsrb);
}
return -ENOTSUP;
}
IRAM_ATTR
static void _serial_intr_handler(void *arg)
{
(void)arg;
irq_isr_enter();
uint32_t mask = usb_serial_jtag_ll_get_intsts_mask();
/* read data if available */
while (IS_USED(MODULE_STDIO_USB_SERIAL_JTAG_RX) &&
usb_serial_jtag_ll_rxfifo_data_available()) {
isrpipe_write_one(&stdio_serial_isrpipe, USB_SERIAL_JTAG.ep1.rdwr_byte);
}
/* write data if there is a free stop */
if (mask & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) {
while (usb_serial_jtag_ll_txfifo_writable()) {
int c = tsrb_get_one(&serial_tx_rb);
if (c < 0) {
/* no more data to send - disable interrupt */
USB_SERIAL_JTAG.int_ena.val = IRQ_MASK & ~USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY;
break;
}
USB_SERIAL_JTAG.ep1.rdwr_byte = c;
}
usb_serial_jtag_ll_txfifo_flush();
}
/* clear all interrupt flags */
usb_serial_jtag_ll_clr_intsts_mask(mask);
irq_isr_exit();
}
void stdio_init(void)
{
tsrb_init(&serial_tx_rb, serial_tx_rb_buf, sizeof(serial_tx_rb_buf));
/* enable RX interrupt */
if (IS_USED(MODULE_STDIO_USB_SERIAL_JTAG_RX)) {
USB_SERIAL_JTAG.int_ena.val = USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT;
}
/* clear all interrupt flags */
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
/* route all UART interrupt sources to same the CPU interrupt */
intr_matrix_set(PRO_CPU_NUM, ETS_USB_SERIAL_JTAG_INTR_SOURCE, CPU_INUM_SERIAL_JTAG);
/* we have to enable therefore the CPU interrupt here */
intr_cntrl_ll_set_int_handler(CPU_INUM_SERIAL_JTAG, _serial_intr_handler, NULL);
intr_cntrl_ll_enable_interrupts(BIT(CPU_INUM_SERIAL_JTAG));
}
/**@}*/

View File

@ -10,6 +10,7 @@ STDIO_MODULES = \
stdio_uart \
stdio_telnet \
stdio_tinyusb_cdc_acm \
stdio_usb_serial_jtag \
#
# select stdio_uart if no other stdio module is slected

View File

@ -49,6 +49,12 @@ config MODULE_STDIO_ETHOS
select MODULE_ETHOS_STDIO
select USE_STDOUT_BUFFERED
config MODULE_STDIO_USB_SERIAL_JTAG
bool "STDIO via ESP32 Debug USB Serial/JTAG interface"
depends on TEST_KCONFIG
depends on CPU_FAM_ESP32C3 || CPU_FAM_ESP32S3
select MODULE_TSRB
endchoice
config MODULE_STDIN
@ -63,6 +69,15 @@ config MODULE_STDIO_UART_RX
help
Reception when using UART-based STDIO needs to be enabled.
config MODULE_STDIO_USB_SERIAL_JTAG_RX
bool
depends on MODULE_STDIO_USB_SERIAL_JTAG
select MODULE_ISRPIPE
select MODULE_STDIO_AVAILABLE
default y if MODULE_STDIN
help
Reception when using ESP32 USB Serial/JTAG STDIO needs to be enabled.
config MODULE_STDIO_AVAILABLE
bool
help