mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-26 15:03:53 +01:00
Merge pull request #11108 from gschorcht/cpu/esp8266/esp-idf/pr
cpu/esp8266: complete reimplementation based on ESP8266 RTOS SDK
This commit is contained in:
commit
be39169bd4
@ -173,7 +173,7 @@ static const gpio_t pwm1_channels[] = PWM1_GPIOS;
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Static array with configuration for declared I2C devices
|
||||
* @brief Static array with configuration for declared SPI devices
|
||||
*/
|
||||
static const spi_conf_t spi_config[] = {
|
||||
#ifdef SPI0_CTRL
|
||||
@ -220,7 +220,7 @@ static const spi_conf_t spi_config[] = {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Static array with configuration for declared I2C devices
|
||||
* @brief Static array with configuration for declared UART devices
|
||||
*/
|
||||
static const uart_conf_t uart_config[] = {
|
||||
{
|
||||
@ -249,13 +249,7 @@ static const uart_conf_t uart_config[] = {
|
||||
*
|
||||
* @note UART_NUMOF definition must not be changed.
|
||||
*/
|
||||
#if defined(UART1_TXD) && defined(UART1_RXD) && defined(UART2_TXD) && defined(UART2_RXD)
|
||||
#define UART_NUMOF 3
|
||||
#elif (defined(UART1_TXD) && defined(UART1_RXD)) || (defined(UART2_TXD) && defined(UART2_RXD))
|
||||
#define UART_NUMOF 2
|
||||
#else
|
||||
#define UART_NUMOF 1
|
||||
#endif
|
||||
#define UART_NUMOF ARRAY_SIZE(uart_config)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -10,3 +10,4 @@ FEATURES_PROVIDED += periph_i2c
|
||||
FEATURES_PROVIDED += periph_pwm
|
||||
FEATURES_PROVIDED += periph_spi
|
||||
FEATURES_PROVIDED += periph_uart
|
||||
FEATURES_PROVIDED += periph_uart_modecfg
|
||||
|
||||
@ -4,5 +4,5 @@ PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.SLAB_USBtoUART*)))
|
||||
include $(RIOTMAKE)/tools/serial.inc.mk
|
||||
|
||||
# reset tool configuration
|
||||
RESET ?= esptool.py
|
||||
RESET_FLAGS ?= --port $(PROG_DEV) --before default_reset run
|
||||
RESET ?= $(RIOTTOOLS)/esptool/espreset.py
|
||||
RESET_FLAGS ?= --port $(PROG_DEV)
|
||||
|
||||
@ -16,9 +16,12 @@
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#include "board_common.h"
|
||||
#include "board.h"
|
||||
#include "esp_common.h"
|
||||
#include "log.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "esp_libc.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -40,35 +43,69 @@ void board_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void adc_print_config(void);
|
||||
extern void dac_print_config(void);
|
||||
extern void pwm_print_config(void);
|
||||
extern void i2c_print_config(void);
|
||||
extern void spi_print_config(void);
|
||||
extern void uart_print_config(void);
|
||||
extern void timer_print_config(void);
|
||||
extern void can_print_config(void);
|
||||
|
||||
void board_print_config (void)
|
||||
{
|
||||
LOG_INFO("\nBoard configuration:\n");
|
||||
ets_printf("\nBoard configuration:\n");
|
||||
|
||||
#if MODULE_PERIPH_ADC
|
||||
adc_print_config();
|
||||
#endif
|
||||
#if MODULE_PERIPH_DAC
|
||||
dac_print_config();
|
||||
#endif
|
||||
#if MODULE_PERIPH_PWM
|
||||
pwm_print_config();
|
||||
#endif
|
||||
#if MODULE_PERIPH_I2C
|
||||
i2c_print_config();
|
||||
#endif
|
||||
#if MODULE_PERIPH_SPI
|
||||
spi_print_config();
|
||||
#endif
|
||||
#if MODULE_PERIPH_UART
|
||||
uart_print_config();
|
||||
#endif
|
||||
#if MODULE_PERIPH_TIMER
|
||||
timer_print_config();
|
||||
#endif
|
||||
#ifdef MODULE_ESP_CAN
|
||||
can_print_config();
|
||||
#endif
|
||||
|
||||
LOG_INFO("\tLED: pins=[ ");
|
||||
ets_printf("\tLED\t\tpins=[ ");
|
||||
#ifdef LED0_PIN
|
||||
LOG_INFO("%d ", LED0_PIN);
|
||||
ets_printf("%d ", LED0_PIN);
|
||||
#endif
|
||||
#ifdef LED1_PIN
|
||||
LOG_INFO("%d ", LED1_PIN);
|
||||
ets_printf("%d ", LED1_PIN);
|
||||
#endif
|
||||
#ifdef LED2_PIN
|
||||
LOG_INFO("%d ", LED2_PIN);
|
||||
ets_printf("%d ", LED2_PIN);
|
||||
#endif
|
||||
LOG_INFO("]\n");
|
||||
ets_printf("]\n");
|
||||
|
||||
LOG_INFO("\n\n");
|
||||
ets_printf("\tBUTTON\t\tpins=[ ");
|
||||
#ifdef BUTTON0_PIN
|
||||
ets_printf("%d ", BUTTON0_PIN);
|
||||
#endif
|
||||
#ifdef BUTTON2_PIN
|
||||
ets_printf("%d ", BUTTON1_PIN);
|
||||
#endif
|
||||
#ifdef BUTTON3_PIN
|
||||
ets_printf("%d ", BUTTON2_PIN);
|
||||
#endif
|
||||
ets_printf("]\n");
|
||||
|
||||
ets_printf("\n");
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -17,6 +17,9 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* not required when compiling ESP vendor code parts */
|
||||
#ifndef ESP_PLATFORM
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cpu.h"
|
||||
@ -124,7 +127,7 @@ extern mtd_dev_t *mtd0;
|
||||
* initializations are done during the CPU initialization that is called from
|
||||
* boot loader.
|
||||
*/
|
||||
extern void board_init(void);
|
||||
void board_init (void);
|
||||
|
||||
/**
|
||||
* @brief Print the board configuration in a human readable format
|
||||
@ -140,4 +143,5 @@ void board_print_config (void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* ESP_PLATFORM */
|
||||
#endif /* BOARD_COMMON_H */
|
||||
|
||||
@ -53,13 +53,13 @@ extern "C" {
|
||||
#define ENC28J60_PARAM_SPI SPI_DEV(0) /**< SPI_DEV(0) is used (fixed) */
|
||||
|
||||
#ifndef ENC28J60_PARAM_CS
|
||||
#define ENC28J60_PARAM_CS GPIO4 /**< ENC28J60 CS signal (can be overriden) */
|
||||
#define ENC28J60_PARAM_CS GPIO4 /**< ENC28J60 CS signal (can be overridden) */
|
||||
#endif
|
||||
#ifndef ENC28J60_PARAM_INT
|
||||
#define ENC28J60_PARAM_INT GPIO9 /**< ENC28J60 INT signal (can be overriden) */
|
||||
#define ENC28J60_PARAM_INT GPIO9 /**< ENC28J60 INT signal (can be overridden) */
|
||||
#endif
|
||||
#ifndef ENC28J60_PARAM_RESET
|
||||
#define ENC28J60_PARAM_RESET GPIO10 /**< ENC28J60 RESET signal (can be overriden) */
|
||||
#define ENC28J60_PARAM_RESET GPIO10 /**< ENC28J60 RESET signal (can be overridden) */
|
||||
#endif
|
||||
/** @} */
|
||||
#endif /* defined(MODULE_ENC28J60) || defined(DOXYGEN) */
|
||||
@ -82,16 +82,16 @@ extern "C" {
|
||||
#define MRF24J40_PARAM_SPI SPI_DEV(0) /**< SPI_DEV(0) is used (fixed) */
|
||||
|
||||
#ifndef MRF24J40_PARAM_SPI_CLK
|
||||
#define MRF24J40_PARAM_SPI_CLK SPI_CLK_1MHZ /**< SPI bus speed used (can be overriden) */
|
||||
#define MRF24J40_PARAM_SPI_CLK SPI_CLK_1MHZ /**< SPI bus speed used (can be overridden) */
|
||||
#endif
|
||||
#ifndef MRF24J40_PARAM_CS
|
||||
#define MRF24J40_PARAM_CS GPIO16 /**< MRF24J40 CS signal (can be overriden) */
|
||||
#define MRF24J40_PARAM_CS GPIO16 /**< MRF24J40 CS signal (can be overridden) */
|
||||
#endif
|
||||
#ifndef MRF24J40_PARAM_INT
|
||||
#define MRF24J40_PARAM_INT GPIO0 /**< MRF24J40 INT signal (can be overriden) */
|
||||
#define MRF24J40_PARAM_INT GPIO0 /**< MRF24J40 INT signal (can be overridden) */
|
||||
#endif
|
||||
#ifndef MRF24J40_PARAM_RESET
|
||||
#define MRF24J40_PARAM_RESET GPIO2 /**< MRF24J40 RESET signal (can be overriden) */
|
||||
#define MRF24J40_PARAM_RESET GPIO2 /**< MRF24J40 RESET signal (can be overridden) */
|
||||
#endif
|
||||
/** @} */
|
||||
#endif /* defined(MODULE_MRF24J40) || defined(DOXYGEN) */
|
||||
@ -109,14 +109,14 @@ extern "C" {
|
||||
* If not defined, the default CS signal of SPI_DEV(0) is used.
|
||||
* @{
|
||||
*/
|
||||
#define SDCARD_SPI_PARAM_SPI SPI_DEV(0) /**< SPI_DEV(0) is used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_CLK SPI0_SCK_GPIO /**< SPI_DEV(0) SCK is used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_MOSI SPI0_MOSI_GPIO /**< SPI_DEV(0) MOSI is used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_MISO SPI0_MISO_GPIO /**< SPI_DEV(0) MISO is used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_POWER GPIO_UNDEF /**< power control is not used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_SPI SPI_DEV(0) /**< SPI_DEV(0) is used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_CLK SPI0_SCK /**< SPI_DEV(0) SCK is used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_MOSI SPI0_MOSI /**< SPI_DEV(0) MOSI is used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_MISO SPI0_MISO /**< SPI_DEV(0) MISO is used (fixed) */
|
||||
#define SDCARD_SPI_PARAM_POWER GPIO_UNDEF /**< power control is not used (fixed) */
|
||||
|
||||
#ifndef SDCARD_SPI_PARAM_CS
|
||||
#define SDCARD_SPI_PARAM_CS SPI0_CS0_GPIO /**< SD-Card CS signal (can be overridden) */
|
||||
#define SDCARD_SPI_PARAM_CS SPI0_CS0 /**< SD-Card CS signal (can be overridden) */
|
||||
#endif
|
||||
/** @} */
|
||||
#endif /* defined(MODULE_SDCARD_SPI) || defined(DOXYGEN) */
|
||||
|
||||
@ -19,8 +19,8 @@
|
||||
#define PERIPH_CONF_COMMON_H
|
||||
|
||||
/* include board.h and periph_cpu.h to make them visible in any case */
|
||||
#include "board.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -36,18 +36,67 @@ extern "C" {
|
||||
* ESP8266 provides one ADC pin that is broken out on all boards.
|
||||
* @{
|
||||
*/
|
||||
#define ADC_NUMOF 1 /**< number of ADC channels */
|
||||
#define ADC_NUMOF (1) /**< number of ADC channels */
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name DAC configuration
|
||||
*
|
||||
* ESP8266 provides no DAC.
|
||||
* @{
|
||||
*/
|
||||
#define DAC_NUMOF (0) /**< number of DAC channels */
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name I2C configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Static array with configuration for declared I2C devices
|
||||
*/
|
||||
static const i2c_conf_t i2c_config[] = {
|
||||
#if defined(I2C0_SCL) && defined(I2C0_SDA) && defined(I2C0_SPEED)
|
||||
{
|
||||
.speed = I2C0_SPEED,
|
||||
.scl = I2C0_SCL,
|
||||
.sda = I2C0_SDA,
|
||||
},
|
||||
#endif
|
||||
#if defined(I2C1_SCL) && defined(I2C1_SDA) && defined(I2C1_SPEED)
|
||||
{
|
||||
.speed = I2C1_SPEED,
|
||||
.scl = I2C1_SCL,
|
||||
.sda = I2C1_SDA,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Number of I2C interfaces
|
||||
*
|
||||
* The number of I2C interfaces is determined automatically from board-specific
|
||||
* peripheral definitions.
|
||||
*
|
||||
* @note I2C_NUMOF definition must not be changed.
|
||||
*/
|
||||
#define I2C_NUMOF ARRAY_SIZE(i2c_config)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name PWM configuration
|
||||
*
|
||||
* The hardware implementation of ESP8266 PWM supports only frequencies as power of
|
||||
* two. Therefore a software implementation of one PWM device PWM_DEV(0) with up to
|
||||
* 8 PWM channels (PWM_CHANNEL_NUM_MAX) is used.
|
||||
* The hardware implementation of ESP8266 PWM supports only frequencies as
|
||||
* power of two. Therefore a software implementation of one PWM device
|
||||
* PWM_DEV(0) with up to 8 PWM channels (#PWM_CHANNEL_NUM_MAX) is used. The
|
||||
* GPIOs that can be used as PWM channels are defined by #PWM0_GPIOS in board
|
||||
* definition.
|
||||
*
|
||||
* @note The minumum PWM period that can be realized is 10 us or 100.000 PWM
|
||||
* @note The minimum PWM period that can be realized is 10 us or 100.000 PWM
|
||||
* clock cycles per second. Therefore, the product of frequency and resolution
|
||||
* should not be greater than 100.000. Otherwise the frequency is scaled down
|
||||
* automatically.
|
||||
@ -55,71 +104,85 @@ extern "C" {
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(PWM0_GPIOS) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Static array of GPIOs that can be used as channels of PWM_DEV(0)
|
||||
*/
|
||||
static const gpio_t pwm0_channels[] = PWM0_GPIOS;
|
||||
|
||||
/**
|
||||
* @brief Number of PWM devices
|
||||
*
|
||||
* The number of PWM devices is determined from the #PWM0_GPIOS definition.
|
||||
*
|
||||
* @note #PWM_NUMOF definition must not be changed.
|
||||
*/
|
||||
#define PWM_NUMOF (1) /**< Number of PWM devices */
|
||||
|
||||
/**
|
||||
* @brief Maximum number of channels per PWM device.
|
||||
*/
|
||||
#define PWM_CHANNEL_NUM_MAX (8)
|
||||
|
||||
/**
|
||||
* @brief Definition of GPIOs that can be used as PWM channels
|
||||
* of device PWM_DEV(0).
|
||||
*
|
||||
* The following definition is just an example configuration. Declare up to
|
||||
* \ref PWM_CHANNEL_NUM_MAX GPIOs as PWM channels. GPIOs with a duty cycle
|
||||
* value of 0 can be used as normal GPIOs for other purposes. GPIOs in the
|
||||
* list that are used for other purposes, e.g., I2C or SPI, are then not
|
||||
* available as PWM channels.
|
||||
*/
|
||||
#ifndef PWM0_CHANNEL_GPIOS
|
||||
#define PWM0_CHANNEL_GPIOS { GPIO2, GPIO4, GPIO5 }
|
||||
#endif
|
||||
|
||||
/** Alternative device definition */
|
||||
#define PWM0_DEV PWM_DEV(0)
|
||||
#endif /* defined(PWM0_GPIOS) || defined(DOXYGEN) */
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name SPI configuration
|
||||
* @name SPI configuration
|
||||
*
|
||||
* ESP8266 provides two hardware SPI interfaces:
|
||||
* ESP8266 has two SPI controllers:
|
||||
*
|
||||
* _FSPI_ for flash memory and usually simply referred to as _SPI_<br>
|
||||
* _HSPI_ for peripherals
|
||||
* - _CSPI_ for caching and accessing the flash memory<br>
|
||||
* - _HSPI_ for peripherals
|
||||
*
|
||||
* Even though _FSPI_ (or simply _SPI_) is a normal SPI interface, it is not
|
||||
* possible to use it for peripherals. _HSPI_ is therefore the only usable
|
||||
* SPI interface available for peripherals as RIOT's SPI_DEV(0).
|
||||
* Thus, _HSPI_ is the only SPI interface that is available for peripherals.
|
||||
* It is exposed as RIOT's SPI_DEV(0). Furthermore, the pin configuration of
|
||||
* the _HSPI_ interface is fixed as shown in following table.
|
||||
*
|
||||
* The pin configuration of the _HSPI_ interface SPI_DEV(0) is fixed. The
|
||||
* only pin definition that can be overridden by an application-specific
|
||||
* board configuration is the CS signal defined by SPI0_CS0_GPIO.
|
||||
* Signal | Pin
|
||||
* -----------|-------
|
||||
* #SPI0_MISO | GPIO12
|
||||
* #SPI0_MOSI | GPIO13
|
||||
* #SPI0_SCK | GPIO14
|
||||
* #SPI0_CS0 | GPIOn with n = 0, 2, 4, 5, 15, 16 (additionally 9, 10 in DOUT flash mode)
|
||||
*
|
||||
* The only pin definition that can be overridden by an application-specific
|
||||
* board configuration is the CS signal defined by #SPI0_CS0.
|
||||
*
|
||||
* Signal | Pin
|
||||
* ----------------|-------
|
||||
* SPI_DEV(0).MISO | GPIO12
|
||||
* SPI_DEV(0).MOSI | GPIO13
|
||||
* SPI_DEV(0).SCK | GPIO14
|
||||
* SPI_DEV(0).CS | GPIOn with n = 0, 2, 4, 5, 15, 16 (additionally 9, 10 in DOUT flash mode)
|
||||
* @{
|
||||
*/
|
||||
#if defined(MODULE_PERIPH_SPI) || defined(DOXYGEN)
|
||||
|
||||
#define SPI_NUMOF 1 /**< Number of SPI interfaces */
|
||||
#define SPI_DEV(x) ((unsigned int)(x+1)) /**< SPI_DEV to SPI hardware mapping */
|
||||
#define SPI0_DEV SPI_DEV(0) /**< HSPI / SPI_DEV(0) device */
|
||||
#define SPI0_CTRL HSPI /**< HSPI / SPI_DEV(0) controller */
|
||||
#define SPI0_MISO GPIO12 /**< HSPI / SPI_DEV(0) MISO pin */
|
||||
#define SPI0_MOSI GPIO13 /**< HSPI / SPI_DEV(0) MOSI pin */
|
||||
#define SPI0_SCK GPIO14 /**< HSPI / SPI_DEV(0) SCK pin */
|
||||
|
||||
#define SPI0_DEV SPI_DEV(0) /**< HSPI / SPI_DEV(0) device */
|
||||
#define SPI0_MISO_GPIO GPIO12 /**< HSPI / SPI_DEV(0) MISO pin */
|
||||
#define SPI0_MOSI_GPIO GPIO13 /**< HSPI / SPI_DEV(0) MOSI pin */
|
||||
#define SPI0_SCK_GPIO GPIO14 /**< HSPI / SPI_DEV(0) SCK pin */
|
||||
|
||||
#ifndef SPI0_CS0_GPIO
|
||||
#define SPI0_CS0_GPIO GPIO15 /**< HSPI / SPI_DEV(0) CS default pin, only used when cs
|
||||
parameter in spi_acquire is GPIO_UNDEF */
|
||||
#ifndef SPI0_CS0
|
||||
#define SPI0_CS0 GPIO15 /**< HSPI / SPI_DEV(0) CS default pin, only used when cs
|
||||
parameter in spi_acquire is #GPIO_UNDEF */
|
||||
#endif
|
||||
#endif /* defined(MODULE_PERIPH_SPI) || defined(DOXYGEN) */
|
||||
|
||||
/**
|
||||
* @brief Static array with configuration for declared SPI devices
|
||||
*/
|
||||
static const spi_conf_t spi_config[] = {
|
||||
#ifdef SPI0_CTRL
|
||||
{
|
||||
.ctrl = SPI0_CTRL,
|
||||
.sck = SPI0_SCK,
|
||||
.mosi = SPI0_MOSI,
|
||||
.miso = SPI0_MISO,
|
||||
.cs = SPI0_CS0,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Number of SPI interfaces
|
||||
*
|
||||
* The number of SPI interfaces is determined from board-specific peripheral
|
||||
* definitions of SPIn_*.
|
||||
*
|
||||
* @note SPI_NUMOF definition must not be changed.
|
||||
*/
|
||||
#define SPI_NUMOF ARRAY_SIZE(spi_config)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@ -153,9 +216,29 @@ extern "C" {
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define UART_NUMOF 1 /**< Number of UART devices */
|
||||
|
||||
#define UART0_TXD GPIO1 /**< TxD pin of UART_DEV(0) */
|
||||
#define UART0_RXD GPIO3 /**< RxD pin of UART_DEV(0) */
|
||||
|
||||
/**
|
||||
* @brief Static array with configuration for declared UART devices
|
||||
*/
|
||||
static const uart_conf_t uart_config[] = {
|
||||
{
|
||||
.txd = UART0_TXD,
|
||||
.rxd = UART0_RXD,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Number of UART interfaces
|
||||
*
|
||||
* The number of UART interfaces is determined from board-specific peripheral
|
||||
* definitions of UARTn_*.
|
||||
*
|
||||
* @note UART_NUMOF definition must not be changed.
|
||||
*/
|
||||
#define UART_NUMOF (sizeof(uart_config)/sizeof(uart_config[0]))
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -82,7 +82,7 @@ D1 mini Pro | ESP8266EX | 16 MByte | ceramic | |
|
||||
|
||||
Following image shows the pinout of all WEMOS LOLIN D1 mini boards. It is compatible with the WEMOS LOLIN D32 Pro ESP32 board.
|
||||
|
||||
@image html "https://gitlab.com/gschorcht/RIOT.wiki-Images/raw/master/esp8266/Wemos_D1_mini_pinout.png?inline=false" "WEMOS LOLIN D1 min pinout"<br>
|
||||
@image html "https://gitlab.com/gschorcht/RIOT.wiki-Images/raw/master/esp8266/Wemos_D1_mini_pinout.png?inline=false" "WEMOS LOLIN D1 mini pinout"<br>
|
||||
|
||||
## <a name="nodemcu_devkit_esp8266"> NodeMCU DEVKIT </a>
|
||||
|
||||
|
||||
@ -6,10 +6,6 @@
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup boards_esp8266_esp-12x
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup boards_esp8266_esp-12x
|
||||
* @brief Board specific definitions for ESP-12x based boards.
|
||||
|
||||
@ -27,9 +27,6 @@ extern "C" {
|
||||
* @name I2C configuration
|
||||
* @{
|
||||
*/
|
||||
#ifndef I2C_NUMOF
|
||||
#define I2C_NUMOF (1) /**< Number of I2C interfaces */
|
||||
#endif
|
||||
#ifndef I2C0_SPEED
|
||||
#define I2C0_SPEED I2C_SPEED_FAST /**< I2C bus speed of I2C_DEV(0) */
|
||||
#endif
|
||||
@ -41,6 +38,25 @@ extern "C" {
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name PWM channel configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Declaration of the channels for device PWM_DEV(0),
|
||||
* at maximum 8 channels.
|
||||
*
|
||||
* @note As long as PWM_DEV(0) is not initialized with \ref pwm_init, the GPIOs
|
||||
* declared as PWM channels can be used for other purposes.
|
||||
*/
|
||||
#ifndef PWM0_GPIOS
|
||||
#define PWM0_GPIOS { GPIO0, GPIO2, GPIO16 }
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
|
||||
@ -6,10 +6,6 @@
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup boards_esp8266_olimex-mod
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup boards_esp8266_olimex-mod
|
||||
* @brief Board specific definitions for
|
||||
|
||||
@ -28,9 +28,6 @@
|
||||
* @name I2C configuration
|
||||
* @{
|
||||
*/
|
||||
#ifndef I2C_NUMOF
|
||||
#define I2C_NUMOF (1) /**< Number of I2C interfaces */
|
||||
#endif
|
||||
#ifndef I2C0_SPEED
|
||||
#define I2C0_SPEED I2C_SPEED_FAST /**< I2C bus speed of I2C_DEV(0) */
|
||||
#endif
|
||||
@ -42,6 +39,23 @@
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name PWM channel configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Declaration of the channels for device PWM_DEV(0),
|
||||
* at maximum 8 channels.
|
||||
*
|
||||
* @note As long as PWM_DEV(0) is not initialized with \ref pwm_init, the GPIOs
|
||||
* declared as PWM channels can be used for other purposes.
|
||||
*/
|
||||
#ifndef PWM0_GPIOS
|
||||
#define PWM0_GPIOS { GPIO0, GPIO5, GPIO16 }
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
|
||||
@ -6,10 +6,6 @@
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup boards_esp8266_sparkfun-thing
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup boards_esp8266_sparkfun-thing
|
||||
* @brief Board specific definitions for
|
||||
|
||||
@ -28,9 +28,6 @@
|
||||
* @name I2C configuration
|
||||
* @{
|
||||
*/
|
||||
#ifndef I2C_NUMOF
|
||||
#define I2C_NUMOF (1) /**< Number of I2C interfaces */
|
||||
#endif
|
||||
#ifndef I2C0_SPEED
|
||||
#define I2C0_SPEED I2C_SPEED_FAST /**< I2C bus speed of I2C_DEV(0) */
|
||||
#endif
|
||||
@ -42,6 +39,25 @@
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name PWM channel configuration
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Declaration of the channels for device PWM_DEV(0),
|
||||
* at maximum 8 channels.
|
||||
*
|
||||
* @note As long as PWM_DEV(0) is not initialized with \ref pwm_init, the GPIOs
|
||||
* declared as PWM channels can be used for other purposes.
|
||||
*/
|
||||
#ifndef PWM0_GPIOS
|
||||
#define PWM0_GPIOS { GPIO0, GPIO4, GPIO5 }
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
|
||||
@ -205,3 +205,10 @@ void IRAM NORETURN panic_arch(void)
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void _panic_handler(uint32_t addr)
|
||||
{
|
||||
ets_printf("#! _xt_panic called from 0x%08x: powering off\n", addr);
|
||||
pm_off();
|
||||
while (1) { };
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ typedef enum {
|
||||
*
|
||||
* ESP32 integrates two 12-bit ADCs (ADC1 and ADC2) capable of measuring up to
|
||||
* 18 analog signals in total. Most of these ADC channels are either connected
|
||||
* to a number of intergrated sensors like a Hall sensors, touch sensors and a
|
||||
* to a number of integrated sensors like a Hall sensors, touch sensors and a
|
||||
* temperature sensor or can be connected with certain GPIOs. Integrated
|
||||
* sensors are disabled in RIOT's implementation and are not accessible. Thus,
|
||||
* up to 18 GPIOs, the RTC GPIOs, can be used as ADC inputs:
|
||||
@ -209,7 +209,7 @@ typedef enum {
|
||||
* determines the mapping between the RIOT's ADC lines and the GPIOs.
|
||||
*
|
||||
* @note ADC_GPIOS must be defined even if there are no GPIOs that could be
|
||||
* used as ADC channels on the board. In this case, an empy list hast to be
|
||||
* used as ADC channels on the board. In this case, an empty list hast to be
|
||||
* defined which just contains the curly braces.
|
||||
*
|
||||
* ADC_NUMOF is determined automatically from the ADC_GPIOS definition.
|
||||
@ -240,7 +240,7 @@ typedef enum {
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief Number of ADC cahnnels that could be used at maximum
|
||||
* @brief Number of ADC channels that could be used at maximum
|
||||
*
|
||||
* @note GPIO37 and GPIO38 are usually not broken out on ESP32 modules and are
|
||||
* therefore not usable. The maximum number of ADC channels (ADC_NUMOF_MAX)
|
||||
@ -263,7 +263,7 @@ typedef enum {
|
||||
* determines the mapping between the RIOT's DAC lines and the GPIOs.
|
||||
*
|
||||
* @note DAC_GPIOS must be defined even if there are no GPIOs that could be
|
||||
* used as DAC channels on the board. In this case, an empy list hast to be
|
||||
* used as DAC channels on the board. In this case, an empty list hast to be
|
||||
* defined which just contains the curly braces.
|
||||
*
|
||||
* DAC_NUMOF is determined automatically from the DAC_GPIOS definition.
|
||||
@ -275,7 +275,7 @@ typedef enum {
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Number of DAC cahnnels that could be used at maximum.
|
||||
* @brief Number of DAC channels that could be used at maximum.
|
||||
*/
|
||||
#define DAC_NUMOF_MAX 2
|
||||
|
||||
@ -287,7 +287,7 @@ typedef enum {
|
||||
* ESP32 has two built-in I2C interfaces.
|
||||
*
|
||||
* The board-specific configuration of the I2C interface I2C_DEV(n) requires
|
||||
* the defintion of
|
||||
* the definition of
|
||||
*
|
||||
* I2Cn_SPEED, the bus speed,
|
||||
* I2Cn_SCL, the GPIO used as SCL signal, and
|
||||
@ -332,6 +332,11 @@ typedef struct {
|
||||
gpio_t sda; /**< GPIO used as SDA pin */
|
||||
} i2c_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Maximum number of I2C interfaces that can be used by board definitions
|
||||
*/
|
||||
#define I2C_NUMOF_MAX (2)
|
||||
|
||||
#define PERIPH_I2C_NEED_READ_REG /**< i2c_read_reg required */
|
||||
#define PERIPH_I2C_NEED_READ_REGS /**< i2c_read_regs required */
|
||||
#define PERIPH_I2C_NEED_WRITE_REG /**< i2c_write_reg required */
|
||||
@ -340,7 +345,6 @@ typedef struct {
|
||||
|
||||
/**
|
||||
* @name PWM configuration
|
||||
* @{
|
||||
*
|
||||
* PWM implementation uses ESP32's high-speed MCPWM modules. ESP32 has 2 such
|
||||
* modules, each with up to 6 channels (PWM_CHANNEL_NUM_DEV_MAX). Thus, the
|
||||
@ -362,6 +366,8 @@ typedef struct {
|
||||
* @note As long as the GPIOs listed in PWM0_GPIOS and PMW1_GPIOS are not
|
||||
* initialized as PWM channels with the *pwm_init* function, they can be used
|
||||
* other purposes.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -395,7 +401,7 @@ typedef struct {
|
||||
* device driver doesn't support it.
|
||||
*
|
||||
* The board-specific configuration of the SPI interface SPI_DEV(n) requires
|
||||
* the defintion of
|
||||
* the definition of
|
||||
*
|
||||
* - SPIn_CTRL, the SPI controller which is used for the interface (VSPI or HSPI),
|
||||
* - SPIn_SCK, the GPIO used as clock signal
|
||||
@ -409,6 +415,8 @@ typedef struct {
|
||||
*
|
||||
* SPI_NUMOF is determined automatically from the board-specific peripheral
|
||||
* definitions of SPIn_*.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -430,6 +438,11 @@ typedef struct {
|
||||
gpio_t cs; /**< GPIO used as CS0 pin */
|
||||
} spi_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Maximum number of SPI interfaces that can be used by board definitions
|
||||
*/
|
||||
#define SPI_NUMOF_MAX 2
|
||||
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE /**< requires function spi_transfer_byte */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REG /**< requires function spi_transfer_reg */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REGS /**< requires function spi_transfer_regs */
|
||||
|
||||
@ -3,6 +3,7 @@ MODULE = cpu
|
||||
|
||||
# Add a list of subdirectories, that should also be built:
|
||||
DIRS += $(RIOTCPU)/esp_common
|
||||
DIRS += freertos
|
||||
DIRS += periph
|
||||
DIRS += sdk
|
||||
DIRS += vendor
|
||||
@ -11,4 +12,6 @@ ifneq (, $(filter esp_wifi, $(USEMODULE)))
|
||||
DIRS += esp-wifi
|
||||
endif
|
||||
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/esp8266/include/internal
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -1,17 +1,5 @@
|
||||
# additional modules dependencies
|
||||
|
||||
ifneq (, $(filter esp_sdk, $(USEMODULE)))
|
||||
USEMODULE += core_thread_flags
|
||||
INCLUDES += -I$(ESP8266_SDK_DIR)/third_party/include
|
||||
LINKFLAGS += -Wl,-wrap=malloc
|
||||
LINKFLAGS += -Wl,-wrap=free
|
||||
LINKFLAGS += -Wl,-wrap=calloc
|
||||
LINKFLAGS += -Wl,-wrap=realloc
|
||||
LINKFLAGS += -Wl,-wrap=_malloc_r
|
||||
LINKFLAGS += -Wl,-wrap=_free_r
|
||||
LINKFLAGS += -Wl,-wrap=_realloc_r
|
||||
endif
|
||||
|
||||
ifneq (, $(filter esp_spiffs, $(USEMODULE)))
|
||||
export SPIFFS_STD_OPTION = -std=c99
|
||||
USEMODULE += spiffs
|
||||
@ -19,12 +7,9 @@ ifneq (, $(filter esp_spiffs, $(USEMODULE)))
|
||||
endif
|
||||
|
||||
ifneq (, $(filter esp_wifi, $(USEMODULE)))
|
||||
CFLAGS += -DLWIP_OPEN_SRC
|
||||
LINKFLAGS += -Wl,-wrap=ethernet_input
|
||||
USEMODULE += netdev_eth
|
||||
endif
|
||||
|
||||
ifneq (,$(filter ndn-riot,$(USEPKG)))
|
||||
USEMODULE += crypto
|
||||
USEMODULE += cipher_modes
|
||||
ifneq (,$(filter log_color,$(USEMODULE)))
|
||||
USEMODULE += esp_log_colored
|
||||
endif
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
FEATURES_PROVIDED += arch_32bit
|
||||
FEATURES_PROVIDED += arch_esp8266
|
||||
FEATURES_PROVIDED += cpp
|
||||
FEATURES_PROVIDED += periph_cpuid
|
||||
FEATURES_PROVIDED += periph_hwrng
|
||||
FEATURES_PROVIDED += periph_pm
|
||||
|
||||
@ -1,23 +1,13 @@
|
||||
# check some environment variables first
|
||||
|
||||
ifndef ESP8266_NEWLIB_DIR
|
||||
$(info ESP8266_NEWLIB_DIR should be defined as /path/to/newlib directory)
|
||||
$(info ESP8266_NEWLIB_DIR is set by default to /opt/esp/newlib-xtensa)
|
||||
export ESP8266_NEWLIB_DIR=/opt/esp/newlib-xtensa
|
||||
endif
|
||||
|
||||
ifndef ESP8266_SDK_DIR
|
||||
$(info ESP8266_SDK_DIR should be defined as /path/to/sdk directory)
|
||||
$(info ESP8266_SDK_DIR is set by default to /opt/esp/esp-open-sdk/sdk)
|
||||
export ESP8266_SDK_DIR=/opt/esp/esp-open-sdk/sdk
|
||||
ifndef ESP8266_RTOS_SDK_DIR
|
||||
$(info ESP8266_RTOS_SDK_DIR should be defined as /path/to/sdk directory)
|
||||
$(info ESP8266_RTOS_SDK_DIR is set by default to /opt/esp/ESP8266-RTOS-SDK)
|
||||
export ESP8266_RTOS_SDK_DIR=/opt/esp/ESP8266-RTOS-SDK
|
||||
endif
|
||||
|
||||
# Options to control the compilation
|
||||
|
||||
ifeq ($(USE_SDK), 1)
|
||||
USEMODULE += esp_sdk
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_GDB), 1)
|
||||
USEMODULE += esp_gdb
|
||||
endif
|
||||
@ -29,85 +19,117 @@ endif
|
||||
# SPECIAL module dependencies
|
||||
# cannot be done in Makefile.dep since Makefile.dep is included too late
|
||||
|
||||
ifneq (, $(filter esp_sw_timer, $(USEMODULE)))
|
||||
USEMODULE += esp_sdk
|
||||
endif
|
||||
|
||||
ifneq (, $(filter esp_wifi, $(USEMODULE)))
|
||||
ifneq (, $(filter esp_now esp_wifi, $(USEMODULE)))
|
||||
$(eval GNRC_NETIF_NUMOF=$(shell echo $$(($(GNRC_NETIF_NUMOF)+1))))
|
||||
USEMODULE += esp_sdk
|
||||
USEMODULE += netopt
|
||||
endif
|
||||
|
||||
ifneq (, $(filter esp_now, $(USEMODULE)))
|
||||
$(eval GNRC_NETIF_NUMOF=$(shell echo $$(($(GNRC_NETIF_NUMOF)+1))))
|
||||
USEMODULE += esp_sdk
|
||||
CFLAGS += -DSCHED_PRIO_LEVELS=32
|
||||
USEMODULE += esp_wifi_any
|
||||
USEMODULE += netopt
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (, $(filter esp_gdbstub, $(USEMODULE)))
|
||||
USEMODULE += esp_gdb
|
||||
endif
|
||||
|
||||
ifneq (, $(filter spiffs, $(USEMODULE)))
|
||||
export RIOT_TEST_TIMEOUT = 300
|
||||
endif
|
||||
|
||||
ifneq (, $(filter littlefs, $(USEMODULE)))
|
||||
export RIOT_TEST_TIMEOUT = 300
|
||||
endif
|
||||
|
||||
# regular Makefile
|
||||
|
||||
export TARGET_ARCH ?= xtensa-lx106-elf
|
||||
export TARGET_ARCH ?= xtensa-esp8266-elf
|
||||
|
||||
# ESP8266 pseudomodules
|
||||
PSEUDOMODULES += esp_gdb
|
||||
PSEUDOMODULES += esp_sdk
|
||||
PSEUDOMODULES += esp_log_colored
|
||||
PSEUDOMODULES += esp_log_tagged
|
||||
PSEUDOMODULES += esp_qemu
|
||||
PSEUDOMODULES += esp_sw_timer
|
||||
PSEUDOMODULES += esp_spiffs
|
||||
PSEUDOMODULES += esp_wifi_any
|
||||
|
||||
USEMODULE += esp
|
||||
USEMODULE += esp_freertos
|
||||
USEMODULE += esp_idf
|
||||
USEMODULE += esp_idf_esp8266
|
||||
USEMODULE += esp_idf_nvs_flash
|
||||
USEMODULE += esp_idf_spi_flash
|
||||
USEMODULE += esp_idf_util
|
||||
USEMODULE += esp_idf_wpa_supplicant_crypto
|
||||
USEMODULE += esp_sdk
|
||||
USEMODULE += log
|
||||
USEMODULE += mtd
|
||||
USEMODULE += newlib
|
||||
USEMODULE += newlib_nano
|
||||
USEMODULE += newlib_syscalls_default
|
||||
USEMODULE += periph
|
||||
USEMODULE += periph_common
|
||||
USEMODULE += periph_hrng
|
||||
USEMODULE += periph_flash
|
||||
USEMODULE += periph_uart
|
||||
USEMODULE += ps
|
||||
USEMODULE += random
|
||||
USEMODULE += sdk
|
||||
USEMODULE += stdio_uart
|
||||
USEMODULE += xtensa
|
||||
|
||||
ifneq (, $(filter pthread, $(USEMODULE)))
|
||||
# has to be included before $(ESP8266_NEWLIB_DIR)
|
||||
INCLUDES += -I$(RIOTBASE)/sys/posix/pthread/include
|
||||
endif
|
||||
|
||||
INCLUDES += -I$(ESP8266_NEWLIB_DIR)/$(TARGET_ARCH)/include
|
||||
INCLUDES += -I$(RIOTBOARD)/common/$(CPU)/include
|
||||
INCLUDES += -I$(RIOTCPU)/esp_common/vendor/
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/include
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/include/freertos
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor/espressif
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor/esp-idf/
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor/esp-idf/bootloader_support/include
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor/esp-idf/esp8266/include
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor/esp-idf/esp8266/include/esp8266
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor/esp-idf/heap/include
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/vendor/esp-idf/log/include
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/bootloader_support/include/
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/esp8266/include
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/esp8266/include/esp8266
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/heap/include
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/heap/port/esp8266/include
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/nvs_flash/include
|
||||
INCLUDES += -I$(ESP8266_RTOS_SDK_DIR)/components/spi_flash/include
|
||||
|
||||
CFLAGS += -DESP_OPEN_SDK -DSCHED_PRIO_LEVELS=32 -DCONTEXT_SWITCH_BY_INT
|
||||
CFLAGS += -D__ESP_FILE__=__FILE__
|
||||
CFLAGS += -Wno-unused-parameter -Wformat=0
|
||||
CFLAGS += -mlongcalls -mtext-section-literals
|
||||
CFLAGS += -ffunction-sections -fdata-sections -fzero-initialized-in-bss
|
||||
CFLAGS += -mlongcalls -mtext-section-literals -fstrict-volatile-bitfields
|
||||
CFLAGS += -fdata-sections -ffunction-sections -fzero-initialized-in-bss
|
||||
|
||||
OPTIONAL_CFLAGS_BLACKLIST += -fdiagnostics-color
|
||||
OPTIONAL_CFLAGS_BLACKLIST += -Wformat-overflow
|
||||
OPTIONAL_CFLAGS_BLACKLIST += -Wformat-truncation
|
||||
OPTIONAL_CFLAGS_BLACKLIST += -gz
|
||||
|
||||
ASFLAGS += --longcalls --text-section-literals
|
||||
|
||||
ifneq (, $(filter esp_sdk, $(USEMODULE)))
|
||||
INCLUDES += -I$(ESP8266_SDK_DIR)/include
|
||||
CFLAGS += -DUSE_US_TIMER
|
||||
endif
|
||||
# thin archives trigger a reboot loop - see #12258, #12035, #12346
|
||||
ARFLAGS = rcs
|
||||
|
||||
ifneq (, $(filter esp_gdbstub, $(USEMODULE)))
|
||||
GDBSTUB_DIR ?= $(RIOTCPU)/$(CPU)/vendor/esp-gdbstub
|
||||
CFLAGS += -DGDBSTUB_FREERTOS=0
|
||||
CFLAGS += -DGDBSTUB_BREAK_ON_INIT=1
|
||||
INCLUDES += -I$(GDBSTUB_DIR)
|
||||
endif
|
||||
|
||||
ifneq (, $(filter esp_gdb, $(USEMODULE)))
|
||||
CFLAGS += -Og -ggdb -g3
|
||||
CFLAGS_OPT ?= -Og -ggdb -g3
|
||||
else
|
||||
CFLAGS += -Os
|
||||
# TODO should be -Os
|
||||
# With -Os char arrays have not to be 32-bit word aligned. This leads to
|
||||
# an alignment exception when the address of an char array is assigned to
|
||||
# an uint32_t pointer and the pointer is used for the access.
|
||||
CFLAGS_OPT ?= -O2
|
||||
endif
|
||||
|
||||
CFLAGS += $(CFLAGS_OPT)
|
||||
|
||||
ifeq ($(QEMU), 1)
|
||||
CFLAGS += -DQEMU
|
||||
USEMODULE += esp_qemu
|
||||
endif
|
||||
|
||||
ifeq ($(FLASH_MODE), qio)
|
||||
@ -118,51 +140,80 @@ ifeq ($(FLASH_MODE), qout)
|
||||
CFLAGS += -DFLASH_MODE_QOUT
|
||||
endif
|
||||
|
||||
LINKFLAGS += -L$(ESP8266_NEWLIB_DIR)/$(TARGET_ARCH)/lib
|
||||
LINKFLAGS += -L$(ESP8266_SDK_DIR)/lib
|
||||
LINKFLAGS += -L$(ESP8266_RTOS_SDK_DIR)/components/esp8266/lib
|
||||
LINKFLAGS += $(CFLAGS_OPT)
|
||||
|
||||
ifneq (, $(filter esp_sdk, $(USEMODULE)))
|
||||
LINKFLAGS += -Wl,--start-group $(BINDIR)/sdk.a
|
||||
ifneq (, $(filter esp_now, $(USEMODULE)))
|
||||
LINKFLAGS += -lespnow
|
||||
endif
|
||||
LINKFLAGS += -lmain -lnet80211 -lcrypto -lwpa2 -lwpa -llwip -lpp -lphy -lc -lhal
|
||||
LINKFLAGS += -Wl,--end-group
|
||||
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp8266.riot-os.sdk.app.ld
|
||||
else
|
||||
LINKFLAGS += -Wl,--start-group -lphy -lhal -lc -Wl,--end-group
|
||||
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp8266.riot-os.no_sdk.app.ld
|
||||
BASELIBS += -lc -lgcc -lwpa -lcore -lnet80211 -lphy -lpp -lhal -lstdc++
|
||||
|
||||
ifneq (, $(filter esp_now, $(USEMODULE)))
|
||||
BASELIBS += -lespnow
|
||||
endif
|
||||
|
||||
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/eagle.rom.addr.v6.ld
|
||||
LINKFLAGS += -nostdlib -lgcc -u ets_run -Wl,-gc-sections # -Wl,--print-gc-sections
|
||||
LINKFLAGS += -u _malloc_r
|
||||
LINKFLAGS += -nostdlib -Wl,-gc-sections -Wl,-static # -Wl,--print-gc-sections
|
||||
|
||||
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp8266.rom.ld
|
||||
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp8266.riot-os.ld
|
||||
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/esp8266.peripherals.ld
|
||||
|
||||
LINKFLAGS += -Wl,-wrap=pp_attach
|
||||
LINKFLAGS += -Wl,-wrap=pm_attach
|
||||
|
||||
ifneq (, $(filter esp_idf_heap, $(USEMODULE)))
|
||||
LINKFLAGS += -Wl,-wrap=_malloc_r
|
||||
LINKFLAGS += -Wl,-wrap=_calloc_r
|
||||
LINKFLAGS += -Wl,-wrap=_free_r
|
||||
LINKFLAGS += -Wl,-wrap=_realloc_r
|
||||
endif
|
||||
|
||||
# The ELFFILE is the base one used for flashing
|
||||
FLASHFILE ?= $(ELFFILE)
|
||||
|
||||
# configure preflasher to convert .elf to .bin before flashing
|
||||
FLASH_SIZE = -fs 8m
|
||||
PREFLASHER ?= esptool.py
|
||||
PREFFLAGS ?= elf2image $(FLASH_SIZE) $(FLASHFILE)
|
||||
FLASH_MODE = dout # FIX configuration, DO NOT CHANGE
|
||||
FLASH_FREQ = 26m # FIX configuration, DO NOT CHANGE
|
||||
FLASH_SIZE ?= 1MB
|
||||
FLASHDEPS += preflash
|
||||
|
||||
# flasher configuration
|
||||
ifeq ($(QEMU), 1)
|
||||
FLASHER = cat
|
||||
FFLAGS += $(FLASHFILE)-0x00000.bin /dev/zero | head -c $$((0x10000)) | cat -
|
||||
FFLAGS += $(FLASHFILE)-0x10000.bin /dev/zero | head -c $$((0xfc000)) | cat -
|
||||
FFLAGS += $(RIOTCPU)/$(CPU)/bin/esp_init_data_default.bin > $(FLASHFILE).bin
|
||||
PREFLASHER ?= $(RIOTTOOLS)/esptool/esptool.py
|
||||
PREFFLAGS = --chip esp8266 elf2image
|
||||
PREFFLAGS += --flash_mode $(FLASH_MODE) --flash_size $(FLASH_SIZE)
|
||||
PREFFLAGS += --flash_freq $(FLASH_FREQ) --version 3
|
||||
PREFFLAGS += -o $(FLASHFILE).bin $(FLASHFILE);
|
||||
PREFFLAGS += echo "" > $(BINDIR)/partitions.csv;
|
||||
PREFFLAGS += echo "nvs, data, nvs, 0x9000, 0x6000" >> $(BINDIR)/partitions.csv;
|
||||
PREFFLAGS += echo "phy_init, data, phy, 0xf000, 0x1000" >> $(BINDIR)/partitions.csv;
|
||||
PREFFLAGS += echo -n "factory, app, factory, 0x10000, " >> $(BINDIR)/partitions.csv;
|
||||
PREFFLAGS += ls -l $(FLASHFILE).bin | awk '{ print $$5 }' >> $(BINDIR)/partitions.csv;
|
||||
|
||||
PREFFLAGS += python $(RIOTCPU)/$(CPU)/vendor/esp-idf/partition_table/gen_esp32part.py
|
||||
PREFFLAGS += --verify $(BINDIR)/partitions.csv $(BINDIR)/partitions.bin
|
||||
|
||||
ifneq (, $(filter esp_log_colored, $(USEMODULE)))
|
||||
BOOTLOADER ?= bootloader_dout_115200_color.bin
|
||||
else
|
||||
FLASH_MODE ?= dout
|
||||
export PROGRAMMER_SPEED ?= 460800
|
||||
FLASHER = esptool.py
|
||||
FFLAGS += -p $(PROG_DEV) -b $(PROGRAMMER_SPEED) write_flash
|
||||
FFLAGS += -fm $(FLASH_MODE)
|
||||
FFLAGS += 0 $(FLASHFILE)-0x00000.bin
|
||||
FFLAGS += 0x10000 $(FLASHFILE)-0x10000.bin; esptool.py -p $(PROG_DEV) run
|
||||
BOOTLOADER ?= bootloader_dout_115200_no_color.bin
|
||||
endif
|
||||
|
||||
OPTIONAL_CFLAGS_BLACKLIST += -fdiagnostics-color
|
||||
OPTIONAL_CFLAGS_BLACKLIST += -Wformat-overflow
|
||||
OPTIONAL_CFLAGS_BLACKLIST += -Wformat-truncation
|
||||
OPTIONAL_CFLAGS_BLACKLIST += -gz
|
||||
ifneq (, $(filter esp_qemu, $(USEMODULE)))
|
||||
FLASHER = dd
|
||||
FFLAGS += if=/dev/zero bs=1M count=1 | tr "\\000" "\\377" > tmp.bin &&
|
||||
FFLAGS += cat $(RIOTCPU)/$(CPU)/bin/$(BOOTLOADER) tmp.bin |
|
||||
FFLAGS += head -c $$((0x8000)) |
|
||||
FFLAGS += cat - $(BINDIR)/partitions.bin tmp.bin |
|
||||
FFLAGS += head -c $$((0x10000)) |
|
||||
FFLAGS += cat - $(FLASHFILE).bin tmp.bin |
|
||||
FFLAGS += head -c $$((0xfc000)) |
|
||||
FFLAGS += cat - $(RIOTCPU)/$(CPU)/bin/esp_init_data_default.bin tmp.bin |
|
||||
FFLAGS += head -c $$((0x100000)) > $(BINDIR)/esp8266flash.bin && rm tmp.bin
|
||||
else
|
||||
export PROGRAMMER_SPEED ?= 460800
|
||||
FLASHER = $(RIOTBASE)/dist/tools/esptool/esptool.py
|
||||
FFLAGS += --chip esp8266 --port $(PROG_DEV) --baud $(PROGRAMMER_SPEED)
|
||||
FFLAGS += --before default_reset write_flash -z
|
||||
FFLAGS += --flash_size detect
|
||||
FFLAGS += --flash_mode $(FLASH_MODE) --flash_freq $(FLASH_FREQ)
|
||||
FFLAGS += 0x0000 $(RIOTCPU)/$(CPU)/bin/$(BOOTLOADER)
|
||||
FFLAGS += 0x8000 $(BINDIR)/partitions.bin
|
||||
FFLAGS += 0x10000 $(FLASHFILE).bin
|
||||
endif
|
||||
|
||||
BIN
cpu/esp8266/bin/bootloader_dout_115200_color.bin
Normal file
BIN
cpu/esp8266/bin/bootloader_dout_115200_color.bin
Normal file
Binary file not shown.
BIN
cpu/esp8266/bin/bootloader_dout_115200_no_color.bin
Normal file
BIN
cpu/esp8266/bin/bootloader_dout_115200_no_color.bin
Normal file
Binary file not shown.
1054
cpu/esp8266/doc.txt
1054
cpu/esp8266/doc.txt
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,7 @@
|
||||
MODULE=esp_wifi
|
||||
|
||||
# we have to do it in that way to avoid that pkg/lwip is found first
|
||||
CFLAGS += -I$(ESP8266_RTOS_SDK_DIR)/components/lwip/lwip/src/include
|
||||
CFLAGS += -I$(ESP8266_RTOS_SDK_DIR)/components/lwip/port/esp8266/include/
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -34,7 +34,7 @@ make -C examples/gnrc_networking BOARD=...
|
||||
```
|
||||
|
||||
@note The Wifi network interface (module `esp_wifi`) and the
|
||||
\ref esp32_esp_now_network_interface "ESP-NOW network interface" (module `esp_now`)
|
||||
\ref esp8266_esp_now_network_interface "ESP-NOW network interface" (module `esp_now`)
|
||||
can be used simultaneously, for example, to realize a border router for
|
||||
a mesh network which uses ESP-NOW.
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Network device driver for the ESP8266 WiFi interface
|
||||
* @brief Network device driver for the ESP32 WiFi interface
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
@ -20,35 +20,46 @@
|
||||
#define ESP_WIFI_NETDEV_H
|
||||
|
||||
#include "net/netdev.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief State of the WiFi interface
|
||||
* @brief Buffer size used for RX buffering
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_WIFI_NOT_WORKING, /**< interface is not working correctly */
|
||||
ESP_WIFI_DISCONNECTED, /**< interface is not associated to the AP */
|
||||
ESP_WIFI_CONNECTING, /**< interface is trying an association to the AP */
|
||||
ESP_WIFI_CONNECTED /**< interface is not associated to the AP */
|
||||
} esp_wifi_state_t;
|
||||
#ifndef ESP_WIFI_BUFSIZE
|
||||
#define ESP_WIFI_BUFSIZE (ETHERNET_MAX_LEN << 1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for ESP infrastructure mode WIFI device
|
||||
* @brief Reference to the netdev device driver struct
|
||||
*/
|
||||
extern const netdev_driver_t esp_wifi_driver;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for ESP WiFi devices
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
netdev_t netdev; /**< netdev parent struct */
|
||||
netdev_t netdev; /**< netdev parent struct */
|
||||
|
||||
uint8_t mac[ETHERNET_ADDR_LEN]; /**< MAC address of the device */
|
||||
uint8_t rx_mem[ESP_WIFI_BUFSIZE]; /**< memory holding incoming packages */
|
||||
ringbuffer_t rx_buf; /**< ringbuffer for incoming packages */
|
||||
|
||||
uint8_t rx_buf[ETHERNET_MAX_LEN]; /**< receive buffer */
|
||||
uint16_t rx_len; /**< number of bytes received from lwIP */
|
||||
uint16_t tx_len; /**< number of bytes in transmit buffer */
|
||||
uint8_t tx_buf[ETHERNET_MAX_LEN]; /**< transmit buffer */
|
||||
|
||||
esp_wifi_state_t state; /**< indicates the interface state */
|
||||
uint32_t event; /**< received event */
|
||||
uint8_t event_recv; /**< number of frame received events */
|
||||
uint8_t event_conn; /**< number of pending connect events */
|
||||
uint8_t event_disc; /**< number of pending disc events */
|
||||
|
||||
bool connected; /**< indicates whether connected to AP */
|
||||
|
||||
gnrc_netif_t* netif; /**< reference to the corresponding netif */
|
||||
|
||||
mutex_t dev_lock; /**< device is already in use */
|
||||
|
||||
} esp_wifi_netdev_t;
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Parameters for the ESP8266 WiFi netdev interface
|
||||
* @brief Parameters for the ESP32 WiFi netdev interface
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
@ -20,10 +20,10 @@
|
||||
#ifndef ESP_WIFI_PARAMS_H
|
||||
#define ESP_WIFI_PARAMS_H
|
||||
|
||||
#if MODULE_ESP_WIFI || DOXYGEN
|
||||
#if defined(MODULE_ESP_WIFI) || defined(DOXYGEN)
|
||||
|
||||
/**
|
||||
* @name Set default configuration parameters for the ESP WIFI netdev driver
|
||||
* @name Set default configuration parameters for the ESP WiFi netdev driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -31,30 +31,32 @@
|
||||
* @brief The size of the stack used for the ESP WIFI netdev driver thread.
|
||||
*/
|
||||
#ifndef ESP_WIFI_STACKSIZE
|
||||
#define ESP_WIFI_STACKSIZE (1536)
|
||||
#define ESP_WIFI_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The priority of the ESP WiFi netdev driver thread. Should not be changed.
|
||||
*/
|
||||
#ifndef ESP_WIFI_PRIO
|
||||
#define ESP_WIFI_PRIO (GNRC_NETIF_PRIO)
|
||||
#define ESP_WIFI_PRIO (GNRC_NETIF_PRIO)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SSID of the AP to be used.
|
||||
*/
|
||||
#ifndef ESP_WIFI_SSID
|
||||
#define ESP_WIFI_SSID "RIOT_AP"
|
||||
#define ESP_WIFI_SSID "RIOT_AP"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Passphrase used for the AP (max. 64 chars).
|
||||
* @brief Passphrase used for the AP as clear text (max. 64 chars).
|
||||
*/
|
||||
#ifndef ESP_WIFI_PASS
|
||||
#define ESP_WIFI_PASS "ThisistheRIOTporttoESP"
|
||||
#define ESP_WIFI_PASS "ThisistheRIOTporttoESP"
|
||||
#endif
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
103
cpu/esp8266/esp_events.c
Normal file
103
cpu/esp8266/esp_events.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP system event handler
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined(MODULE_ESP_WIFI_ANY) || defined(MODULE_ESP_ETH)
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "irq_arch.h"
|
||||
|
||||
#define MAX_HANDLER_NUM 5
|
||||
|
||||
static system_event_cb_t _handler[MAX_HANDLER_NUM] = {};
|
||||
static void* _handler_arg[MAX_HANDLER_NUM] = {};
|
||||
|
||||
esp_err_t esp_system_event_add_handler (system_event_cb_t handler, void *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* determine next free handler entry */
|
||||
for (i = 0; i < MAX_HANDLER_NUM; i++) {
|
||||
if (_handler[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* return if there is no free entry */
|
||||
if (i == MAX_HANDLER_NUM) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* set the handler and argument entry */
|
||||
_handler[i] = handler;
|
||||
_handler_arg[i] = arg;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_system_event_del_handler (system_event_cb_t handler)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* determine the handler entry */
|
||||
for (i = 0; i < MAX_HANDLER_NUM; i++) {
|
||||
if (_handler[i] == handler) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* return if entry was not found */
|
||||
if (i == MAX_HANDLER_NUM) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* clean handler and arg entry */
|
||||
_handler[i] = NULL;
|
||||
_handler_arg[i] = NULL;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_system_event_handler(void *ctx, system_event_t *event)
|
||||
{
|
||||
for (int i = 0; i < MAX_HANDLER_NUM; i++) {
|
||||
if (_handler[i] != NULL) {
|
||||
_handler[i](_handler_arg[i], event);
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void esp_event_handler_init(void)
|
||||
{
|
||||
#if defined(MODULE_ESP_WIFI_ANY) || defined(MODULE_ESP_ETH)
|
||||
esp_event_loop_init(esp_system_event_handler, NULL);
|
||||
#endif
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -17,87 +17,144 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
#include "periph/pm.h"
|
||||
#include "ps.h"
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "esp/common_macros.h"
|
||||
#include "esp/xtensa_ops.h"
|
||||
#include "sdk/ets.h"
|
||||
#include "tools.h"
|
||||
#include "xtensa/corebits.h"
|
||||
#include "xtensa/xtensa_api.h"
|
||||
|
||||
extern void heap_stats(void);
|
||||
|
||||
static const char* exception_names [] =
|
||||
{
|
||||
"IllegalInstructionCause", /* 0 */
|
||||
"SyscallCause", /* 1 */
|
||||
"InstructionFetchErrorCause", /* 2 */
|
||||
"LoadStoreErrorCause", /* 3 */
|
||||
"Level1InterruptCause", /* 4 */
|
||||
"AllocaCause", /* 5 */
|
||||
"IntegerDivideByZeroCause", /* 6 */
|
||||
"", /* 7 - reserved */
|
||||
"PrivilegedCause", /* 8 */
|
||||
"LoadStoreAlignmentCause", /* 9 */
|
||||
"", /* 10 - reserved */
|
||||
"", /* 11 - reserved */
|
||||
"InstrPIFDataErrorCause", /* 12 */
|
||||
"LoadStorePIFDataErrorCause", /* 13 */
|
||||
"InstrPIFAddrErrorCause", /* 14 */
|
||||
"LoadStorePIFAddrErrorCause", /* 15 */
|
||||
"InstTLBMissCause", /* 16 */
|
||||
"InstTLBMultiHitCause", /* 17 */
|
||||
"InstFetchPrivilegeCause", /* 18 */
|
||||
"", /* 19 - reserved */
|
||||
"InstFetchProhibitedCause", /* 20 */
|
||||
"", /* 21 - reserved */
|
||||
"", /* 22 - reserved */
|
||||
"", /* 23 - reserved */
|
||||
"LoadStoreTLBMissCause", /* 24 */
|
||||
"LoadStoreTLBMultiHitCause", /* 25 */
|
||||
"LoadStorePrivilegeCause", /* 26 */
|
||||
"", /* 27 - reserved */
|
||||
"LoadProhibitedCause", /* 28 */
|
||||
"StoreProhibitedCause", /* 29 */
|
||||
"", /* 30 - reserved */
|
||||
"", /* 31 - reserved */
|
||||
"Coprocessor0Disabled", /* 32 */
|
||||
"Coprocessor1Disabled", /* 33 */
|
||||
"Coprocessor2Disabled", /* 34 */
|
||||
"Coprocessor3Disabled", /* 35 */
|
||||
"Coprocessor4Disabled", /* 36 */
|
||||
"Coprocessor5Disabled", /* 37 */
|
||||
"Coprocessor6Disabled", /* 38 */
|
||||
"Coprocessor7Disabled", /* 39 */
|
||||
"IllegalInstructionCause", /* 0 */
|
||||
"SyscallCause", /* 1 */
|
||||
"InstructionFetchErrorCause", /* 2 */
|
||||
"LoadStoreErrorCause", /* 3 */
|
||||
"Level1InterruptCause", /* 4 */
|
||||
"AllocaCause", /* 5 */
|
||||
"IntegerDivideByZeroCause", /* 6 */
|
||||
"", /* 7 - reserved */
|
||||
"PrivilegedCause", /* 8 */
|
||||
"LoadStoreAlignmentCause", /* 9 */
|
||||
"", /* 10 - reserved */
|
||||
"", /* 11 - reserved */
|
||||
"InstrPIFDataErrorCause", /* 12 */
|
||||
"LoadStorePIFDataErrorCause", /* 13 */
|
||||
"InstrPIFAddrErrorCause", /* 14 */
|
||||
"LoadStorePIFAddrErrorCause", /* 15 */
|
||||
"InstTLBMissCause", /* 16 */
|
||||
"InstTLBMultiHitCause", /* 17 */
|
||||
"InstFetchPrivilegeCause", /* 18 */
|
||||
"", /* 19 - reserved */
|
||||
"InstFetchProhibitedCause", /* 20 */
|
||||
"", /* 21 - reserved */
|
||||
"", /* 22 - reserved */
|
||||
"", /* 23 - reserved */
|
||||
"LoadStoreTLBMissCause", /* 24 */
|
||||
"LoadStoreTLBMultiHitCause", /* 25 */
|
||||
"LoadStorePrivilegeCause", /* 26 */
|
||||
"", /* 27 - reserved */
|
||||
"LoadProhibitedCause", /* 28 */
|
||||
"StoreProhibitedCause", /* 29 */
|
||||
"", /* 30 - reserved */
|
||||
"", /* 31 - reserved */
|
||||
"Coprocessor0Disabled", /* 32 */
|
||||
"Coprocessor1Disabled", /* 33 */
|
||||
"Coprocessor2Disabled", /* 34 */
|
||||
"Coprocessor3Disabled", /* 35 */
|
||||
"Coprocessor4Disabled", /* 36 */
|
||||
"Coprocessor5Disabled", /* 37 */
|
||||
"Coprocessor6Disabled", /* 38 */
|
||||
"Coprocessor7Disabled", /* 39 */
|
||||
};
|
||||
|
||||
void IRAM NORETURN exception_handler (XtExcFrame *frame)
|
||||
{
|
||||
uint32_t excsave1;
|
||||
uint32_t epc1;
|
||||
uint32_t epc2;
|
||||
uint32_t epc3;
|
||||
RSR(excsave1, excsave1);
|
||||
RSR(epc1, epc1);
|
||||
RSR(epc2, epc2);
|
||||
RSR(epc3, epc3);
|
||||
|
||||
ets_printf("EXCEPTION!! exccause=%d (%s) @%08lx excvaddr=%08lx\n",
|
||||
#ifdef MCU_ESP32
|
||||
uint32_t epc4;
|
||||
RSR(epc4, epc4);
|
||||
#endif
|
||||
|
||||
ets_printf("EXCEPTION!! exccause=%d (%s) @%08x excvaddr=%08x\n",
|
||||
frame->exccause, exception_names[frame->exccause],
|
||||
excsave1, frame->excvaddr);
|
||||
#if defined(DEVELHELP)
|
||||
#if defined(MODULE_PS)
|
||||
ps();
|
||||
#endif
|
||||
print_meminfo();
|
||||
#endif
|
||||
/* flushing the buffer */
|
||||
ets_printf(" \n");
|
||||
ets_printf(" \n");
|
||||
ets_printf(" \n");
|
||||
|
||||
#if defined(DEVELHELP)
|
||||
|
||||
#if defined(MODULE_PS)
|
||||
ets_printf("processes:\n");
|
||||
ps();
|
||||
ets_printf("\n");
|
||||
#endif /* MODULE_PS */
|
||||
|
||||
heap_stats();
|
||||
|
||||
ets_printf("\nregister set\n");
|
||||
ets_printf("pc : %08x\t", frame->pc);
|
||||
ets_printf("ps : %08x\t", frame->ps);
|
||||
ets_printf("exccause: %08x\t", frame->exccause);
|
||||
ets_printf("excvaddr: %08x\n", frame->excvaddr);
|
||||
ets_printf("epc1 : %08x\t", epc1);
|
||||
ets_printf("epc2 : %08x\t", epc2);
|
||||
ets_printf("epc3 : %08x\t", epc3);
|
||||
#ifdef MCU_ESP32
|
||||
ets_printf("epc4 : %08x\n", epc4);
|
||||
#else /* MCU_ESP32 */
|
||||
ets_printf("epc3 : %08x\n", epc3);
|
||||
#endif /* MCU_ESP32 */
|
||||
ets_printf("a0 : %08x\t", frame->a0);
|
||||
ets_printf("a1 : %08x\t", frame->a1);
|
||||
ets_printf("a2 : %08x\t", frame->a2);
|
||||
ets_printf("a3 : %08x\n", frame->a3);
|
||||
ets_printf("a4 : %08x\t", frame->a4);
|
||||
ets_printf("a5 : %08x\t", frame->a5);
|
||||
ets_printf("a6 : %08x\t", frame->a6);
|
||||
ets_printf("a7 : %08x\n", frame->a7);
|
||||
ets_printf("a8 : %08x\t", frame->a8);
|
||||
ets_printf("a9 : %08x\t", frame->a9);
|
||||
ets_printf("a10 : %08x\t", frame->a10);
|
||||
ets_printf("a11 : %08x\n", frame->a11);
|
||||
ets_printf("a12 : %08x\t", frame->a12);
|
||||
ets_printf("a13 : %08x\t", frame->a13);
|
||||
ets_printf("a14 : %08x\t", frame->a14);
|
||||
ets_printf("a15 : %08x\n", frame->a15);
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
ets_printf("lbeg : %08x\t", frame->lbeg);
|
||||
ets_printf("lend : %08x\t", frame->lend);
|
||||
ets_printf("lcount : %08x\n", frame->lcount);
|
||||
#endif /* XCHAL_HAVE_LOOPS */
|
||||
#endif /* DEVELHELP */
|
||||
|
||||
/* restart */
|
||||
/* TODO: Improvement
|
||||
Normally, we should try to restart the system. However, this
|
||||
will not work after some exceptions, e.g., the LoadStoreErrorCause.
|
||||
One option is to break the execution and wait for the WDT reset. Maybe
|
||||
there is better way. If debugger is active, 'break 0,0' stops the
|
||||
execution in debugger. */
|
||||
/* __asm__ volatile ("break 0,0"); */
|
||||
/* hard reset */
|
||||
__asm__ volatile (" call0 0x40000080 ");
|
||||
|
||||
@ -118,9 +175,7 @@ void init_exceptions (void)
|
||||
void IRAM NORETURN panic_arch(void)
|
||||
{
|
||||
#if defined(DEVELHELP)
|
||||
print_meminfo();
|
||||
ets_printf(" \n");
|
||||
ets_printf(" \n");
|
||||
heap_stats();
|
||||
#endif
|
||||
|
||||
/* hard reset */
|
||||
@ -128,3 +183,10 @@ void IRAM NORETURN panic_arch(void)
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void _panic_handler(uint32_t addr)
|
||||
{
|
||||
ets_printf("#! _xt_panic called from 0x%08x: powering off\n", addr);
|
||||
pm_off();
|
||||
while (1) { };
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
MODULE=esp
|
||||
MODULE=esp_freertos
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
58
cpu/esp8266/freertos/event_groups.c
Normal file
58
cpu/esp8266/freertos/event_groups.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
EventGroupHandle_t xEventGroupCreate (void)
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vEventGroupDelete (EventGroupHandle_t xEventGroup)
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
}
|
||||
|
||||
EventBits_t xEventGroupSetBits (EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet)
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EventBits_t xEventGroupClearBits (EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear )
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EventBits_t xEventGroupWaitBits (const EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait)
|
||||
{
|
||||
printf("%s is not supported\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
75
cpu/esp8266/freertos/portable.c
Normal file
75
cpu/esp8266/freertos/portable.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "log.h"
|
||||
#ifdef MCU_ESP8266
|
||||
#include "esp_attr.h"
|
||||
#include "irq.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
uint32_t xPortGetTickRateHz(void) {
|
||||
return MSEC_PER_SEC / portTICK_PERIOD_MS;
|
||||
}
|
||||
|
||||
BaseType_t xPortInIsrContext(void)
|
||||
{
|
||||
/* is working on single core in that way */
|
||||
return irq_is_in();
|
||||
}
|
||||
|
||||
#ifdef MCU_ESP8266
|
||||
|
||||
unsigned _xt_tick_divisor = 0; /* cached number of cycles per tick */
|
||||
|
||||
extern void vTaskEnterCritical( portMUX_TYPE *mux );
|
||||
extern void vTaskExitCritical( portMUX_TYPE *mux );
|
||||
|
||||
void vPortEnterCritical(void)
|
||||
{
|
||||
vTaskEnterCritical(0);
|
||||
}
|
||||
|
||||
extern void vPortExitCritical(void)
|
||||
{
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
|
||||
/* source: /path/to/esp8266-rtos-sdk/components/freertos/port/esp8266/port.c */
|
||||
void IRAM_ATTR vPortETSIntrLock(void)
|
||||
{
|
||||
ETS_INTR_LOCK();
|
||||
}
|
||||
|
||||
/* source: /path/to/esp8266-rtos-sdk/components/freertos/port/esp8266/port.c */
|
||||
void IRAM_ATTR vPortETSIntrUnlock(void)
|
||||
{
|
||||
ETS_INTR_UNLOCK();
|
||||
}
|
||||
|
||||
/* source: /path/to/esp8266-rtos-sdk/components/freertos/port/esp8266/port.c */
|
||||
void ResetCcountVal(unsigned int cnt_val)
|
||||
{
|
||||
asm volatile("wsr a2, ccount");
|
||||
}
|
||||
|
||||
#endif /* MCU_ESP8266 */
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
394
cpu/esp8266/freertos/queue.c
Normal file
394
cpu/esp8266/freertos/queue.c
Normal file
@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "esp_attr.h"
|
||||
#include "irq_arch.h"
|
||||
#include "log.h"
|
||||
#include "mutex.h"
|
||||
#include "rmutex.h"
|
||||
#include "syscalls.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
/*
|
||||
* In FreeRTOS different types of semaphores, mutexes and queues are all
|
||||
* mapped to a single generic queue type. With all these different types,
|
||||
* single functions for send, receive, give and take are then used. To be
|
||||
* able to dsitinguish between these different types in RIOT, we need typed
|
||||
* objects.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t type; /* type of the queue, MUST be the first element */
|
||||
list_node_t sending; /* threads that are waiting to send */
|
||||
list_node_t receiving; /* threads that are waiting to receive */
|
||||
uint8_t* queue; /* the queue of waiting items */
|
||||
uint32_t item_size; /* size of each item in the queue */
|
||||
uint32_t item_num; /* num of items that can be stored in queue */
|
||||
uint32_t item_front; /* first item in queue */
|
||||
uint32_t item_tail; /* last item in queue */
|
||||
uint32_t item_level; /* num of items stored in queue */
|
||||
} _queue_t;
|
||||
|
||||
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength,
|
||||
const UBaseType_t uxItemSize,
|
||||
const uint8_t ucQueueType )
|
||||
{
|
||||
DEBUG("%s pid=%d len=%u size=%u type=%u ", __func__,
|
||||
thread_getpid(), uxQueueLength, uxItemSize, ucQueueType);
|
||||
|
||||
uint32_t queue_size = uxQueueLength * uxItemSize;
|
||||
_queue_t* queue = malloc(sizeof(_queue_t) + queue_size);
|
||||
|
||||
if (!queue) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
queue->type = ucQueueType;
|
||||
queue->receiving.next = NULL;
|
||||
queue->sending.next = NULL;
|
||||
queue->queue = (queue_size) ? (uint8_t*)queue + sizeof(_queue_t) : NULL;
|
||||
queue->item_num = uxQueueLength;
|
||||
queue->item_size = uxItemSize;
|
||||
queue->item_front = 0;
|
||||
queue->item_tail = 0;
|
||||
queue->item_level = 0;
|
||||
|
||||
DEBUG("queue=%p\n", queue);
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 )
|
||||
|
||||
QueueHandle_t xQueueCreateCountingSemaphore (const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount)
|
||||
{
|
||||
_queue_t* queue;
|
||||
|
||||
assert(uxMaxCount != 0);
|
||||
assert(uxInitialCount <= uxMaxCount);
|
||||
|
||||
queue = xQueueGenericCreate(uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH,
|
||||
queueQUEUE_TYPE_COUNTING_SEMAPHORE);
|
||||
|
||||
DEBUG("%s pid=%d queue=%p\n", __func__, thread_getpid(), queue);
|
||||
|
||||
if (queue != NULL) {
|
||||
queue->item_level = uxInitialCount;
|
||||
queue->item_tail = (queue->item_front + queue->item_level) % queue->item_num;
|
||||
}
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
void vQueueDelete( QueueHandle_t xQueue )
|
||||
{
|
||||
DEBUG("%s pid=%d queue=%p\n", __func__, thread_getpid(), xQueue);
|
||||
|
||||
assert(xQueue != NULL);
|
||||
free(xQueue);
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR _queue_generic_send(QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
const BaseType_t xCopyPosition,
|
||||
TickType_t xTicksToWait,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p pos=%d wait=%u woken=%p isr=%d\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xCopyPosition, xTicksToWait, pxHigherPriorityTaskWoken,
|
||||
irq_is_in());
|
||||
|
||||
assert(xQueue != NULL);
|
||||
|
||||
_queue_t* queue = (_queue_t*)xQueue;
|
||||
|
||||
while (1) {
|
||||
vTaskEnterCritical(0);
|
||||
|
||||
/* is there still space in the queue */
|
||||
if (queue->item_level < queue->item_num || xCopyPosition == queueOVERWRITE) {
|
||||
uint32_t write_pos;
|
||||
/* determine the write position in the queue and update positions */
|
||||
if (xCopyPosition == queueSEND_TO_BACK) {
|
||||
write_pos = queue->item_tail;
|
||||
queue->item_tail = (queue->item_tail + 1) % queue->item_num;
|
||||
queue->item_level++;
|
||||
}
|
||||
else if (xCopyPosition == queueSEND_TO_FRONT) {
|
||||
queue->item_front = (queue->item_front - 1) % queue->item_num;
|
||||
queue->item_level++;
|
||||
write_pos = queue->item_front;
|
||||
}
|
||||
else { /* queueOVERWRITE */
|
||||
write_pos = queue->item_front;
|
||||
if (queue->item_level == 0) {
|
||||
queue->item_level++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the item has no 0 size, copy it to the according place in queue */
|
||||
if (queue->item_size && queue->queue && pvItemToQueue) {
|
||||
memcpy(queue->queue + write_pos * queue->item_size,
|
||||
pvItemToQueue, queue->item_size);
|
||||
}
|
||||
|
||||
/* indicates a required context switch */
|
||||
bool ctx_switch = false;
|
||||
|
||||
/* unlock waiting receiving thread */
|
||||
if (queue->receiving.next != NULL) {
|
||||
list_node_t *next = list_remove_head(&queue->receiving);
|
||||
thread_t *proc = container_of((clist_node_t*)next, thread_t, rq_entry);
|
||||
sched_set_status(proc, STATUS_PENDING);
|
||||
ctx_switch = proc->priority < sched_threads[thread_getpid()]->priority;
|
||||
|
||||
DEBUG("%s pid=%d queue=%p unlock waiting pid=%d switch=%d\n",
|
||||
__func__, thread_getpid(), xQueue, proc->pid, ctx_switch);
|
||||
}
|
||||
|
||||
if (ctx_switch && pxHigherPriorityTaskWoken) {
|
||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
else if (ctx_switch) {
|
||||
vTaskExitCritical(0);
|
||||
/* sets only the sched_context_switch_request in ISRs */
|
||||
thread_yield_higher();
|
||||
}
|
||||
else {
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
|
||||
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
|
||||
/* in all cases vTaskExitCritical has been called already */
|
||||
return pdPASS;
|
||||
}
|
||||
else if (xTicksToWait == 0 || irq_is_in()) {
|
||||
/* if there was no space and timeout = 0, return with error */
|
||||
DEBUG("%s pid=%d queue=%p return errQUEUE_FULL\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
return errQUEUE_FULL;
|
||||
}
|
||||
else {
|
||||
/* suspend the calling thread to wait for space in the queue */
|
||||
thread_t *me = (thread_t*)sched_active_thread;
|
||||
sched_set_status(me, STATUS_SEND_BLOCKED);
|
||||
/* waiting list is sorted by priority */
|
||||
thread_add_to_list(&queue->sending, me);
|
||||
|
||||
DEBUG("%s pid=%d queue=%p suspended calling thread\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
thread_yield_higher();
|
||||
|
||||
/* TODO timeout handling with xTicksToWait */
|
||||
DEBUG("%s pid=%d queue=%p continue calling thread\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
}
|
||||
/* in all cases vTaskExitCritical has been called already */
|
||||
}
|
||||
return errQUEUE_FULL;
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR _queue_generic_recv (QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xJustPeeking,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p wait=%u peek=%u woken=%p isr=%d\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xTicksToWait, xJustPeeking, pxHigherPriorityTaskWoken,
|
||||
irq_is_in());
|
||||
|
||||
assert(xQueue != NULL);
|
||||
|
||||
_queue_t* queue = (_queue_t*)xQueue;
|
||||
|
||||
while (1) {
|
||||
vTaskEnterCritical(0);
|
||||
|
||||
/* if there is at least one item in the queue */
|
||||
if (queue->item_level > 0) {
|
||||
/* if the item has no 0 size, copy it from queue to buffer */
|
||||
if (queue->item_size && queue->item_num && queue->queue && pvBuffer) {
|
||||
memcpy(pvBuffer,
|
||||
queue->queue + queue->item_front * queue->item_size,
|
||||
queue->item_size);
|
||||
}
|
||||
|
||||
|
||||
/* when only peeking leave the element in queue */
|
||||
if (xJustPeeking == pdTRUE) {
|
||||
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
return pdPASS;
|
||||
}
|
||||
|
||||
/* remove element from queue */
|
||||
queue->item_front = (queue->item_front + 1) % queue->item_num;
|
||||
queue->item_level--;
|
||||
|
||||
/* return if there is no waiting sending thread */
|
||||
if (queue->sending.next == NULL) {
|
||||
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
return pdPASS;
|
||||
}
|
||||
|
||||
/* otherwise unlock the waiting sending thread */
|
||||
list_node_t *next = list_remove_head(&queue->sending);
|
||||
thread_t *proc = container_of((clist_node_t*)next, thread_t, rq_entry);
|
||||
sched_set_status(proc, STATUS_PENDING);
|
||||
|
||||
/* test whether context switch is required */
|
||||
bool ctx_switch = proc->priority < sched_threads[thread_getpid()]->priority;
|
||||
|
||||
DEBUG("%s pid=%d queue=%p unlock waiting pid=%d switch=%d\n",
|
||||
__func__, thread_getpid(), xQueue, proc->pid, ctx_switch);
|
||||
|
||||
if (ctx_switch && pxHigherPriorityTaskWoken) {
|
||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
else if (ctx_switch) {
|
||||
vTaskExitCritical(0);
|
||||
/* sets only the sched_context_switch_request in ISRs */
|
||||
sched_switch(proc->priority);
|
||||
}
|
||||
else {
|
||||
vTaskExitCritical(0);
|
||||
}
|
||||
|
||||
DEBUG("%s pid=%d queue=%p return pdPASS\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
|
||||
/* in all cases vTaskExitCritical has been called already */
|
||||
return pdPASS;
|
||||
}
|
||||
else if (xTicksToWait == 0 || irq_is_in()) {
|
||||
/* if there was no item in the queue and timeout is 0, return with error */
|
||||
DEBUG("%s pid=%d queue=%p return errQUEUE_EMPTY\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
vTaskExitCritical(0);
|
||||
return errQUEUE_EMPTY;
|
||||
}
|
||||
else {
|
||||
/* suspend the calling thread to wait for an item in the queue */
|
||||
thread_t *me = (thread_t*)sched_active_thread;
|
||||
sched_set_status(me, STATUS_RECEIVE_BLOCKED);
|
||||
/* waiting list is sorted by priority */
|
||||
thread_add_to_list(&queue->receiving, me);
|
||||
|
||||
DEBUG("%s pid=%d queue=%p suspended calling thread\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
|
||||
vTaskExitCritical(0);
|
||||
thread_yield_higher();
|
||||
|
||||
/* TODO timeout handling with xTicksToWait */
|
||||
DEBUG("%s pid=%d queue=%p continue calling thread\n", __func__,
|
||||
thread_getpid(), xQueue);
|
||||
}
|
||||
/* in all cases vTaskExitCritical has been called already */
|
||||
}
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR xQueueGenericSend( QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xCopyPosition )
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p wait=%u pos=%d\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xTicksToWait, xCopyPosition);
|
||||
|
||||
return _queue_generic_send(xQueue, pvItemToQueue, xCopyPosition,
|
||||
xTicksToWait, NULL);
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR xQueueGenericSendFromISR( QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
const BaseType_t xCopyPosition )
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p pos=%d woken=%p\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xCopyPosition, pxHigherPriorityTaskWoken);
|
||||
|
||||
return _queue_generic_send(xQueue, pvItemToQueue, xCopyPosition,
|
||||
0, pxHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR xQueueGenericReceive (QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xJustPeeking)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p wait=%u peek=%d\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, xTicksToWait, xJustPeeking);
|
||||
|
||||
return _queue_generic_recv(xQueue, pvBuffer, xTicksToWait,
|
||||
xJustPeeking, NULL);
|
||||
}
|
||||
|
||||
BaseType_t IRAM_ATTR xQueueReceiveFromISR (QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d queue=%p woken=%p\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority,
|
||||
xQueue, pxHigherPriorityTaskWoken);
|
||||
|
||||
return _queue_generic_recv(xQueue, pvBuffer, 0,
|
||||
0, pxHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue )
|
||||
{
|
||||
assert(xQueue != NULL);
|
||||
|
||||
_queue_t* queue = (_queue_t*)xQueue;
|
||||
return queue->item_level;
|
||||
}
|
||||
|
||||
BaseType_t xQueueGiveFromISR (QueueHandle_t xQueue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken)
|
||||
{
|
||||
/* this function only satisfies the linker and should not be called */
|
||||
assert(0);
|
||||
|
||||
DEBUG("%s\n", __func__);
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
176
cpu/esp8266/freertos/semphr.c
Normal file
176
cpu/esp8266/freertos/semphr.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "irq_arch.h"
|
||||
#include "log.h"
|
||||
#include "mutex.h"
|
||||
#include "rmutex.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
/*
|
||||
* In FreeRTOS different types of semaphores, mutexes and queues are all
|
||||
* mapped to a single generic queue type. With all these different types,
|
||||
* single functions for send, receive, give and take are then used. To be
|
||||
* able to dsitinguish between these different types in RIOT, we need typed
|
||||
* objects.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t type; /* type of the mutex, MUST be the first element */
|
||||
mutex_t mutex; /* the mutex */
|
||||
} _mutex_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type; /* type of the mutex, MUST be the first element */
|
||||
rmutex_t rmutex; /* the mutex */
|
||||
} _rmutex_t;
|
||||
|
||||
SemaphoreHandle_t xSemaphoreCreateMutex(void)
|
||||
{
|
||||
_mutex_t* _tmp = (_mutex_t*)malloc (sizeof(_mutex_t));
|
||||
_tmp->type = queueQUEUE_TYPE_MUTEX;
|
||||
mutex_init(&_tmp->mutex);
|
||||
|
||||
DEBUG("%s mutex=%p\n", __func__, _tmp);
|
||||
return _tmp;
|
||||
}
|
||||
|
||||
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )
|
||||
{
|
||||
DEBUG("%s mutex=%p\n", __func__, xSemaphore);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
free(xSemaphore);
|
||||
}
|
||||
|
||||
BaseType_t xSemaphoreGive (SemaphoreHandle_t xSemaphore)
|
||||
{
|
||||
DEBUG("%s mutex=%p\n", __func__, xSemaphore);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
|
||||
uint8_t type = ((_mutex_t*)xSemaphore)->type;
|
||||
mutex_t* mutex= &((_mutex_t*)xSemaphore)->mutex;
|
||||
|
||||
switch (type) {
|
||||
case queueQUEUE_TYPE_MUTEX:
|
||||
mutex_unlock(mutex);
|
||||
break;
|
||||
case queueQUEUE_TYPE_RECURSIVE_MUTEX:
|
||||
return xSemaphoreGiveRecursive (xSemaphore);
|
||||
default:
|
||||
return xQueueGenericSend(xSemaphore, NULL, 0, queueSEND_TO_BACK);
|
||||
}
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xSemaphoreTake (SemaphoreHandle_t xSemaphore,
|
||||
TickType_t xTicksToWait)
|
||||
{
|
||||
DEBUG("%s mutex=%p wait=%u\n", __func__, xSemaphore, xTicksToWait);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
|
||||
uint8_t type = ((_mutex_t*)xSemaphore)->type;
|
||||
mutex_t* mutex= &((_mutex_t*)xSemaphore)->mutex;
|
||||
|
||||
switch (type) {
|
||||
case queueQUEUE_TYPE_MUTEX:
|
||||
{
|
||||
if (xTicksToWait == 0) {
|
||||
return (mutex_trylock(mutex) == 1) ? pdPASS : pdFAIL;
|
||||
}
|
||||
else {
|
||||
mutex_lock(mutex);
|
||||
/* TODO timeout handling */
|
||||
return pdTRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case queueQUEUE_TYPE_RECURSIVE_MUTEX:
|
||||
return xSemaphoreTakeRecursive (xSemaphore, xTicksToWait);
|
||||
|
||||
default:
|
||||
return xQueueGenericReceive(xSemaphore, NULL, xTicksToWait, pdFALSE);
|
||||
}
|
||||
}
|
||||
|
||||
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void)
|
||||
{
|
||||
_rmutex_t* _tmp = (_rmutex_t*)malloc (sizeof(_rmutex_t));
|
||||
_tmp->type = queueQUEUE_TYPE_RECURSIVE_MUTEX;
|
||||
rmutex_init(&_tmp->rmutex);
|
||||
|
||||
DEBUG("%s rmutex=%p\n", __func__, _tmp);
|
||||
|
||||
return _tmp;
|
||||
}
|
||||
|
||||
BaseType_t xSemaphoreGiveRecursive (SemaphoreHandle_t xSemaphore)
|
||||
{
|
||||
DEBUG("%s rmutex=%p\n", __func__, xSemaphore);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
assert(((_rmutex_t*)xSemaphore)->type == queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
|
||||
rmutex_unlock(&((_rmutex_t*)xSemaphore)->rmutex);
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xSemaphoreTakeRecursive (SemaphoreHandle_t xSemaphore,
|
||||
TickType_t xTicksToWait)
|
||||
{
|
||||
DEBUG("%s rmutex=%p wait=%u\n", __func__, xSemaphore, xTicksToWait);
|
||||
|
||||
assert(xSemaphore != NULL);
|
||||
assert(((_rmutex_t*)xSemaphore)->type == queueQUEUE_TYPE_RECURSIVE_MUTEX);
|
||||
|
||||
BaseType_t ret = pdTRUE;
|
||||
rmutex_t* rmutex = &((_rmutex_t*)xSemaphore)->rmutex;
|
||||
|
||||
if (xTicksToWait == 0) {
|
||||
ret = (rmutex_trylock(rmutex) == 1) ? pdPASS : pdFAIL;
|
||||
}
|
||||
else {
|
||||
rmutex_lock(&((_rmutex_t*)xSemaphore)->rmutex);
|
||||
/* TODO timeout handling */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void vPortCPUAcquireMutex(portMUX_TYPE *mux)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d mux=%p\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority, mux);
|
||||
critical_enter();
|
||||
mutex_lock(mux); /* lock the mutex with interrupts disabled */
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
void vPortCPUReleaseMutex(portMUX_TYPE *mux)
|
||||
{
|
||||
DEBUG("%s pid=%d prio=%d mux=%p\n", __func__,
|
||||
thread_getpid(), sched_threads[thread_getpid()]->priority, mux);
|
||||
critical_enter();
|
||||
mutex_unlock(mux); /* unlock the mutex with interrupts disabled */
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
226
cpu/esp8266/freertos/task.c
Normal file
226
cpu/esp8266/freertos/task.c
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "esp_attr.h"
|
||||
#include "log.h"
|
||||
#include "syscalls.h"
|
||||
#include "thread.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
#include "soc/soc.h"
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#define MHZ 1000000
|
||||
|
||||
#ifdef MCU_ESP8266
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#define PRO_CPU_NUM (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Architecture specific data of thread control blocks
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t saved_int_state;
|
||||
uint32_t critical_nesting;
|
||||
} thread_arch_ext_t;
|
||||
|
||||
volatile thread_arch_ext_t threads_arch_exts[KERNEL_PID_LAST + 1] = {};
|
||||
|
||||
BaseType_t xTaskCreatePinnedToCore (TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask,
|
||||
const BaseType_t xCoreID)
|
||||
{
|
||||
/* FreeRTOS priority values have to be inverted */
|
||||
uxPriority = SCHED_PRIO_LEVELS - uxPriority - 1;
|
||||
|
||||
DEBUG("%s name=%s size=%d prio=%d pvCreatedTask=%p ",
|
||||
__func__, pcName, usStackDepth, uxPriority, pvCreatedTask);
|
||||
|
||||
char* stack = malloc(usStackDepth + sizeof(thread_t));
|
||||
|
||||
if (!stack) {
|
||||
LOG_TAG_ERROR("freertos", "not enough memory to create task %s with "
|
||||
"stack size of %d bytes\n", pcName, usStackDepth);
|
||||
abort();
|
||||
return pdFALSE;
|
||||
}
|
||||
kernel_pid_t pid = thread_create(stack,
|
||||
usStackDepth + sizeof(thread_t),
|
||||
uxPriority,
|
||||
THREAD_CREATE_WOUT_YIELD |
|
||||
THREAD_CREATE_STACKTEST,
|
||||
(thread_task_func_t)pvTaskCode,
|
||||
pvParameters, pcName);
|
||||
DEBUG("pid=%d\n", pid);
|
||||
|
||||
if (pvCreatedTask) {
|
||||
*pvCreatedTask = (TaskHandle_t)(0L + pid);
|
||||
}
|
||||
|
||||
return (pid < 0) ? pdFALSE : pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xTaskCreate (TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask)
|
||||
{
|
||||
return xTaskCreatePinnedToCore (pvTaskCode,
|
||||
pcName,
|
||||
usStackDepth,
|
||||
pvParameters,
|
||||
uxPriority,
|
||||
pvCreatedTask,
|
||||
PRO_CPU_NUM);
|
||||
}
|
||||
|
||||
void vTaskDelete (TaskHandle_t xTaskToDelete)
|
||||
{
|
||||
DEBUG("%s pid=%d task=%p\n", __func__, thread_getpid(), xTaskToDelete);
|
||||
|
||||
assert(xTaskToDelete != NULL);
|
||||
|
||||
uint32_t pid = (uint32_t)xTaskToDelete;
|
||||
|
||||
/* remove old task from scheduling */
|
||||
thread_t* thread = (thread_t*)sched_threads[pid];
|
||||
sched_set_status(thread, STATUS_STOPPED);
|
||||
sched_threads[pid] = NULL;
|
||||
sched_num_threads--;
|
||||
sched_active_thread = NULL;
|
||||
|
||||
/* determine the new running task */
|
||||
sched_run();
|
||||
}
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandle(void)
|
||||
{
|
||||
DEBUG("%s pid=%d\n", __func__, thread_getpid());
|
||||
|
||||
uint32_t pid = thread_getpid();
|
||||
return (TaskHandle_t)pid;
|
||||
}
|
||||
|
||||
void vTaskDelay( const TickType_t xTicksToDelay )
|
||||
{
|
||||
DEBUG("%s xTicksToDelay=%d\n", __func__, xTicksToDelay);
|
||||
#if defined(MCU_ESP8266) && defined(MODULE_ESP_WIFI_ANY)
|
||||
uint64_t us = xTicksToDelay * MHZ / xPortGetTickRateHz();
|
||||
xtimer_usleep(us);
|
||||
#endif
|
||||
}
|
||||
|
||||
TickType_t xTaskGetTickCount (void)
|
||||
{
|
||||
return system_get_time() / USEC_PER_MSEC / portTICK_PERIOD_MS;
|
||||
}
|
||||
|
||||
void vTaskEnterCritical( portMUX_TYPE *mux )
|
||||
{
|
||||
#ifdef MCU_ESP8266
|
||||
/* we have to return on NMI */
|
||||
if (NMIIrqIsOn) {
|
||||
return;
|
||||
}
|
||||
#endif /* MCU_ESP8266 */
|
||||
|
||||
/* disable interrupts */
|
||||
uint32_t state = irq_disable();
|
||||
|
||||
/* determine calling thread pid (can't fail) */
|
||||
kernel_pid_t my_pid = thread_getpid();
|
||||
|
||||
DEBUG("%s pid=%d prio=%d mux=%p\n", __func__,
|
||||
my_pid, sched_threads[my_pid]->priority, mux);
|
||||
|
||||
/* acquire the mutex with interrupts disabled */
|
||||
if (mux) {
|
||||
mutex_lock(mux); /* TODO should be only a spin lock */
|
||||
}
|
||||
|
||||
/* increment nesting counter and save old interrupt level */
|
||||
threads_arch_exts[my_pid].critical_nesting++;
|
||||
if (threads_arch_exts[my_pid].critical_nesting == 1) {
|
||||
threads_arch_exts[my_pid].saved_int_state = state;
|
||||
}
|
||||
}
|
||||
|
||||
void vTaskExitCritical( portMUX_TYPE *mux )
|
||||
{
|
||||
#ifdef MCU_ESP8266
|
||||
/* we have to return on NMI */
|
||||
if (NMIIrqIsOn) {
|
||||
return;
|
||||
}
|
||||
#endif /* MCU_ESP8266 */
|
||||
|
||||
/* determine calling thread pid (can't fail) */
|
||||
kernel_pid_t my_pid = thread_getpid();
|
||||
|
||||
DEBUG("%s pid=%d prio=%d mux=%p\n", __func__,
|
||||
my_pid, sched_threads[my_pid]->priority, mux);
|
||||
|
||||
/* release the mutex with interrupts disabled */
|
||||
if (mux) {
|
||||
mutex_unlock(mux); /* TODO should be only a spin lock */
|
||||
}
|
||||
|
||||
/* decrement nesting counter and restore old interrupt level */
|
||||
if (threads_arch_exts[my_pid].critical_nesting) {
|
||||
threads_arch_exts[my_pid].critical_nesting--;
|
||||
if (threads_arch_exts[my_pid].critical_nesting == 0) {
|
||||
irq_restore(threads_arch_exts[my_pid].saved_int_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vTaskStepTick(const TickType_t xTicksToJump)
|
||||
{
|
||||
DEBUG("%s xTicksToJump=%d\n", __func__, xTicksToJump);
|
||||
/*
|
||||
* TODO:
|
||||
* At the moment, only the calling task is set to sleep state. Usually, the
|
||||
* complete system should sleep but not only the task.
|
||||
*/
|
||||
vTaskDelay(xTicksToJump);
|
||||
}
|
||||
|
||||
TickType_t prvGetExpectedIdleTime(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
/*
|
||||
* TODO:
|
||||
* Since we are not able to estimate the time the system will be idle,
|
||||
* we simply return 0.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
129
cpu/esp8266/freertos/timers.c
Normal file
129
cpu/esp8266/freertos/timers.c
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "esp_attr.h"
|
||||
#include "log.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/timers.h"
|
||||
|
||||
typedef struct {
|
||||
xtimer_t xtimer; /* xtimer object */
|
||||
const char* name; /* FreeRTOS timer name */
|
||||
uint32_t period; /* in us */
|
||||
bool autoreload; /* FreeRTOS timer reload indicator */
|
||||
const void* timerid; /* FreeRTOS timer id */
|
||||
TimerCallbackFunction_t cb; /* FreeRTOS callback function */
|
||||
} freertos_xtimer_t;
|
||||
|
||||
static void IRAM_ATTR _xtimer_callback (void *arg)
|
||||
{
|
||||
assert(arg != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)arg;
|
||||
|
||||
if (timer->autoreload) {
|
||||
xtimer_set(&timer->xtimer, timer->period);
|
||||
}
|
||||
|
||||
if (timer->cb) {
|
||||
timer->cb(arg);
|
||||
}
|
||||
}
|
||||
|
||||
TimerHandle_t xTimerCreate (const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriod,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction)
|
||||
{
|
||||
freertos_xtimer_t* timer = malloc(sizeof(freertos_xtimer_t));
|
||||
if (timer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FreeRTOS timer parameter */
|
||||
timer->name = pcTimerName;
|
||||
timer->period = xTimerPeriod * portTICK_PERIOD_MS * USEC_PER_MSEC;
|
||||
timer->autoreload = uxAutoReload;
|
||||
timer->timerid = pvTimerID;
|
||||
timer->cb = pxCallbackFunction;
|
||||
|
||||
/* xtimer parameter */
|
||||
timer->xtimer.callback = _xtimer_callback;
|
||||
timer->xtimer.arg = timer;
|
||||
|
||||
DEBUG("%s %p %s %d %u\n", __func__, timer, pcTimerName, xTimerPeriod, uxAutoReload);
|
||||
return timer;
|
||||
}
|
||||
|
||||
BaseType_t xTimerDelete(TimerHandle_t xTimer, TickType_t xBlockTime)
|
||||
{
|
||||
DEBUG("%s %p %d\n", __func__, xTimer, xBlockTime);
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
xtimer_remove(&timer->xtimer);
|
||||
free(timer);
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xTimerStart (TimerHandle_t xTimer, TickType_t xBlockTime)
|
||||
{
|
||||
DEBUG("%s %p %d\n", __func__, xTimer, xBlockTime);
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
xtimer_set(&timer->xtimer, timer->period);
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xTimerStop (TimerHandle_t xTimer, TickType_t xBlockTime)
|
||||
{
|
||||
DEBUG("%s %p %d\n", __func__, xTimer, xBlockTime);
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
xtimer_remove(&timer->xtimer);
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
BaseType_t xTimerReset (TimerHandle_t xTimer, TickType_t xBlockTime)
|
||||
{
|
||||
DEBUG("%s %p %d\n", __func__, xTimer, xBlockTime);
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
xtimer_set(&timer->xtimer, xBlockTime * portTICK_PERIOD_MS * USEC_PER_MSEC);
|
||||
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
void *pvTimerGetTimerID(const TimerHandle_t xTimer)
|
||||
{
|
||||
assert(xTimer != NULL);
|
||||
|
||||
freertos_xtimer_t* timer = (freertos_xtimer_t*)xTimer;
|
||||
return (void*)timer->timerid;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Common helper macros
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** string representation of x */
|
||||
#ifndef XTSTR
|
||||
#define _XTSTR(x) # x
|
||||
#define XTSTR(x) _XTSTR(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(ICACHE_FLASH) || defined (DOXYGEN)
|
||||
|
||||
#ifndef ICACHE_RAM_ATTR
|
||||
/** Places the code with this attribute in the IRAM. */
|
||||
#define ICACHE_RAM_ATTR __attribute__((section(".iram.text")))
|
||||
#endif
|
||||
#else
|
||||
#ifndef ICACHE_RAM_ATTR
|
||||
#define ICACHE_RAM_ATTR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Print out a message that function is not yet implementd */
|
||||
#define NOT_YET_IMPLEMENTED() LOG_INFO("%s not yet implemented\n", __func__)
|
||||
/** Print out a message that function is not supported */
|
||||
#define NOT_SUPPORTED() LOG_INFO("%s not supported\n", __func__)
|
||||
|
||||
|
||||
#if defined(ENABLE_DEBUG) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Parameter check with return a value.
|
||||
*
|
||||
* If ENABLE_DEBUG is true, the macro checks a condition and returns with a value
|
||||
* if the condition is not fulfilled.
|
||||
* @param cond the condition
|
||||
* @param err the return value in the case the condition is not fulfilled.
|
||||
*/
|
||||
#define CHECK_PARAM_RET(cond,err) if (!(cond)) \
|
||||
{ \
|
||||
DEBUG("%s\n", "parameter condition (" #cond ") not fulfilled"); \
|
||||
return err; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parameter check without return value.
|
||||
*
|
||||
* If ENABLE_DEBUG is true, the macro checks a condition and returns without a
|
||||
* value if the condition is not fulfilled.
|
||||
* @param cond the condition
|
||||
*/
|
||||
#define CHECK_PARAM(cond) if (!(cond)) \
|
||||
{ \
|
||||
DEBUG("%s\n", "parameter condition (" #cond ") not fulfilled"); \
|
||||
return; \
|
||||
}
|
||||
#else
|
||||
#define CHECK_PARAM_RET(cond,err) if (!(cond)) return err;
|
||||
#define CHECK_PARAM(cond) if (!(cond)) return;
|
||||
#endif
|
||||
|
||||
|
||||
#define LOG_TAG_ERROR(tag, fmt, ...) LOG_ERROR("[%s] " fmt, tag, ##__VA_ARGS__)
|
||||
#define LOG_TAG_WARNING(tag, fmt, ...) LOG_WARNING("[%s] " fmt, tag, ##__VA_ARGS__)
|
||||
#define LOG_TAG_INFO(tag, fmt, ...) LOG_INFO("[%s] " fmt, tag, ##__VA_ARGS__)
|
||||
#define LOG_TAG_DEBUG(tag, fmt, ...) LOG_DEBUG("[%s] " fmt, tag, ##__VA_ARGS__)
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* COMMON_H */
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -29,7 +29,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Stack size configuration
|
||||
* @brief Defines the CPU frequency in MHz
|
||||
*
|
||||
* Possible values are 80 and 160 MHz.
|
||||
*/
|
||||
#ifndef ESP8266_CPU_FREQUENCY
|
||||
#define ESP8266_CPU_FREQUENCY (80)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Stack size configurations
|
||||
* @{
|
||||
*/
|
||||
#ifndef THREAD_EXTRA_STACKSIZE_PRINTF
|
||||
@ -49,16 +58,12 @@ extern "C" {
|
||||
#define GNRC_IPV6_STACK_SIZE (1536)
|
||||
#endif
|
||||
#ifndef GNRC_PKTDUMP_STACKSIZE
|
||||
#define GNRC_PKTDUMP_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
|
||||
#define GNRC_PKTDUMP_STACKSIZE (THREAD_STACKSIZE_DEFAULT << 1)
|
||||
#endif
|
||||
|
||||
#ifndef ESP_NOW_STACKSIZE
|
||||
#define ESP_NOW_STACKSIZE (2560)
|
||||
#endif
|
||||
|
||||
#ifndef ETS_THREAD_STACKSIZE
|
||||
#define ETS_THREAD_STACKSIZE (1536)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@ -66,16 +71,6 @@ extern "C" {
|
||||
*/
|
||||
#define PRINTF_BUFSIZ 256
|
||||
|
||||
/* Following include is neccessary to overwrite newlib's PRI*8 and PRI*32. */
|
||||
/* PLEASE NOTE: ets_vprintf does not understand %i %li, or %hi */
|
||||
#ifndef DOXYGEN
|
||||
#include <inttypes.h>
|
||||
#undef __INT8
|
||||
#define __INT8
|
||||
#undef __INT32
|
||||
#define __INT32
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
130
cpu/esp8266/include/esp_common.h
Normal file
130
cpu/esp8266/include/esp_common.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Common helper macros
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ESP_COMMON_H
|
||||
#define ESP_COMMON_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "esp_common_log.h"
|
||||
|
||||
#define asm __asm__
|
||||
|
||||
/** string representation of x */
|
||||
#ifndef XTSTR
|
||||
#define _XTSTR(x) # x
|
||||
#define XTSTR(x) _XTSTR(x)
|
||||
#endif /* XSTR */
|
||||
|
||||
#if !defined(ICACHE_FLASH)
|
||||
#ifndef ICACHE_RAM_ATTR
|
||||
/** Places the code with this attribute in the IRAM. */
|
||||
#define ICACHE_RAM_ATTR __attribute__((section(".iram0.text")))
|
||||
#endif
|
||||
#else /* ICACHE_FLASH */
|
||||
#ifndef ICACHE_RAM_ATTR
|
||||
#define ICACHE_RAM_ATTR
|
||||
#endif
|
||||
#endif /* ICACHE_FLASH */
|
||||
|
||||
/** Print out a message that function is not yet implementd */
|
||||
#define NOT_YET_IMPLEMENTED() LOG_INFO("%s not yet implemented\n", __func__)
|
||||
/** Print out a message that function is not supported */
|
||||
#define NOT_SUPPORTED() LOG_INFO("%s not supported\n", __func__)
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
/**
|
||||
* @brief Parameter check with return a value.
|
||||
*
|
||||
* If ENABLE_DEBUG is true, the macro checks a condition and returns with a value
|
||||
* if the condition is not fulfilled.
|
||||
* @param cond the condition
|
||||
* @param err the return value in the case the condition is not fulfilled.
|
||||
*/
|
||||
#define CHECK_PARAM_RET(cond,err) if (!(cond)) \
|
||||
{ \
|
||||
DEBUG("%s parameter condition (" #cond ") " \
|
||||
"not fulfilled\n", __func__); \
|
||||
return err; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parameter check without return value.
|
||||
*
|
||||
* If ENABLE_DEBUG is true, the macro checks a condition and returns without a
|
||||
* value if the condition is not fulfilled.
|
||||
* @param cond the condition
|
||||
*/
|
||||
#define CHECK_PARAM(cond) if (!(cond)) \
|
||||
{ \
|
||||
DEBUG("%s parameter condition (" #cond ") " \
|
||||
"not fulfilled\n", __func__); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#else /* ENABLE_DEBUG */
|
||||
|
||||
#define CHECK_PARAM_RET(cond,err) if (!(cond)) return err;
|
||||
#define CHECK_PARAM(cond) if (!(cond)) return;
|
||||
|
||||
#endif /* ENABLE_DEBUG */
|
||||
|
||||
/** gives the minimum of a and b */
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/** gives the maximum of a and b */
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief function name mappings for source code compatibility with ESP8266 port
|
||||
* @{
|
||||
*/
|
||||
#ifdef MCU_ESP32
|
||||
#define system_get_cpu_freq ets_get_cpu_frequency
|
||||
#define system_update_cpu_freq ets_update_cpu_frequency
|
||||
#endif /* MCU_ESP32 */
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** microseconds per millisecond */
|
||||
#ifndef USEC_PER_MSEC
|
||||
#define USEC_PER_MSEC 1000UL
|
||||
#endif
|
||||
|
||||
#ifndef MSEC_PER_SEC
|
||||
#define MSEC_PER_SEC 1000UL
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
|
||||
#endif /* ESP_COMMON_H */
|
||||
150
cpu/esp8266/include/esp_common_log.h
Normal file
150
cpu/esp8266/include/esp_common_log.h
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Common log macros
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ESP_COMMON_LOG_H
|
||||
#define ESP_COMMON_LOG_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
extern uint32_t system_get_time_ms (void);
|
||||
extern int ets_printf(const char *fmt, ...);
|
||||
|
||||
#if MODULE_ESP_LOG_COLORED
|
||||
|
||||
#define LOG_RESET_COLOR "\033[0m"
|
||||
#define LOG_COLOR_E "\033[1;31m"
|
||||
#define LOG_COLOR_W "\033[1;33m"
|
||||
#define LOG_COLOR_I "\033[1m"
|
||||
#define LOG_COLOR_D "\033[0;32m"
|
||||
#define LOG_COLOR_V
|
||||
|
||||
#else /* MODULE_ESP_LOG_COLORED */
|
||||
|
||||
#define LOG_RESET_COLOR
|
||||
#define LOG_COLOR_E
|
||||
#define LOG_COLOR_W
|
||||
#define LOG_COLOR_I
|
||||
#define LOG_COLOR_D
|
||||
#define LOG_COLOR_V
|
||||
|
||||
#endif /* MODULE_ESP_LOG_COLORED */
|
||||
|
||||
#if MODULE_ESP_LOG_TAGGED
|
||||
|
||||
#define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%d) [%s] " format LOG_RESET_COLOR
|
||||
|
||||
#define LOG_TAG(level, letter, tag, format, ...) \
|
||||
do { \
|
||||
if ((unsigned)level <= (unsigned)LOG_LEVEL) { \
|
||||
printf(LOG_FORMAT(letter, format), system_get_time_ms(), tag, ##__VA_ARGS__); \
|
||||
fflush(stdout); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define LOG_TAG_EARLY(level, letter, tag, format, ...) \
|
||||
do { \
|
||||
if (LOG_LEVEL >= level) { \
|
||||
ets_printf(LOG_FORMAT(letter, format), system_get_time_ms(), tag, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#else /* MODULE_ESP_LOG_TAGGED */
|
||||
|
||||
#define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter format LOG_RESET_COLOR
|
||||
|
||||
#define LOG_TAG(level, letter, tag, format, ...) \
|
||||
do { \
|
||||
(void)tag; \
|
||||
if ((unsigned)level <= (unsigned)LOG_LEVEL) { \
|
||||
printf(LOG_FORMAT(letter, format), ##__VA_ARGS__); \
|
||||
fflush(stdout); \
|
||||
} \
|
||||
} while (0U)
|
||||
|
||||
#define LOG_TAG_EARLY(level, letter, tag, format, ...) \
|
||||
do { \
|
||||
(void)tag; \
|
||||
if ((unsigned)level <= (unsigned)LOG_LEVEL) { \
|
||||
ets_printf(LOG_FORMAT(letter, format), ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0U)
|
||||
|
||||
#endif /* MODULE_ESP_LOG_TAGGED */
|
||||
|
||||
/**
|
||||
* Override LOG_* definitions with a tagged version. By default the function
|
||||
* name is used as tag.
|
||||
*/
|
||||
#ifndef MODULE_LOG_PRINTFNOFORMAT
|
||||
#undef LOG_ERROR
|
||||
#undef LOG_INFO
|
||||
#undef LOG_WARNING
|
||||
#undef LOG_DEBUG
|
||||
#define LOG_ERROR(format, ...) LOG_TAG(LOG_ERROR , E, __func__, format, ##__VA_ARGS__)
|
||||
#define LOG_WARNING(format, ...) LOG_TAG(LOG_WARNING, W, __func__, format, ##__VA_ARGS__)
|
||||
#define LOG_INFO(format, ...) LOG_TAG(LOG_INFO , I, __func__, format, ##__VA_ARGS__)
|
||||
#define LOG_DEBUG(format, ...) LOG_TAG(LOG_DEBUG , D, __func__, format, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/** Tagged LOG_* definitions */
|
||||
#define LOG_TAG_ERROR(tag, format, ...) LOG_TAG(LOG_ERROR , E, tag, format, ##__VA_ARGS__)
|
||||
#define LOG_TAG_WARNING(tag, format, ...) LOG_TAG(LOG_WARNING, W, tag, format, ##__VA_ARGS__)
|
||||
#define LOG_TAG_INFO(tag, format, ...) LOG_TAG(LOG_INFO , I, tag, format, ##__VA_ARGS__)
|
||||
#define LOG_TAG_DEBUG(tag, format, ...) LOG_TAG(LOG_DEBUG , D, tag, format, ##__VA_ARGS__)
|
||||
|
||||
/** definitions for source code compatibility with ESP-IDF */
|
||||
#define ESP_EARLY_LOGE(tag, format, ...) LOG_TAG_EARLY(LOG_ERROR , E, tag, format "\n", ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGW(tag, format, ...) LOG_TAG_EARLY(LOG_WARNING, W, tag, format "\n", ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGI(tag, format, ...) LOG_TAG_EARLY(LOG_INFO , I, tag, format "\n", ##__VA_ARGS__)
|
||||
#define ESP_LOGE(tag, format, ...) LOG_TAG(LOG_ERROR , E, tag, format "\n", ##__VA_ARGS__)
|
||||
#define ESP_LOGW(tag, format, ...) LOG_TAG(LOG_WARNING, W, tag, format "\n", ##__VA_ARGS__)
|
||||
#define ESP_LOGI(tag, format, ...) LOG_TAG(LOG_INFO , I, tag, format "\n", ##__VA_ARGS__)
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
|
||||
#define ESP_EARLY_LOGD(tag, format, ...) LOG_TAG_EARLY(LOG_DEBUG, D, tag, format "\n", ##__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGV(tag, format, ...) LOG_TAG_EARLY(LOG_ALL , V, tag, format "\n", ##__VA_ARGS__)
|
||||
#define ESP_LOGD(tag, format, ...) LOG_TAG(LOG_DEBUG, D, tag, format "\n", ##__VA_ARGS__)
|
||||
#define ESP_LOGV(tag, format, ...) LOG_TAG(LOG_ALL , V, tag, format "\n", ##__VA_ARGS__)
|
||||
|
||||
#else /* ENABLE_DEBUG */
|
||||
|
||||
#define ESP_EARLY_LOGD( tag, format, ... ) (void)tag
|
||||
#define ESP_EARLY_LOGV( tag, format, ... ) (void)tag
|
||||
#define ESP_LOGD( tag, format, ... ) (void)tag
|
||||
#define ESP_LOGV( tag, format, ... ) (void)tag
|
||||
|
||||
#endif /* ENABLE_DEBUG */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
|
||||
#endif /* ESP_COMMON_LOG_H */
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -24,7 +24,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Initalize exception handler */
|
||||
/** Initialize exception handler */
|
||||
extern void init_exceptions(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
69
cpu/esp8266/include/freertos/FreeRTOS.h
Normal file
69
cpu/esp8266/include/freertos/FreeRTOS.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_FREERTOS_H
|
||||
#define FREERTOS_FREERTOS_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/portmacro.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define configMAX_PRIORITIES SCHED_PRIO_LEVELS
|
||||
|
||||
#ifndef configASSERT
|
||||
#define configASSERT assert
|
||||
#endif
|
||||
|
||||
#define portTICK_PERIOD_MS 10
|
||||
#define portTickType TickType_t
|
||||
|
||||
#define portTICK_RATE_MS portTICK_PERIOD_MS
|
||||
|
||||
#define BaseType_t portBASE_TYPE
|
||||
#define UBaseType_t unsigned portBASE_TYPE
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
|
||||
uint32_t xPortGetTickRateHz(void);
|
||||
BaseType_t xPortInIsrContext(void);
|
||||
|
||||
/*
|
||||
* PLEASE NOTE: Following definitions were copied directly from the FreeRTOS
|
||||
* distribution and are under the following copyright:
|
||||
*
|
||||
* FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||
* All rights reserved
|
||||
*
|
||||
* FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License (version 2) as published by the
|
||||
* Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
*
|
||||
* Full license text is available on the following
|
||||
* link: http://www.freertos.org/a00114.html
|
||||
*/
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
#define pdPASS ( pdTRUE )
|
||||
#define pdFAIL ( pdFALSE )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_FREERTOS_H */
|
||||
46
cpu/esp8266/include/freertos/event_groups.h
Normal file
46
cpu/esp8266/include/freertos/event_groups.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_EVENT_GROUPS_H
|
||||
#define FREERTOS_EVENT_GROUPS_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void * EventGroupHandle_t;
|
||||
typedef TickType_t EventBits_t;
|
||||
|
||||
EventGroupHandle_t xEventGroupCreate (void);
|
||||
|
||||
void vEventGroupDelete (EventGroupHandle_t xEventGroup);
|
||||
|
||||
EventBits_t xEventGroupSetBits (EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet);
|
||||
|
||||
EventBits_t xEventGroupClearBits (EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear );
|
||||
|
||||
EventBits_t xEventGroupWaitBits (const EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_EVENT_GROUPS_H */
|
||||
63
cpu/esp8266/include/freertos/portmacro.h
Normal file
63
cpu/esp8266/include/freertos/portmacro.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_PORTMACRO_H
|
||||
#define FREERTOS_PORTMACRO_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#include "mutex.h"
|
||||
#include "irq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define portBASE_TYPE int
|
||||
#define portUBASE_TYPE unsigned portBASE_TYPE
|
||||
|
||||
#define portMAX_DELAY 0xFFFFFFFF
|
||||
|
||||
#define portMUX_TYPE mutex_t
|
||||
#define portMUX_INITIALIZER_UNLOCKED MUTEX_INIT
|
||||
|
||||
#define portYIELD_FROM_ISR thread_yield_higher
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
|
||||
#define portNUM_PROCESSORS 2
|
||||
#define xPortGetCoreID() PRO_CPU_NUM
|
||||
|
||||
#define portENTER_CRITICAL(pm) mutex_lock(pm)
|
||||
#define portEXIT_CRITICAL(pm) mutex_unlock(pm)
|
||||
#define portENTER_CRITICAL_NESTED irq_disable
|
||||
#define portEXIT_CRITICAL_NESTED irq_restore
|
||||
|
||||
#define portENTER_CRITICAL_ISR vTaskEnterCritical
|
||||
#define portEXIT_CRITICAL_ISR vTaskExitCritical
|
||||
|
||||
#else /* MCU_ESP32 */
|
||||
|
||||
#define portNUM_PROCESSORS 1
|
||||
#define xPortGetCoreID() PRO_CPU_NUM
|
||||
|
||||
#define portENTER_CRITICAL vTaskEnterCritical
|
||||
#define portEXIT_CRITICAL vTaskExitCritical
|
||||
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_PORTMACRO_H */
|
||||
118
cpu/esp8266/include/freertos/queue.h
Normal file
118
cpu/esp8266/include/freertos/queue.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_QUEUE_H
|
||||
#define FREERTOS_QUEUE_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define xQueueHandle QueueHandle_t
|
||||
|
||||
typedef void* QueueHandle_t;
|
||||
|
||||
QueueHandle_t xQueueGenericCreate (const UBaseType_t uxQueueLength,
|
||||
const UBaseType_t uxItemSize,
|
||||
const uint8_t ucQueueType);
|
||||
|
||||
QueueHandle_t xQueueCreateCountingSemaphore (const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount);
|
||||
|
||||
void vQueueDelete (QueueHandle_t xQueue);
|
||||
|
||||
BaseType_t xQueueGenericReset (QueueHandle_t xQueue, BaseType_t xNewQueue);
|
||||
|
||||
BaseType_t xQueueGenericReceive (QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xJustPeeking);
|
||||
|
||||
BaseType_t xQueueGenericSend (QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xCopyPosition);
|
||||
|
||||
BaseType_t xQueueReceiveFromISR (QueueHandle_t xQueue, void * const pvBuffer,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken);
|
||||
|
||||
BaseType_t xQueueGenericSendFromISR (QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
const BaseType_t xCopyPosition );
|
||||
|
||||
BaseType_t xQueueGiveFromISR (QueueHandle_t xQueue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken);
|
||||
|
||||
UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue );
|
||||
|
||||
/*
|
||||
* PLEASE NOTE: Following definitions were copied directly from the FreeRTOS
|
||||
* distribution and are under the following copyright:
|
||||
*
|
||||
* FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||
* All rights reserved
|
||||
*
|
||||
* FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License (version 2) as published by the
|
||||
* Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
*
|
||||
* Full license text is available on the following
|
||||
* link: http://www.freertos.org/a00114.html
|
||||
*/
|
||||
|
||||
#define queueSEND_TO_BACK ( ( BaseType_t ) 0 )
|
||||
#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 )
|
||||
#define queueOVERWRITE ( ( BaseType_t ) 2 )
|
||||
|
||||
#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U )
|
||||
#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U )
|
||||
#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U )
|
||||
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U )
|
||||
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U )
|
||||
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U )
|
||||
|
||||
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
|
||||
#define errQUEUE_FULL ( ( BaseType_t ) 0 )
|
||||
#define errQUEUE_BLOCKED ( -4 )
|
||||
#define errQUEUE_YIELD ( -5 )
|
||||
|
||||
#define xQueueCreate( uxQueueLength, uxItemSize ) \
|
||||
xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )
|
||||
|
||||
#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) \
|
||||
xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), \
|
||||
pdFALSE )
|
||||
|
||||
#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) \
|
||||
xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), \
|
||||
queueSEND_TO_BACK )
|
||||
|
||||
#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) \
|
||||
xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), \
|
||||
queueSEND_TO_BACK )
|
||||
|
||||
#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \
|
||||
xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), \
|
||||
( pxHigherPriorityTaskWoken ), \
|
||||
queueSEND_TO_BACK )
|
||||
|
||||
#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_QUEUE_H */
|
||||
81
cpu/esp8266/include/freertos/semphr.h
Normal file
81
cpu/esp8266/include/freertos/semphr.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_SEMPHR_H
|
||||
#define FREERTOS_SEMPHR_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "mutex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* SemaphoreHandle_t;
|
||||
|
||||
SemaphoreHandle_t xSemaphoreCreateMutex(void);
|
||||
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void);
|
||||
|
||||
void vSemaphoreDelete (SemaphoreHandle_t xSemaphore);
|
||||
|
||||
BaseType_t xSemaphoreGive (SemaphoreHandle_t xSemaphore);
|
||||
BaseType_t xSemaphoreTake (SemaphoreHandle_t xSemaphore,
|
||||
TickType_t xTicksToWait);
|
||||
BaseType_t xSemaphoreGiveRecursive (SemaphoreHandle_t xSemaphore);
|
||||
BaseType_t xSemaphoreTakeRecursive (SemaphoreHandle_t xSemaphore,
|
||||
TickType_t xTicksToWait);
|
||||
|
||||
#define vPortCPUInitializeMutex(m) mutex_init(m)
|
||||
|
||||
void vPortCPUAcquireMutex (portMUX_TYPE *mux);
|
||||
void vPortCPUReleaseMutex (portMUX_TYPE *mux);
|
||||
|
||||
/*
|
||||
* PLEASE NOTE: Following definitions were copied directly from the FreeRTOS
|
||||
* distribution and are under the following copyright:
|
||||
*
|
||||
* FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
|
||||
* All rights reserved
|
||||
*
|
||||
* FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License (version 2) as published by the
|
||||
* Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
*
|
||||
* Full license text is available on the following
|
||||
* link: http://www.freertos.org/a00114.html
|
||||
*/
|
||||
|
||||
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )
|
||||
|
||||
#define xSemaphoreCreateBinary() \
|
||||
xQueueGenericCreate( ( UBaseType_t ) 1, \
|
||||
semSEMAPHORE_QUEUE_ITEM_LENGTH, \
|
||||
queueQUEUE_TYPE_BINARY_SEMAPHORE )
|
||||
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) \
|
||||
xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
|
||||
|
||||
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) \
|
||||
xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), \
|
||||
NULL, ( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) \
|
||||
xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), \
|
||||
( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_SEMPHR_H */
|
||||
65
cpu/esp8266/include/freertos/task.h
Normal file
65
cpu/esp8266/include/freertos/task.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TASK_H
|
||||
#define FREERTOS_TASK_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define xTaskHandle TaskHandle_t
|
||||
#define tskNO_AFFINITY INT_MAX
|
||||
|
||||
#define taskDISABLE_INTERRUPTS portDISABLE_INTERRUPTS
|
||||
#define taskENABLE_INTERRUPTS portENABLE_INTERRUPTS
|
||||
|
||||
#define taskENTER_CRITICAL portENTER_CRITICAL
|
||||
#define taskEXIT_CRITICAL portEXIT_CRITICAL
|
||||
|
||||
typedef void (*TaskFunction_t)(void *);
|
||||
|
||||
typedef void* TaskHandle_t;
|
||||
|
||||
BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask);
|
||||
|
||||
BaseType_t xTaskCreatePinnedToCore(TaskFunction_t pvTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask,
|
||||
const BaseType_t xCoreID);
|
||||
|
||||
void vTaskDelete(TaskHandle_t xTaskToDelete);
|
||||
void vTaskDelay(const TickType_t xTicksToDelay);
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandle(void);
|
||||
|
||||
void vTaskEnterCritical(portMUX_TYPE *mux);
|
||||
void vTaskExitCritical(portMUX_TYPE *mux);
|
||||
|
||||
TickType_t xTaskGetTickCount (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_TASK_H */
|
||||
45
cpu/esp8266/include/freertos/timers.h
Normal file
45
cpu/esp8266/include/freertos/timers.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TIMERS_H
|
||||
#define FREERTOS_TIMERS_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* TimerHandle_t;
|
||||
|
||||
#define TimerCallbackFunction_t xtimer_callback_t
|
||||
#define tmrTIMER_CALLBACK TimerCallbackFunction_t
|
||||
|
||||
TimerHandle_t xTimerCreate (const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriod,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction);
|
||||
BaseType_t xTimerDelete(TimerHandle_t xTimer, TickType_t xBlockTime);
|
||||
BaseType_t xTimerStart (TimerHandle_t xTimer, TickType_t xBlockTime);
|
||||
BaseType_t xTimerStop (TimerHandle_t xTimer, TickType_t xBlockTime);
|
||||
BaseType_t xTimerReset (TimerHandle_t xTimer, TickType_t xTicksToWait);
|
||||
|
||||
void *pvTimerGetTimerID(const TimerHandle_t xTimer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* FREERTOS_TIMERS_H */
|
||||
24
cpu/esp8266/include/freertos/xtensa_api.h
Normal file
24
cpu/esp8266/include/freertos/xtensa_api.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* FreeRTOS to RIOT-OS adaption module for source code compatibility
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_XTENSA_API_H
|
||||
#define FREERTOS_XTENSA_API_H
|
||||
|
||||
#include "xtensa/xtensa_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_XTENSA_API_H */
|
||||
142
cpu/esp8266/include/gpio_arch.h
Normal file
142
cpu/esp8266/include/gpio_arch.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Architecture specific GPIO functions for ESP8266
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef GPIO_ARCH_H
|
||||
#define GPIO_ARCH_H
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
#include "periph/gpio.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Definitions for source code compatibility with ESP-IDF */
|
||||
#define GPIO_MODE_INPUT GPIO_IN
|
||||
#define GPIO_MODE_OUTPUT GPIO_OUT
|
||||
#define GPIO_MODE_INPUT_OUTPUT GPIO_IN_OUT
|
||||
|
||||
/** Definition of possible GPIO usage types (for internal use only) */
|
||||
typedef enum
|
||||
{
|
||||
_GPIO = 0, /**< pin used as standard GPIO */
|
||||
#ifdef MCU_ESP32
|
||||
_ADC, /**< pin used as ADC input */
|
||||
_CAN, /**< pin used as CAN signal */
|
||||
_DAC, /**< pin used as DAC output */
|
||||
_EMAC, /**< pin used as EMAC signal */
|
||||
#endif /* MCU_ESP32 */
|
||||
_I2C, /**< pin used as I2C signal */
|
||||
_PWM, /**< pin used as PWM output */
|
||||
_SPI, /**< pin used as SPI interface */
|
||||
_SPIF, /**< pin used as SPI flash interface */
|
||||
_UART, /**< pin used as UART interface */
|
||||
_NOT_EXIST /**< pin cannot be used at all */
|
||||
} gpio_pin_usage_t;
|
||||
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
|
||||
/** Table of GPIO to IOMUX register mappings */
|
||||
extern const uint32_t _gpio_to_iomux_reg[];
|
||||
#define GPIO_PIN_MUX_REG _gpio_to_iomux_reg
|
||||
|
||||
#else /* MCU_ESP32 */
|
||||
|
||||
/** Map of GPIO pin numbers to IOMUX pin numbers */
|
||||
extern const uint8_t _gpio_to_iomux[];
|
||||
/** Map of IOMUX pin numbers to GPIO pin numbers */
|
||||
extern const uint8_t _iomux_to_gpio[];
|
||||
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
/**
|
||||
* @brief Set the usage type of the pin
|
||||
* @param pin GPIO pin
|
||||
* @param usage GPIO pin usage type
|
||||
* @return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int gpio_set_pin_usage(gpio_t pin, gpio_pin_usage_t usage);
|
||||
|
||||
/**
|
||||
* @brief Get the usage type of the pin
|
||||
* @param pin GPIO pin
|
||||
* @return GPIO pin usage type on success
|
||||
* _NOT_EXIST on error
|
||||
*/
|
||||
gpio_pin_usage_t gpio_get_pin_usage(gpio_t pin);
|
||||
|
||||
/**
|
||||
* @brief Get the usage type of the pin as string
|
||||
* @param pin GPIO pin
|
||||
* @return GPIO pin usage type string on success
|
||||
* _NOT_EXIST on error
|
||||
*/
|
||||
const char* gpio_get_pin_usage_str(gpio_t pin);
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
/**
|
||||
* @brief Disable the pullup of the pin
|
||||
*/
|
||||
void gpio_pullup_dis (gpio_t pin);
|
||||
|
||||
/**
|
||||
* @brief Returns the RTCIO pin number or -1 if the pin is not an RTCIO pin
|
||||
*/
|
||||
int8_t gpio_is_rtcio (gpio_t pin);
|
||||
|
||||
/**
|
||||
* @brief Configure sleep mode for an GPIO pin if the pin is an RTCIO pin
|
||||
* @param pin GPIO pin
|
||||
* @param mode active in sleep mode if true
|
||||
* @param input as input if true, as output otherwise
|
||||
* @return 0 on success
|
||||
* @return -1 on invalid pin
|
||||
*/
|
||||
int gpio_config_sleep_mode (gpio_t pin, bool sleep_mode, bool input);
|
||||
|
||||
/**
|
||||
* @brief GPIO set direction init the pin calling gpio_init
|
||||
* @param pin GPIO pin
|
||||
* @param mode active in sleep mode if true
|
||||
* @return 0 on success
|
||||
* -1 on invalid argument
|
||||
*/
|
||||
int gpio_set_direction(gpio_t pin, gpio_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief extern declaration of ROM functions to avoid compilation problems
|
||||
*/
|
||||
void gpio_matrix_in (uint32_t gpio, uint32_t signal_idx, bool inv);
|
||||
void gpio_matrix_out(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv);
|
||||
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* GPIO_ARCH_H */
|
||||
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level GPIO driver implementation for ESP8266
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef GPIO_COMMON_H
|
||||
#define GPIO_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Map of GPIO pin numbers to IOMUX pin numbers */
|
||||
extern const uint8_t _gpio_to_iomux[];
|
||||
/** Map of IOMUX pin numbers to GPIO pin numbers */
|
||||
extern const uint8_t _iomux_to_gpio[];
|
||||
|
||||
/**
|
||||
* @brief Definition of possible GPIO usage types
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
_GPIO = 0, /**< pin used as standard GPIO */
|
||||
_I2C, /**< pin used as I2C signal */
|
||||
_PWM, /**< pin used as PWM output */
|
||||
_SPI, /**< pin used as SPI interface */
|
||||
_SPIF, /**< pin used as SPI flash interface */
|
||||
_UART, /**< pin used as UART interface */
|
||||
} _gpio_pin_usage_t;
|
||||
|
||||
/**
|
||||
* Holds the usage type of each GPIO pin
|
||||
*/
|
||||
extern _gpio_pin_usage_t _gpio_pin_usage [GPIO_PIN_NUMOF];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GPIO_COMMON_H */
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -39,9 +39,8 @@ extern uint32_t irq_interrupt_nesting;
|
||||
/**
|
||||
* @name Macros to enter and exit an ISR
|
||||
*
|
||||
* In non-SDK interrupt handling all stuff is done in `_frxt_int_enter`
|
||||
* and `_frxt_int_exit`. These macros do therefore nothing and are kept only
|
||||
* for source code compatibility.
|
||||
* Since all the stuff is done in `_frxt_int_enter` and `_frxt_int_exit`, these
|
||||
* macros are doing nothing and are kept only for source code compatibility.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
@ -56,10 +55,28 @@ extern uint32_t irq_interrupt_nesting;
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define critical_enter() int _irq_state = irq_disable ()
|
||||
#define critical_enter() int _irq_state = irq_disable()
|
||||
#define critical_exit() irq_restore(_irq_state)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Macros to enter and exit a critical region with state variable
|
||||
* @{
|
||||
*/
|
||||
#define critical_enter_var(m) m = irq_disable()
|
||||
#define critical_exit_var(m) irq_restore(m)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Software interrupt types
|
||||
*
|
||||
* These definitions are used to distinguish different types of software
|
||||
* interrupts in software interrupt handler.
|
||||
*/
|
||||
#define ETS_SOFT_INT_NONE 0
|
||||
#define ETS_SOFT_INT_YIELD 1
|
||||
#define ETS_SOFT_INT_HDL_MAC 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
60
cpu/esp8266/include/log_module.h
Normal file
60
cpu/esp8266/include/log_module.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Log module to realize consistent log messages
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#ifndef LOG_MODULE_H
|
||||
#define LOG_MODULE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "esp_common_log.h"
|
||||
|
||||
#ifdef MODULE_LOG_PRINTFNOFORMAT
|
||||
|
||||
static inline void log_write(unsigned level, const char *format, ...) {
|
||||
(void)level;
|
||||
puts(format);
|
||||
}
|
||||
|
||||
#else /* MODULE_LOG_PRINTFNOFORMAT */
|
||||
|
||||
#define log_write(level, ...) \
|
||||
do { \
|
||||
if (level == LOG_ERROR) { \
|
||||
LOG_TAG(LOG_ERROR, E, __func__, ##__VA_ARGS__); \
|
||||
} \
|
||||
else if (level == LOG_WARNING) { \
|
||||
LOG_TAG(LOG_WARNING, W, __func__, ##__VA_ARGS__); \
|
||||
} \
|
||||
else if (level == LOG_INFO) { \
|
||||
LOG_TAG(LOG_INFO, D, __func__, ##__VA_ARGS__); \
|
||||
} \
|
||||
else if (level == LOG_DEBUG) { \
|
||||
LOG_TAG(LOG_DEBUG, E, __func__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* MODULE_LOG_PRINTFNOFORMAT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/**@}*/
|
||||
#endif /* LOG_MODULE_H */
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -33,31 +33,55 @@ extern "C" {
|
||||
#define CPUID_LEN (4U)
|
||||
|
||||
/**
|
||||
* @name GPIO configuration of ESP8266
|
||||
* @name GPIO configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Available ports on the ESP8266
|
||||
* @brief Override the default gpio_t type definition
|
||||
*
|
||||
* This is required here to have gpio_t defined in this file.
|
||||
* @{
|
||||
*/
|
||||
#define PORT_GPIO 0 /**< port GPIO */
|
||||
#define HAVE_GPIO_T
|
||||
typedef unsigned int gpio_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Definition of a fitting UNDEF value
|
||||
*/
|
||||
#define GPIO_UNDEF (GPIO_ID_NONE)
|
||||
#define GPIO_UNDEF ((gpio_t)(UINT_MAX))
|
||||
|
||||
/**
|
||||
* @brief Define CPU specific GPIO pin generator macro
|
||||
* @brief Define a CPU specific GPIO pin generator macro
|
||||
*/
|
||||
#define GPIO_PIN(x, y) ((x << 4) | y)
|
||||
#define GPIO_PIN(x, y) ((x & 0) | y)
|
||||
|
||||
/**
|
||||
* @brief Available GPIO ports on ESP8266
|
||||
*/
|
||||
#define PORT_GPIO (0)
|
||||
|
||||
/**
|
||||
* @brief Define CPU specific number of GPIO pins
|
||||
*/
|
||||
#define GPIO_PIN_NUMOF GPIO_PIN_COUNT+1
|
||||
#define GPIO_PIN_NUMOF (17)
|
||||
|
||||
/**
|
||||
* @brief Override flank selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_FLANK_T
|
||||
typedef enum {
|
||||
GPIO_NONE = 0,
|
||||
GPIO_RISING = 1, /**< emit interrupt on rising flank */
|
||||
GPIO_FALLING = 2, /**< emit interrupt on falling flank */
|
||||
GPIO_BOTH = 3, /**< emit interrupt on both flanks */
|
||||
GPIO_LOW = 4, /**< emit interrupt on low level */
|
||||
GPIO_HIGH = 5 /**< emit interrupt on low level */
|
||||
} gpio_flank_t;
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Predefined GPIO names
|
||||
@ -82,51 +106,64 @@ extern "C" {
|
||||
#define GPIO16 (GPIO_PIN(PORT_GPIO,16))
|
||||
/** @} */
|
||||
|
||||
#ifndef DOXYGEN
|
||||
#define GPIO0_MASK (BIT(0))
|
||||
#define GPIO1_MASK (BIT(1))
|
||||
#define GPIO2_MASK (BIT(2))
|
||||
#define GPIO3_MASK (BIT(3))
|
||||
#define GPIO4_MASK (BIT(4))
|
||||
#define GPIO5_MASK (BIT(5))
|
||||
#define GPIO6_MASK (BIT(6))
|
||||
#define GPIO7_MASK (BIT(7))
|
||||
#define GPIO8_MASK (BIT(8))
|
||||
#define GPIO9_MASK (BIT(9))
|
||||
#define GPIO10_MASK (BIT(10))
|
||||
#define GPIO11_MASK (BIT(11))
|
||||
#define GPIO12_MASK (BIT(12))
|
||||
#define GPIO13_MASK (BIT(13))
|
||||
#define GPIO14_MASK (BIT(14))
|
||||
#define GPIO15_MASK (BIT(15))
|
||||
#define GPIO16_MASK (BIT(16))
|
||||
|
||||
/**
|
||||
* @brief Override flank selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_FLANK_T
|
||||
typedef enum {
|
||||
GPIO_NONE = 0,
|
||||
GPIO_RISING = 1, /**< emit interrupt on rising flank */
|
||||
GPIO_FALLING = 2, /**< emit interrupt on falling flank */
|
||||
GPIO_BOTH = 3, /**< emit interrupt on both flanks */
|
||||
GPIO_LOW = 4, /**< emit interrupt on low level */
|
||||
GPIO_HIGH = 5 /**< emit interrupt on low level */
|
||||
} gpio_flank_t;
|
||||
/** @} */
|
||||
#endif /* DOXYGEN */
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name I2C configuration
|
||||
*
|
||||
* ESP8266 provides up to two bit-banging I2C interfaces.
|
||||
*
|
||||
* The board-specific configuration of the I2C interface I2C_DEV(n) requires
|
||||
* the definition of
|
||||
*
|
||||
* I2Cn_SPEED, the bus speed,
|
||||
* I2Cn_SCL, the GPIO used as SCL signal, and
|
||||
* I2Cn_SDA, the GPIO used as SDA signal,
|
||||
*
|
||||
* where n can be 0 or 1. If they are not defined, the I2C interface
|
||||
* I2C_DEV(n) is not used.
|
||||
*
|
||||
* @note The configuration of the I2C interfaces I2C_DEV(n) must be in
|
||||
* continuous ascending order of n.
|
||||
*
|
||||
* I2C_NUMOF is determined automatically from board-specific peripheral
|
||||
* definitions of I2Cn_SPEED, I2Cn_SCK, and I2Cn_SDA.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define PERIPH_I2C_NEED_READ_REG
|
||||
#define PERIPH_I2C_NEED_READ_REGS
|
||||
#define PERIPH_I2C_NEED_WRITE_REG
|
||||
#define PERIPH_I2C_NEED_WRITE_REGS
|
||||
|
||||
/**
|
||||
* @brief Override I2C clock speed values
|
||||
*
|
||||
* This is required here to have i2c_speed_t defined in this file.
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_I2C_SPEED_T
|
||||
typedef enum {
|
||||
I2C_SPEED_LOW = 0, /**< 10 kbit/s */
|
||||
I2C_SPEED_NORMAL, /**< 100 kbit/s */
|
||||
I2C_SPEED_FAST, /**< 400 kbit/s */
|
||||
I2C_SPEED_FAST_PLUS, /**< 1 Mbit/s */
|
||||
I2C_SPEED_HIGH, /**< not supported */
|
||||
} i2c_speed_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief I2C configuration structure type
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_speed_t speed; /**< I2C bus speed */
|
||||
gpio_t scl; /**< GPIO used as SCL pin */
|
||||
gpio_t sda; /**< GPIO used as SDA pin */
|
||||
} i2c_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Maximum number of I2C interfaces that can be used by board definitions
|
||||
*/
|
||||
#define I2C_NUMOF_MAX (2)
|
||||
|
||||
#define PERIPH_I2C_NEED_READ_REG /**< i2c_read_reg required */
|
||||
#define PERIPH_I2C_NEED_READ_REGS /**< i2c_read_regs required */
|
||||
#define PERIPH_I2C_NEED_WRITE_REG /**< i2c_write_reg required */
|
||||
#define PERIPH_I2C_NEED_WRITE_REGS /**< i2c_write_regs required */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@ -139,24 +176,114 @@ typedef enum {
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name SPI configuration
|
||||
* @name PWM configuration
|
||||
*
|
||||
* The hardware implementation of ESP8266 PWM supports only frequencies as
|
||||
* power of two. Therefore a software implementation of one PWM device
|
||||
* PWM_DEV(0) with up to 8 PWM channels (#PWM_CHANNEL_NUM_MAX) is used. The
|
||||
* GPIOs that can be used as PWM channels are defined by #PWM0_GPIOS in board
|
||||
* definition.
|
||||
*
|
||||
* @note The minimum PWM period that can be realized is 10 us or 100.000 PWM
|
||||
* clock cycles per second. Therefore, the product of frequency and resolution
|
||||
* should not be greater than 100.000. Otherwise the frequency is scaled down
|
||||
* automatically.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#if defined(MODULE_PERIPH_SPI)
|
||||
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REG
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REGS
|
||||
/**
|
||||
* @brief Maximum number of PWM devices.
|
||||
*/
|
||||
#define PWM_NUMOF_MAX (1)
|
||||
|
||||
#endif /* MODULE_PERIPH_SPI */
|
||||
/**
|
||||
* @brief Maximum number of channels per PWM device.
|
||||
*/
|
||||
#define PWM_CHANNEL_NUM_MAX (8)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name SPI configuration
|
||||
*
|
||||
* ESP8266 has two SPI controllers:
|
||||
*
|
||||
* - _CSPI_ for caching and accessing the flash memory<br>
|
||||
* - _HSPI_ for peripherals
|
||||
*
|
||||
* Thus, _HSPI_ is the only SPI interface that is available for peripherals.
|
||||
* It is exposed as RIOT's SPI_DEV(0). The pin configuration of the _HSPI_
|
||||
* interface is fixed as shown in following table.
|
||||
*
|
||||
* Signal | Pin
|
||||
* -- --------|-------
|
||||
* #SPI0_MISO | GPIO12
|
||||
* #SPI0_MOSI | GPIO13
|
||||
* #SPI0_SCK | GPIO14
|
||||
* #SPI0_CS0 | GPIOn with n = 0, 2, 4, 5, 15, 16 (additionally 9, 10 in DOUT flash mode)
|
||||
*
|
||||
* The only pin definition that can be overridden by an application-specific
|
||||
* board configuration is the CS signal defined by #SPI0_CS0.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief SPI controllers that can be used for peripheral interfaces
|
||||
*/
|
||||
typedef enum {
|
||||
HSPI = 1, /**< HSPI interface controller */
|
||||
} spi_ctrl_t;
|
||||
|
||||
/**
|
||||
* @brief SPI configuration structure type
|
||||
*/
|
||||
typedef struct {
|
||||
spi_ctrl_t ctrl; /**< SPI controller used for the interface */
|
||||
gpio_t sck; /**< GPIO used as SCK pin */
|
||||
gpio_t mosi; /**< GPIO used as MOSI pin */
|
||||
gpio_t miso; /**< GPIO used as MISO pin */
|
||||
gpio_t cs; /**< GPIO used as CS0 pin */
|
||||
} spi_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Maximum number of SPI interfaces
|
||||
*/
|
||||
#define SPI_NUMOF_MAX (1)
|
||||
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE /**< requires function spi_transfer_byte */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REG /**< requires function spi_transfer_reg */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REGS /**< requires function spi_transfer_regs */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Prevent shared timer functions from being used
|
||||
*/
|
||||
#define PERIPH_TIMER_PROVIDES_SET
|
||||
|
||||
/**
|
||||
* @name UART configuration
|
||||
*
|
||||
* All ESP8266 boards have exactly one UART device with fixed pin mapping.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief UART configuration structure type
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_t txd; /**< GPIO used as TxD pin */
|
||||
gpio_t rxd; /**< GPIO used as RxD pin */
|
||||
} uart_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Maximum number of UART interfaces
|
||||
*/
|
||||
#define UART_NUMOF_MAX (1)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
86
cpu/esp8266/include/sdk_conf.h
Normal file
86
cpu/esp8266/include/sdk_conf.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief SDK configuration compatible to the ESP-IDF
|
||||
*
|
||||
* This file defines configuration parameters that are only required for source
|
||||
* code compatibility with the SDK. These configuration parameters are not used
|
||||
* directly to configure the compilation of RIOT-OS. However, some of them can
|
||||
* be overrien overridden by application-specific board configuration.
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#ifndef SDK_CONF_H
|
||||
#define SDK_CONF_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include "board.h"
|
||||
#include "esp_image_format.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SDK version number
|
||||
*
|
||||
* Determined with `git describe --tags` in `$ESP8266_SDK_DIR`
|
||||
*/
|
||||
#define IDF_VER "v3.1-4-g08c234e"
|
||||
|
||||
/**
|
||||
* @name Default console configuration
|
||||
*
|
||||
* STDIO_UART_BAUDRATE is used as CONFIG_CONSOLE_UART_BAUDRATE and
|
||||
* can be overridden by an application specific configuration.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define CONFIG_CONSOLE_UART_NUM (0)
|
||||
#ifndef CONFIG_CONSOLE_UART_BAUDRATE
|
||||
#define CONFIG_CONSOLE_UART_BAUDRATE (STDIO_UART_BAUDRATE)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#define CONFIG_APP1_SIZE (0xf0000)
|
||||
#define CONFIG_APP1_OFFSET (0x10000)
|
||||
|
||||
#define CONFIG_SOC_IRAM_SIZE (0xc000)
|
||||
|
||||
#define CONFIG_TASK_WDT_PANIC
|
||||
#define CONFIG_TASK_WDT_TIMEOUT_S (15)
|
||||
|
||||
#define CONFIG_WIFI_PPT_TASKSTACK_SIZE (3584)
|
||||
#define CONFIG_MAIN_TASK_STACK_SIZE (2048)
|
||||
#define CONFIG_EVENT_LOOP_STACK_SIZE (2048)
|
||||
|
||||
#define CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE
|
||||
#define CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION (0)
|
||||
|
||||
#define CONFIG_SPI_FLASH_FREQ (ESP_IMAGE_SPI_SPEED_40M) /* 40 MHz */
|
||||
#define CONFIG_SPI_FLASH_MODE (ESP_IMAGE_SPI_MODE_DIO) /* DIO mode */
|
||||
#define CONFIG_SPI_FLASH_SIZE (0x100000)
|
||||
|
||||
#define CONFIG_SCAN_AP_MAX (32)
|
||||
|
||||
#define CONFIG_USING_NEW_ETS_VPRINTF
|
||||
#define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* SDK_CONF_H */
|
||||
748
cpu/esp8266/include/stdio.h
Normal file
748
cpu/esp8266/include/stdio.h
Normal file
@ -0,0 +1,748 @@
|
||||
/**
|
||||
* This file is a modification of the original file to overwrite the *putchar*
|
||||
* and *getchar* macros in the case the *uart_stdio* module is used. If the
|
||||
* *uart_stdio* module is used, *putchar* and *getchar* are redirections to
|
||||
* according *uart_stdio_* functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the University of California, Berkeley. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* @(#)stdio.h 5.3 (Berkeley) 3/15/86
|
||||
*/
|
||||
|
||||
/*
|
||||
* NB: to fit things in six character monocase externals, the
|
||||
* stdio code uses the prefix `__s' for stdio objects, typically
|
||||
* followed by a three-character attempt at a mnemonic.
|
||||
*/
|
||||
|
||||
#ifndef STDIO_H
|
||||
#define STDIO_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "_ansi.h"
|
||||
|
||||
#define _FSTDIO /* ``function stdio'' */
|
||||
|
||||
#define __need_size_t
|
||||
#define __need_NULL
|
||||
#include <sys/cdefs.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define __need___va_list
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
* <sys/reent.h> defines __FILE, _fpos_t.
|
||||
* They must be defined there because struct _reent needs them (and we don't
|
||||
* want reent.h to include this file.
|
||||
*/
|
||||
|
||||
#include <sys/reent.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
_BEGIN_STD_C
|
||||
|
||||
typedef __FILE FILE;
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
typedef _fpos64_t fpos_t;
|
||||
#else
|
||||
typedef _fpos_t fpos_t;
|
||||
#ifdef __LARGE64_FILES
|
||||
typedef _fpos64_t fpos64_t;
|
||||
#endif
|
||||
#endif /* !__CYGWIN__ */
|
||||
|
||||
#include <sys/stdio.h>
|
||||
|
||||
#define __SLBF 0x0001 /* line buffered */
|
||||
#define __SNBF 0x0002 /* unbuffered */
|
||||
#define __SRD 0x0004 /* OK to read */
|
||||
#define __SWR 0x0008 /* OK to write */
|
||||
/* RD and WR are never simultaneously asserted */
|
||||
#define __SRW 0x0010 /* open for reading & writing */
|
||||
#define __SEOF 0x0020 /* found EOF */
|
||||
#define __SERR 0x0040 /* found error */
|
||||
#define __SMBF 0x0080 /* _buf is from malloc */
|
||||
#define __SAPP 0x0100 /* fdopen()ed in append mode - so must write to end */
|
||||
#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
|
||||
#define __SOPT 0x0400 /* do fseek() optimisation */
|
||||
#define __SNPT 0x0800 /* do not do fseek() optimisation */
|
||||
#define __SOFF 0x1000 /* set iff _offset is in fact correct */
|
||||
#define __SORD 0x2000 /* true => stream orientation (byte/wide) decided */
|
||||
#if defined(__CYGWIN__)
|
||||
#define __SCLE 0x4000 /* convert line endings CR/LF <-> NL */
|
||||
#endif
|
||||
#define __SL64 0x8000 /* is 64-bit offset large file */
|
||||
|
||||
/* _flags2 flags */
|
||||
#define __SNLK 0x0001 /* stdio functions do not lock streams themselves */
|
||||
#define __SWID 0x2000 /* true => stream orientation wide, false => byte, only valid if __SORD in _flags is true */
|
||||
|
||||
/*
|
||||
* The following three definitions are for ANSI C, which took them
|
||||
* from System V, which stupidly took internal interface macros and
|
||||
* made them official arguments to setvbuf(), without renaming them.
|
||||
* Hence, these ugly _IOxxx names are *supposed* to appear in user code.
|
||||
*
|
||||
* Although these happen to match their counterparts above, the
|
||||
* implementation does not rely on that (so these could be renumbered).
|
||||
*/
|
||||
#define _IOFBF 0 /* setvbuf should set fully buffered */
|
||||
#define _IOLBF 1 /* setvbuf should set line buffered */
|
||||
#define _IONBF 2 /* setvbuf should set unbuffered */
|
||||
|
||||
#define EOF (-1)
|
||||
|
||||
#ifdef __BUFSIZ__
|
||||
#define BUFSIZ __BUFSIZ__
|
||||
#else
|
||||
#define BUFSIZ 1024
|
||||
#endif
|
||||
|
||||
#ifdef __FOPEN_MAX__
|
||||
#define FOPEN_MAX __FOPEN_MAX__
|
||||
#else
|
||||
#define FOPEN_MAX 20
|
||||
#endif
|
||||
|
||||
#ifdef __FILENAME_MAX__
|
||||
#define FILENAME_MAX __FILENAME_MAX__
|
||||
#else
|
||||
#define FILENAME_MAX 1024
|
||||
#endif
|
||||
|
||||
#ifdef __L_tmpnam__
|
||||
#define L_tmpnam __L_tmpnam__
|
||||
#else
|
||||
#define L_tmpnam FILENAME_MAX
|
||||
#endif
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define P_tmpdir "/tmp"
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0 /* set file offset to offset */
|
||||
#endif
|
||||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1 /* set file offset to current plus offset */
|
||||
#endif
|
||||
#ifndef SEEK_END
|
||||
#define SEEK_END 2 /* set file offset to EOF plus offset */
|
||||
#endif
|
||||
|
||||
#define TMP_MAX 26
|
||||
|
||||
#define stdin (_REENT->_stdin)
|
||||
#define stdout (_REENT->_stdout)
|
||||
#define stderr (_REENT->_stderr)
|
||||
|
||||
#define _stdin_r(x) ((x)->_stdin)
|
||||
#define _stdout_r(x) ((x)->_stdout)
|
||||
#define _stderr_r(x) ((x)->_stderr)
|
||||
|
||||
/*
|
||||
* Functions defined in ANSI C standard.
|
||||
*/
|
||||
|
||||
#ifndef __VALIST
|
||||
#ifdef __GNUC__
|
||||
#define __VALIST __gnuc_va_list
|
||||
#else
|
||||
#define __VALIST char*
|
||||
#endif
|
||||
#endif
|
||||
|
||||
FILE * _EXFUN(tmpfile, (void));
|
||||
char * _EXFUN(tmpnam, (char *));
|
||||
#if __BSD_VISIBLE || __XSI_VISIBLE || __POSIX_VISIBLE >= 200112
|
||||
char * _EXFUN(tempnam, (const char *, const char *));
|
||||
#endif
|
||||
int _EXFUN(fclose, (FILE *));
|
||||
int _EXFUN(fflush, (FILE *));
|
||||
FILE * _EXFUN(freopen, (const char *__restrict, const char *__restrict, FILE *__restrict));
|
||||
void _EXFUN(setbuf, (FILE *__restrict, char *__restrict));
|
||||
int _EXFUN(setvbuf, (FILE *__restrict, char *__restrict, int, size_t));
|
||||
int _EXFUN(fprintf, (FILE *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
int _EXFUN(fscanf, (FILE *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 3))));
|
||||
int _EXFUN(printf, (const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 1, 2))));
|
||||
int _EXFUN(scanf, (const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 1, 2))));
|
||||
int _EXFUN(sscanf, (const char *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 3))));
|
||||
int _EXFUN(vfprintf, (FILE *__restrict, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
int _EXFUN(vprintf, (const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 1, 0))));
|
||||
int _EXFUN(vsprintf, (char *__restrict, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
int _EXFUN(fgetc, (FILE *));
|
||||
char * _EXFUN(fgets, (char *__restrict, int, FILE *__restrict));
|
||||
int _EXFUN(fputc, (int, FILE *));
|
||||
int _EXFUN(fputs, (const char *__restrict, FILE *__restrict));
|
||||
int _EXFUN(getc, (FILE *));
|
||||
int _EXFUN(getchar, (void));
|
||||
char * _EXFUN(gets, (char *));
|
||||
int _EXFUN(putc, (int, FILE *));
|
||||
int _EXFUN(putchar, (int));
|
||||
int _EXFUN(puts, (const char *));
|
||||
int _EXFUN(ungetc, (int, FILE *));
|
||||
size_t _EXFUN(fread, (_PTR __restrict, size_t _size, size_t _n, FILE *__restrict));
|
||||
size_t _EXFUN(fwrite, (const _PTR __restrict , size_t _size, size_t _n, FILE *));
|
||||
#ifdef _COMPILING_NEWLIB
|
||||
int _EXFUN(fgetpos, (FILE *, _fpos_t *));
|
||||
#else
|
||||
int _EXFUN(fgetpos, (FILE *__restrict, fpos_t *__restrict));
|
||||
#endif
|
||||
int _EXFUN(fseek, (FILE *, long, int));
|
||||
#ifdef _COMPILING_NEWLIB
|
||||
int _EXFUN(fsetpos, (FILE *, const _fpos_t *));
|
||||
#else
|
||||
int _EXFUN(fsetpos, (FILE *, const fpos_t *));
|
||||
#endif
|
||||
long _EXFUN(ftell, ( FILE *));
|
||||
void _EXFUN(rewind, (FILE *));
|
||||
void _EXFUN(clearerr, (FILE *));
|
||||
int _EXFUN(feof, (FILE *));
|
||||
int _EXFUN(ferror, (FILE *));
|
||||
void _EXFUN(perror, (const char *));
|
||||
#ifndef _REENT_ONLY
|
||||
FILE * _EXFUN(fopen, (const char *__restrict _name, const char *__restrict _type));
|
||||
int _EXFUN(sprintf, (char *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
int _EXFUN(remove, (const char *));
|
||||
int _EXFUN(rename, (const char *, const char *));
|
||||
#ifdef _COMPILING_NEWLIB
|
||||
int _EXFUN(_rename, (const char *, const char *));
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(__STRICT_ANSI__) || defined(__USE_XOPEN2K)
|
||||
#ifdef _COMPILING_NEWLIB
|
||||
int _EXFUN(fseeko, (FILE *, _off_t, int));
|
||||
_off_t _EXFUN(ftello, ( FILE *));
|
||||
#else
|
||||
int _EXFUN(fseeko, (FILE *, off_t, int));
|
||||
off_t _EXFUN(ftello, ( FILE *));
|
||||
#endif
|
||||
#endif
|
||||
#if __GNU_VISIBLE
|
||||
int _EXFUN(fcloseall, (_VOID));
|
||||
#endif
|
||||
#if !defined(__STRICT_ANSI__) || (__STDC_VERSION__ >= 199901L) || (__cplusplus >= 201103L)
|
||||
#ifndef _REENT_ONLY
|
||||
int _EXFUN(asiprintf, (char **, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
char * _EXFUN(asniprintf, (char *, size_t *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
char * _EXFUN(asnprintf, (char *__restrict, size_t *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(asprintf, (char **__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
#ifndef diprintf
|
||||
int _EXFUN(diprintf, (int, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
#endif
|
||||
int _EXFUN(fiprintf, (FILE *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
int _EXFUN(fiscanf, (FILE *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 3))));
|
||||
int _EXFUN(iprintf, (const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 1, 2))));
|
||||
int _EXFUN(iscanf, (const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 1, 2))));
|
||||
int _EXFUN(siprintf, (char *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
int _EXFUN(siscanf, (const char *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 3))));
|
||||
int _EXFUN(snprintf, (char *__restrict, size_t, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(sniprintf, (char *, size_t, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(vasiprintf, (char **, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
char * _EXFUN(vasniprintf, (char *, size_t *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
char * _EXFUN(vasnprintf, (char *, size_t *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(vasprintf, (char **, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
int _EXFUN(vdiprintf, (int, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
int _EXFUN(vfiprintf, (FILE *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
int _EXFUN(vfiscanf, (FILE *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 0))));
|
||||
int _EXFUN(vfscanf, (FILE *__restrict, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 0))));
|
||||
int _EXFUN(viprintf, (const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 1, 0))));
|
||||
int _EXFUN(viscanf, (const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 1, 0))));
|
||||
int _EXFUN(vscanf, (const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 1, 0))));
|
||||
int _EXFUN(vsiprintf, (char *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
int _EXFUN(vsiscanf, (const char *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 0))));
|
||||
int _EXFUN(vsniprintf, (char *, size_t, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(vsnprintf, (char *__restrict, size_t, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(vsscanf, (const char *__restrict, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 0))));
|
||||
#endif /* !_REENT_ONLY */
|
||||
#endif /* !__STRICT_ANSI__ */
|
||||
|
||||
/*
|
||||
* Routines in POSIX 1003.1:2001.
|
||||
*/
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
#ifndef _REENT_ONLY
|
||||
FILE * _EXFUN(fdopen, (int, const char *));
|
||||
#endif
|
||||
int _EXFUN(fileno, (FILE *));
|
||||
int _EXFUN(getw, (FILE *));
|
||||
int _EXFUN(pclose, (FILE *));
|
||||
FILE * _EXFUN(popen, (const char *, const char *));
|
||||
int _EXFUN(putw, (int, FILE *));
|
||||
void _EXFUN(setbuffer, (FILE *, char *, int));
|
||||
int _EXFUN(setlinebuf, (FILE *));
|
||||
int _EXFUN(getc_unlocked, (FILE *));
|
||||
int _EXFUN(getchar_unlocked, (void));
|
||||
void _EXFUN(flockfile, (FILE *));
|
||||
int _EXFUN(ftrylockfile, (FILE *));
|
||||
void _EXFUN(funlockfile, (FILE *));
|
||||
int _EXFUN(putc_unlocked, (int, FILE *));
|
||||
int _EXFUN(putchar_unlocked, (int));
|
||||
#endif /* ! __STRICT_ANSI__ */
|
||||
|
||||
/*
|
||||
* Routines in POSIX 1003.1:200x.
|
||||
*/
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
# ifndef _REENT_ONLY
|
||||
# ifndef dprintf
|
||||
int _EXFUN(dprintf, (int, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
# endif
|
||||
FILE * _EXFUN(fmemopen, (void *__restrict, size_t, const char *__restrict));
|
||||
/* getdelim - see __getdelim for now */
|
||||
/* getline - see __getline for now */
|
||||
FILE * _EXFUN(open_memstream, (char **, size_t *));
|
||||
#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
|
||||
int _EXFUN(renameat, (int, const char *, int, const char *));
|
||||
#endif
|
||||
int _EXFUN(vdprintf, (int, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Recursive versions of the above.
|
||||
*/
|
||||
|
||||
int _EXFUN(_asiprintf_r, (struct _reent *, char **, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
char * _EXFUN(_asniprintf_r, (struct _reent *, char *, size_t *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 4, 5))));
|
||||
char * _EXFUN(_asnprintf_r, (struct _reent *, char *__restrict, size_t *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 4, 5))));
|
||||
int _EXFUN(_asprintf_r, (struct _reent *, char **__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(_diprintf_r, (struct _reent *, int, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(_dprintf_r, (struct _reent *, int, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(_fclose_r, (struct _reent *, FILE *));
|
||||
int _EXFUN(_fcloseall_r, (struct _reent *));
|
||||
FILE * _EXFUN(_fdopen_r, (struct _reent *, int, const char *));
|
||||
int _EXFUN(_fflush_r, (struct _reent *, FILE *));
|
||||
int _EXFUN(_fgetc_r, (struct _reent *, FILE *));
|
||||
int _EXFUN(_fgetc_unlocked_r, (struct _reent *, FILE *));
|
||||
char * _EXFUN(_fgets_r, (struct _reent *, char *__restrict, int, FILE *__restrict));
|
||||
char * _EXFUN(_fgets_unlocked_r, (struct _reent *, char *__restrict, int, FILE *__restrict));
|
||||
#ifdef _COMPILING_NEWLIB
|
||||
int _EXFUN(_fgetpos_r, (struct _reent *, FILE *__restrict, _fpos_t *__restrict));
|
||||
int _EXFUN(_fsetpos_r, (struct _reent *, FILE *, const _fpos_t *));
|
||||
#else
|
||||
int _EXFUN(_fgetpos_r, (struct _reent *, FILE *, fpos_t *));
|
||||
int _EXFUN(_fsetpos_r, (struct _reent *, FILE *, const fpos_t *));
|
||||
#endif
|
||||
int _EXFUN(_fiprintf_r, (struct _reent *, FILE *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(_fiscanf_r, (struct _reent *, FILE *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 3, 4))));
|
||||
FILE * _EXFUN(_fmemopen_r, (struct _reent *, void *__restrict, size_t, const char *__restrict));
|
||||
FILE * _EXFUN(_fopen_r, (struct _reent *, const char *__restrict, const char *__restrict));
|
||||
FILE * _EXFUN(_freopen_r, (struct _reent *, const char *__restrict, const char *__restrict, FILE *__restrict));
|
||||
int _EXFUN(_fprintf_r, (struct _reent *, FILE *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(_fpurge_r, (struct _reent *, FILE *));
|
||||
int _EXFUN(_fputc_r, (struct _reent *, int, FILE *));
|
||||
int _EXFUN(_fputc_unlocked_r, (struct _reent *, int, FILE *));
|
||||
int _EXFUN(_fputs_r, (struct _reent *, const char *__restrict, FILE *__restrict));
|
||||
int _EXFUN(_fputs_unlocked_r, (struct _reent *, const char *__restrict, FILE *__restrict));
|
||||
size_t _EXFUN(_fread_r, (struct _reent *, _PTR __restrict, size_t _size, size_t _n, FILE *__restrict));
|
||||
size_t _EXFUN(_fread_unlocked_r, (struct _reent *, _PTR __restrict, size_t _size, size_t _n, FILE *__restrict));
|
||||
int _EXFUN(_fscanf_r, (struct _reent *, FILE *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 3, 4))));
|
||||
int _EXFUN(_fseek_r, (struct _reent *, FILE *, long, int));
|
||||
int _EXFUN(_fseeko_r,(struct _reent *, FILE *, _off_t, int));
|
||||
long _EXFUN(_ftell_r, (struct _reent *, FILE *));
|
||||
_off_t _EXFUN(_ftello_r,(struct _reent *, FILE *));
|
||||
void _EXFUN(_rewind_r, (struct _reent *, FILE *));
|
||||
size_t _EXFUN(_fwrite_r, (struct _reent *, const _PTR __restrict, size_t _size, size_t _n, FILE *__restrict));
|
||||
size_t _EXFUN(_fwrite_unlocked_r, (struct _reent *, const _PTR __restrict, size_t _size, size_t _n, FILE *__restrict));
|
||||
int _EXFUN(_getc_r, (struct _reent *, FILE *));
|
||||
int _EXFUN(_getc_unlocked_r, (struct _reent *, FILE *));
|
||||
int _EXFUN(_getchar_r, (struct _reent *));
|
||||
int _EXFUN(_getchar_unlocked_r, (struct _reent *));
|
||||
char * _EXFUN(_gets_r, (struct _reent *, char *));
|
||||
int _EXFUN(_iprintf_r, (struct _reent *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
int _EXFUN(_iscanf_r, (struct _reent *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 3))));
|
||||
FILE * _EXFUN(_open_memstream_r, (struct _reent *, char **, size_t *));
|
||||
void _EXFUN(_perror_r, (struct _reent *, const char *));
|
||||
int _EXFUN(_printf_r, (struct _reent *, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 3))));
|
||||
int _EXFUN(_putc_r, (struct _reent *, int, FILE *));
|
||||
int _EXFUN(_putc_unlocked_r, (struct _reent *, int, FILE *));
|
||||
int _EXFUN(_putchar_unlocked_r, (struct _reent *, int));
|
||||
int _EXFUN(_putchar_r, (struct _reent *, int));
|
||||
int _EXFUN(_puts_r, (struct _reent *, const char *));
|
||||
int _EXFUN(_remove_r, (struct _reent *, const char *));
|
||||
int _EXFUN(_rename_r, (struct _reent *,
|
||||
const char *_old, const char *_new));
|
||||
int _EXFUN(_scanf_r, (struct _reent *, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 3))));
|
||||
int _EXFUN(_siprintf_r, (struct _reent *, char *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(_siscanf_r, (struct _reent *, const char *, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 3, 4))));
|
||||
int _EXFUN(_sniprintf_r, (struct _reent *, char *, size_t, const char *, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 4, 5))));
|
||||
int _EXFUN(_snprintf_r, (struct _reent *, char *__restrict, size_t, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 4, 5))));
|
||||
int _EXFUN(_sprintf_r, (struct _reent *, char *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
|
||||
int _EXFUN(_sscanf_r, (struct _reent *, const char *__restrict, const char *__restrict, ...)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 3, 4))));
|
||||
char * _EXFUN(_tempnam_r, (struct _reent *, const char *, const char *));
|
||||
FILE * _EXFUN(_tmpfile_r, (struct _reent *));
|
||||
char * _EXFUN(_tmpnam_r, (struct _reent *, char *));
|
||||
int _EXFUN(_ungetc_r, (struct _reent *, int, FILE *));
|
||||
int _EXFUN(_vasiprintf_r, (struct _reent *, char **, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
char * _EXFUN(_vasniprintf_r, (struct _reent*, char *, size_t *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 4, 0))));
|
||||
char * _EXFUN(_vasnprintf_r, (struct _reent*, char *, size_t *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 4, 0))));
|
||||
int _EXFUN(_vasprintf_r, (struct _reent *, char **, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(_vdiprintf_r, (struct _reent *, int, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(_vdprintf_r, (struct _reent *, int, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(_vfiprintf_r, (struct _reent *, FILE *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(_vfiscanf_r, (struct _reent *, FILE *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 3, 0))));
|
||||
int _EXFUN(_vfprintf_r, (struct _reent *, FILE *__restrict, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(_vfscanf_r, (struct _reent *, FILE *__restrict, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 3, 0))));
|
||||
int _EXFUN(_viprintf_r, (struct _reent *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
int _EXFUN(_viscanf_r, (struct _reent *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 0))));
|
||||
int _EXFUN(_vprintf_r, (struct _reent *, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 2, 0))));
|
||||
int _EXFUN(_vscanf_r, (struct _reent *, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 2, 0))));
|
||||
int _EXFUN(_vsiprintf_r, (struct _reent *, char *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(_vsiscanf_r, (struct _reent *, const char *, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 3, 0))));
|
||||
int _EXFUN(_vsniprintf_r, (struct _reent *, char *, size_t, const char *, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 4, 0))));
|
||||
int _EXFUN(_vsnprintf_r, (struct _reent *, char *__restrict, size_t, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 4, 0))));
|
||||
int _EXFUN(_vsprintf_r, (struct _reent *, char *__restrict, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__printf__, 3, 0))));
|
||||
int _EXFUN(_vsscanf_r, (struct _reent *, const char *__restrict, const char *__restrict, __VALIST)
|
||||
_ATTRIBUTE ((__format__ (__scanf__, 3, 0))));
|
||||
|
||||
/* Other extensions. */
|
||||
|
||||
int _EXFUN(fpurge, (FILE *));
|
||||
ssize_t _EXFUN(__getdelim, (char **, size_t *, int, FILE *));
|
||||
ssize_t _EXFUN(__getline, (char **, size_t *, FILE *));
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
void _EXFUN(clearerr_unlocked, (FILE *));
|
||||
int _EXFUN(feof_unlocked, (FILE *));
|
||||
int _EXFUN(ferror_unlocked, (FILE *));
|
||||
int _EXFUN(fileno_unlocked, (FILE *));
|
||||
int _EXFUN(fflush_unlocked, (FILE *));
|
||||
int _EXFUN(fgetc_unlocked, (FILE *));
|
||||
int _EXFUN(fputc_unlocked, (int, FILE *));
|
||||
size_t _EXFUN(fread_unlocked, (_PTR __restrict, size_t _size, size_t _n, FILE *__restrict));
|
||||
size_t _EXFUN(fwrite_unlocked, (const _PTR __restrict , size_t _size, size_t _n, FILE *));
|
||||
#endif
|
||||
|
||||
#if __GNU_VISIBLE
|
||||
char * _EXFUN(fgets_unlocked, (char *__restrict, int, FILE *__restrict));
|
||||
int _EXFUN(fputs_unlocked, (const char *__restrict, FILE *__restrict));
|
||||
#endif
|
||||
|
||||
#ifdef __LARGE64_FILES
|
||||
#if !defined(__CYGWIN__) || defined(_COMPILING_NEWLIB)
|
||||
FILE * _EXFUN(fdopen64, (int, const char *));
|
||||
FILE * _EXFUN(fopen64, (const char *, const char *));
|
||||
FILE * _EXFUN(freopen64, (_CONST char *, _CONST char *, FILE *));
|
||||
_off64_t _EXFUN(ftello64, (FILE *));
|
||||
_off64_t _EXFUN(fseeko64, (FILE *, _off64_t, int));
|
||||
int _EXFUN(fgetpos64, (FILE *, _fpos64_t *));
|
||||
int _EXFUN(fsetpos64, (FILE *, const _fpos64_t *));
|
||||
FILE * _EXFUN(tmpfile64, (void));
|
||||
|
||||
FILE * _EXFUN(_fdopen64_r, (struct _reent *, int, const char *));
|
||||
FILE * _EXFUN(_fopen64_r, (struct _reent *,const char *, const char *));
|
||||
FILE * _EXFUN(_freopen64_r, (struct _reent *, _CONST char *, _CONST char *, FILE *));
|
||||
_off64_t _EXFUN(_ftello64_r, (struct _reent *, FILE *));
|
||||
_off64_t _EXFUN(_fseeko64_r, (struct _reent *, FILE *, _off64_t, int));
|
||||
int _EXFUN(_fgetpos64_r, (struct _reent *, FILE *, _fpos64_t *));
|
||||
int _EXFUN(_fsetpos64_r, (struct _reent *, FILE *, const _fpos64_t *));
|
||||
FILE * _EXFUN(_tmpfile64_r, (struct _reent *));
|
||||
#endif /* !__CYGWIN__ */
|
||||
#endif /* __LARGE64_FILES */
|
||||
|
||||
/*
|
||||
* Routines internal to the implementation.
|
||||
*/
|
||||
|
||||
int _EXFUN(__srget_r, (struct _reent *, FILE *));
|
||||
int _EXFUN(__swbuf_r, (struct _reent *, int, FILE *));
|
||||
|
||||
/*
|
||||
* Stdio function-access interface.
|
||||
*/
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
# ifdef __LARGE64_FILES
|
||||
FILE *_EXFUN(funopen,(const _PTR __cookie,
|
||||
int (*__readfn)(_PTR __c, char *__buf,
|
||||
_READ_WRITE_BUFSIZE_TYPE __n),
|
||||
int (*__writefn)(_PTR __c, const char *__buf,
|
||||
_READ_WRITE_BUFSIZE_TYPE __n),
|
||||
_fpos64_t (*__seekfn)(_PTR __c, _fpos64_t __off, int __whence),
|
||||
int (*__closefn)(_PTR __c)));
|
||||
FILE *_EXFUN(_funopen_r,(struct _reent *, const _PTR __cookie,
|
||||
int (*__readfn)(_PTR __c, char *__buf,
|
||||
_READ_WRITE_BUFSIZE_TYPE __n),
|
||||
int (*__writefn)(_PTR __c, const char *__buf,
|
||||
_READ_WRITE_BUFSIZE_TYPE __n),
|
||||
_fpos64_t (*__seekfn)(_PTR __c, _fpos64_t __off, int __whence),
|
||||
int (*__closefn)(_PTR __c)));
|
||||
# else
|
||||
FILE *_EXFUN(funopen,(const _PTR __cookie,
|
||||
int (*__readfn)(_PTR __cookie, char *__buf,
|
||||
_READ_WRITE_BUFSIZE_TYPE __n),
|
||||
int (*__writefn)(_PTR __cookie, const char *__buf,
|
||||
_READ_WRITE_BUFSIZE_TYPE __n),
|
||||
fpos_t (*__seekfn)(_PTR __cookie, fpos_t __off, int __whence),
|
||||
int (*__closefn)(_PTR __cookie)));
|
||||
FILE *_EXFUN(_funopen_r,(struct _reent *, const _PTR __cookie,
|
||||
int (*__readfn)(_PTR __cookie, char *__buf,
|
||||
_READ_WRITE_BUFSIZE_TYPE __n),
|
||||
int (*__writefn)(_PTR __cookie, const char *__buf,
|
||||
_READ_WRITE_BUFSIZE_TYPE __n),
|
||||
fpos_t (*__seekfn)(_PTR __cookie, fpos_t __off, int __whence),
|
||||
int (*__closefn)(_PTR __cookie)));
|
||||
# endif /* !__LARGE64_FILES */
|
||||
|
||||
# define fropen(__cookie, __fn) funopen(__cookie, __fn, (int (*)())0, \
|
||||
(fpos_t (*)())0, (int (*)())0)
|
||||
# define fwopen(__cookie, __fn) funopen(__cookie, (int (*)())0, __fn, \
|
||||
(fpos_t (*)())0, (int (*)())0)
|
||||
|
||||
typedef ssize_t cookie_read_function_t(void *__cookie, char *__buf, size_t __n);
|
||||
typedef ssize_t cookie_write_function_t(void *__cookie, const char *__buf,
|
||||
size_t __n);
|
||||
# ifdef __LARGE64_FILES
|
||||
typedef int cookie_seek_function_t(void *__cookie, _off64_t *__off,
|
||||
int __whence);
|
||||
# else
|
||||
typedef int cookie_seek_function_t(void *__cookie, off_t *__off, int __whence);
|
||||
# endif /* !__LARGE64_FILES */
|
||||
typedef int cookie_close_function_t(void *__cookie);
|
||||
typedef struct
|
||||
{
|
||||
/* These four struct member names are dictated by Linux; hopefully,
|
||||
they don't conflict with any macros. */
|
||||
cookie_read_function_t *read;
|
||||
cookie_write_function_t *write;
|
||||
cookie_seek_function_t *seek;
|
||||
cookie_close_function_t *close;
|
||||
} cookie_io_functions_t;
|
||||
FILE *_EXFUN(fopencookie,(void *__cookie,
|
||||
const char *__mode, cookie_io_functions_t __functions));
|
||||
FILE *_EXFUN(_fopencookie_r,(struct _reent *, void *__cookie,
|
||||
const char *__mode, cookie_io_functions_t __functions));
|
||||
#endif /* ! __STRICT_ANSI__ */
|
||||
|
||||
#ifndef __CUSTOM_FILE_IO__
|
||||
/*
|
||||
* The __sfoo macros are here so that we can
|
||||
* define function versions in the C library.
|
||||
*/
|
||||
#define __sgetc_raw_r(__ptr, __f) (--(__f)->_r < 0 ? __srget_r(__ptr, __f) : (int)(*(__f)->_p++))
|
||||
|
||||
#ifdef __SCLE
|
||||
/* For a platform with CR/LF, additional logic is required by
|
||||
__sgetc_r which would otherwise simply be a macro; therefore we
|
||||
use an inlined function. The function is only meant to be inlined
|
||||
in place as used and the function body should never be emitted.
|
||||
|
||||
There are two possible means to this end when compiling with GCC,
|
||||
one when compiling with a standard C99 compiler, and for other
|
||||
compilers we're just stuck. At the moment, this issue only
|
||||
affects the Cygwin target, so we'll most likely be using GCC. */
|
||||
|
||||
_ELIDABLE_INLINE int __sgetc_r(struct _reent *__ptr, FILE *__p);
|
||||
|
||||
_ELIDABLE_INLINE int __sgetc_r(struct _reent *__ptr, FILE *__p)
|
||||
{
|
||||
int __c = __sgetc_raw_r(__ptr, __p);
|
||||
if ((__p->_flags & __SCLE) && (__c == '\r'))
|
||||
{
|
||||
int __c2 = __sgetc_raw_r(__ptr, __p);
|
||||
if (__c2 == '\n')
|
||||
__c = __c2;
|
||||
else
|
||||
ungetc(__c2, __p);
|
||||
}
|
||||
return __c;
|
||||
}
|
||||
#else
|
||||
#define __sgetc_r(__ptr, __p) __sgetc_raw_r(__ptr, __p)
|
||||
#endif
|
||||
|
||||
#ifdef _never /* __GNUC__ */
|
||||
/* If this inline is actually used, then systems using coff debugging
|
||||
info get hopelessly confused. 21sept93 rich@cygnus.com. */
|
||||
_ELIDABLE_INLINE int __sputc_r(struct _reent *_ptr, int _c, FILE *_p) {
|
||||
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
|
||||
return (*_p->_p++ = _c);
|
||||
else
|
||||
return (__swbuf_r(_ptr, _c, _p));
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* This has been tuned to generate reasonable code on the vax using pcc
|
||||
*/
|
||||
#define __sputc_raw_r(__ptr, __c, __p) \
|
||||
(--(__p)->_w < 0 ? \
|
||||
(__p)->_w >= (__p)->_lbfsize ? \
|
||||
(*(__p)->_p = (__c)), *(__p)->_p != '\n' ? \
|
||||
(int)*(__p)->_p++ : \
|
||||
__swbuf_r(__ptr, '\n', __p) : \
|
||||
__swbuf_r(__ptr, (int)(__c), __p) : \
|
||||
(*(__p)->_p = (__c), (int)*(__p)->_p++))
|
||||
#ifdef __SCLE
|
||||
#define __sputc_r(__ptr, __c, __p) \
|
||||
((((__p)->_flags & __SCLE) && ((__c) == '\n')) \
|
||||
? __sputc_raw_r(__ptr, '\r', (__p)) : 0 , \
|
||||
__sputc_raw_r((__ptr), (__c), (__p)))
|
||||
#else
|
||||
#define __sputc_r(__ptr, __c, __p) __sputc_raw_r(__ptr, __c, __p)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define __sfeof(p) ((int)(((p)->_flags & __SEOF) != 0))
|
||||
#define __sferror(p) ((int)(((p)->_flags & __SERR) != 0))
|
||||
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
|
||||
#define __sfileno(p) ((p)->_file)
|
||||
|
||||
#ifndef _REENT_SMALL
|
||||
#define feof(p) __sfeof(p)
|
||||
#define ferror(p) __sferror(p)
|
||||
#define clearerr(p) __sclearerr(p)
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
#define feof_unlocked(p) __sfeof(p)
|
||||
#define ferror_unlocked(p) __sferror(p)
|
||||
#define clearerr_unlocked(p) __sclearerr(p)
|
||||
#endif /* __BSD_VISIBLE */
|
||||
#endif /* _REENT_SMALL */
|
||||
|
||||
#if 0 /*ndef __STRICT_ANSI__ - FIXME: must initialize stdio first, use fn */
|
||||
#define fileno(p) __sfileno(p)
|
||||
#endif
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
#ifndef lint
|
||||
#define getc(fp) __sgetc_r(_REENT, fp)
|
||||
#define putc(x, fp) __sputc_r(_REENT, x, fp)
|
||||
#endif /* lint */
|
||||
#endif /* __CYGWIN__ */
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
/* fast always-buffered version, true iff error */
|
||||
#define fast_putc(x,p) (--(p)->_w < 0 ? \
|
||||
__swbuf_r(_REENT, (int)(x), p) == EOF : (*(p)->_p = (x), (p)->_p++, 0))
|
||||
|
||||
#define L_cuserid 9 /* posix says it goes in stdio.h :( */
|
||||
#ifdef __CYGWIN__
|
||||
#define L_ctermid 16
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* !__CUSTOM_FILE_IO__ */
|
||||
|
||||
#define getchar() getc(stdin)
|
||||
#define putchar(x) putc(x, stdout)
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define getchar_unlocked() getc_unlocked(stdin)
|
||||
#define putchar_unlocked(x) putc_unlocked(x, stdout)
|
||||
#endif
|
||||
|
||||
_END_STD_C
|
||||
|
||||
#undef putchar
|
||||
#undef getchar
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* STDIO_H */
|
||||
@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 by
|
||||
* Ralf Corsepius, Ulm/Germany. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software
|
||||
* is freely granted, provided that this notice is preserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Modified _intsup.h for compilation with RIOT OS
|
||||
* Source: /path/to/newlib-xtensa/xtensa-lx106-elf/include/sys
|
||||
* Changes: __INT32 (see below)
|
||||
*/
|
||||
|
||||
#ifndef SYS__INTSUP_H
|
||||
#define SYS__INTSUP_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* additional header guard to avoid conflicts if original file is included later */
|
||||
#ifndef _SYS__INTSUP_H
|
||||
#define _SYS__INTSUP_H
|
||||
|
||||
#include <sys/features.h>
|
||||
|
||||
#if __GNUC_PREREQ (3, 2)
|
||||
/* gcc > 3.2 implicitly defines the values we are interested */
|
||||
#define __STDINT_EXP(x) __##x##__
|
||||
#else
|
||||
#define __STDINT_EXP(x) x
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
/* Determine how intptr_t and intN_t fastN_t and leastN_t are defined by gcc
|
||||
for this target. This is used to determine the correct printf() constant in
|
||||
inttypes.h and other constants in stdint.h.
|
||||
So we end up with
|
||||
?(signed|unsigned) char == 0
|
||||
?(signed|unsigned) short == 1
|
||||
?(signed|unsigned) int == 2
|
||||
?(signed|unsigned) short int == 3
|
||||
?(signed|unsigned) long == 4
|
||||
?(signed|unsigned) long int == 6
|
||||
?(signed|unsigned) long long == 8
|
||||
?(signed|unsigned) long long int == 10
|
||||
*/
|
||||
#pragma push_macro("signed")
|
||||
#pragma push_macro("unsigned")
|
||||
#pragma push_macro("char")
|
||||
#pragma push_macro("short")
|
||||
#pragma push_macro("__int20")
|
||||
#pragma push_macro("int")
|
||||
#pragma push_macro("long")
|
||||
#undef signed
|
||||
#undef unsigned
|
||||
#undef char
|
||||
#undef short
|
||||
#undef int
|
||||
#undef __int20
|
||||
#undef long
|
||||
#define signed +0
|
||||
#define unsigned +0
|
||||
#define char +0
|
||||
#define short +1
|
||||
#define __int20 +2
|
||||
#define int +2
|
||||
#define long +4
|
||||
#if (__INTPTR_TYPE__ == 8 || __INTPTR_TYPE__ == 10)
|
||||
#define _INTPTR_EQ_LONGLONG
|
||||
#elif (__INTPTR_TYPE__ == 4 || __INTPTR_TYPE__ == 6)
|
||||
#define _INTPTR_EQ_LONG
|
||||
/* Note - the tests for _INTPTR_EQ_INT and _INTPTR_EQ_SHORT are currently
|
||||
redundant as the values are not used. But one day they may be needed
|
||||
and so the tests remain. */
|
||||
#elif __INTPTR_TYPE__ == 2
|
||||
#define _INTPTR_EQ_INT
|
||||
#elif (__INTPTR_TYPE__ == 1 || __INTPTR_TYPE__ == 3)
|
||||
#define _INTPTR_EQ_SHORT
|
||||
#else
|
||||
#error "Unable to determine type definition of intptr_t"
|
||||
#endif
|
||||
#if (__INT32_TYPE__ == 4 || __INT32_TYPE__ == 6)
|
||||
#define _INT32_EQ_LONG
|
||||
#elif __INT32_TYPE__ == 2
|
||||
/* Nothing to define because int32_t is safe to print as an int. */
|
||||
#else
|
||||
#error "Unable to determine type definition of int32_t"
|
||||
#endif
|
||||
|
||||
#if (__INT8_TYPE__ == 0)
|
||||
#define __INT8 /* "hh" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT8_TYPE__ == 1 || __INT8_TYPE__ == 3)
|
||||
#define __INT8 /* "h" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT8_TYPE__ == 2)
|
||||
#define __INT8
|
||||
#elif (__INT8_TYPE__ == 4 || __INT8_TYPE__ == 6)
|
||||
#define __INT8 "l"
|
||||
#elif (__INT8_TYPE__ == 8 || __INT8_TYPE__ == 10)
|
||||
#define __INT8 "ll"
|
||||
#endif
|
||||
#if (__INT16_TYPE__ == 1 || __INT16_TYPE__ == 3)
|
||||
#define __INT16 /* "h" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT16_TYPE__ == 2)
|
||||
#define __INT16
|
||||
#elif (__INT16_TYPE__ == 4 || __INT16_TYPE__ == 6)
|
||||
#define __INT16 "l"
|
||||
#elif (__INT16_TYPE__ == 8 || __INT16_TYPE__ == 10)
|
||||
#define __INT16 "ll"
|
||||
#endif
|
||||
#if (__INT32_TYPE__ == 2)
|
||||
#define __INT32
|
||||
#elif (__INT32_TYPE__ == 4 || __INT32_TYPE__ == 6)
|
||||
/**
|
||||
* Definition of __INT32 had to be changed since to avoid format warnings/
|
||||
* errors since xtensa-lx106-elf-gcc defines *__INT32_TYPE__* as *long int*
|
||||
* while newlib defines *int32_t* as *signed int*. PRI*32 there throw format
|
||||
* warnings/errors.
|
||||
*/
|
||||
#if 0
|
||||
#define __INT32 "l"
|
||||
#else
|
||||
#define __INT32
|
||||
#endif
|
||||
#elif (__INT32_TYPE__ == 8 || __INT32_TYPE__ == 10)
|
||||
#define __INT32 "ll"
|
||||
#endif
|
||||
#if (__INT64_TYPE__ == 2)
|
||||
#define __INT64
|
||||
#elif (__INT64_TYPE__ == 4 || __INT64_TYPE__ == 6)
|
||||
#define __INT64 "l"
|
||||
#elif (__INT64_TYPE__ == 8 || __INT64_TYPE__ == 10)
|
||||
#define __INT64 "ll"
|
||||
#endif
|
||||
#if (__INT_FAST8_TYPE__ == 0)
|
||||
#define __FAST8 /* "hh" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT_FAST8_TYPE__ == 1 || __INT_FAST8_TYPE__ == 3)
|
||||
#define __FAST8 /* "h" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT_FAST8_TYPE__ == 2)
|
||||
#define __FAST8
|
||||
#elif (__INT_FAST8_TYPE__ == 4 || __INT_FAST8_TYPE__ == 6)
|
||||
#define __FAST8 "l"
|
||||
#elif (__INT_FAST8_TYPE__ == 8 || __INT_FAST8_TYPE__ == 10)
|
||||
#define __FAST8 "ll"
|
||||
#endif
|
||||
#if (__INT_FAST16_TYPE__ == 1 || __INT_FAST16_TYPE__ == 3)
|
||||
#define __FAST16 /* "h" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT_FAST16_TYPE__ == 2)
|
||||
#define __FAST16
|
||||
#elif (__INT_FAST16_TYPE__ == 4 || __INT_FAST16_TYPE__ == 6)
|
||||
#define __FAST16 "l"
|
||||
#elif (__INT_FAST16_TYPE__ == 8 || __INT_FAST16_TYPE__ == 10)
|
||||
#define __FAST16 "ll"
|
||||
#endif
|
||||
#if (__INT_FAST32_TYPE__ == 2)
|
||||
#define __FAST32
|
||||
#elif (__INT_FAST32_TYPE__ == 4 || __INT_FAST32_TYPE__ == 6)
|
||||
#define __FAST32 "l"
|
||||
#elif (__INT_FAST32_TYPE__ == 8 || __INT_FAST32_TYPE__ == 10)
|
||||
#define __FAST32 "ll"
|
||||
#endif
|
||||
#if (__INT_FAST64_TYPE__ == 2)
|
||||
#define __FAST64
|
||||
#elif (__INT_FAST64_TYPE__ == 4 || __INT_FAST64_TYPE__ == 6)
|
||||
#define __FAST64 "l"
|
||||
#elif (__INT_FAST64_TYPE__ == 8 || __INT_FAST64_TYPE__ == 10)
|
||||
#define __FAST64 "ll"
|
||||
#endif
|
||||
|
||||
#if (__INT_LEAST8_TYPE__ == 0)
|
||||
#define __LEAST8 /* "hh" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT_LEAST8_TYPE__ == 1 || __INT_LEAST8_TYPE__ == 3)
|
||||
#define __LEAST8 /* "h" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT_LEAST8_TYPE__ == 2)
|
||||
#define __LEAST8
|
||||
#elif (__INT_LEAST8_TYPE__ == 4 || __INT_LEAST8_TYPE__ == 6)
|
||||
#define __LEAST8 "l"
|
||||
#elif (__INT_LEAST8_TYPE__ == 8 || __INT_LEAST8_TYPE__ == 10)
|
||||
#define __LEAST8 "ll"
|
||||
#endif
|
||||
#if (__INT_LEAST16_TYPE__ == 1 || __INT_LEAST16_TYPE__ == 3)
|
||||
#define __LEAST16 /* "h" */ /* ets_printf doesn't support "h" */
|
||||
#elif (__INT_LEAST16_TYPE__ == 2)
|
||||
#define __LEAST16
|
||||
#elif (__INT_LEAST16_TYPE__ == 4 || __INT_LEAST16_TYPE__ == 6)
|
||||
#define __LEAST16 "l"
|
||||
#elif (__INT_LEAST16_TYPE__ == 8 || __INT_LEAST16_TYPE__ == 10)
|
||||
#define __LEAST16 "ll"
|
||||
#endif
|
||||
#if (__INT_LEAST32_TYPE__ == 2)
|
||||
#define __LEAST32
|
||||
#elif (__INT_LEAST32_TYPE__ == 4 || __INT_LEAST32_TYPE__ == 6)
|
||||
#define __LEAST32 "l"
|
||||
#elif (__INT_LEAST32_TYPE__ == 8 || __INT_LEAST32_TYPE__ == 10)
|
||||
#define __LEAST32 "ll"
|
||||
#endif
|
||||
#if (__INT_LEAST64_TYPE__ == 2)
|
||||
#define __LEAST64
|
||||
#elif (__INT_LEAST64_TYPE__ == 4 || __INT_LEAST64_TYPE__ == 6)
|
||||
#define __LEAST64 "l"
|
||||
#elif (__INT_LEAST64_TYPE__ == 8 || __INT_LEAST64_TYPE__ == 10)
|
||||
#define __LEAST64 "ll"
|
||||
#endif
|
||||
#undef signed
|
||||
#undef unsigned
|
||||
#undef char
|
||||
#undef short
|
||||
#undef int
|
||||
#undef long
|
||||
#pragma pop_macro("signed")
|
||||
#pragma pop_macro("unsigned")
|
||||
#pragma pop_macro("char")
|
||||
#pragma pop_macro("short")
|
||||
#pragma pop_macro("__int20")
|
||||
#pragma pop_macro("int")
|
||||
#pragma pop_macro("long")
|
||||
|
||||
#endif /* _SYS__INTSUP_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* SYS__INTSUP_H */
|
||||
337
cpu/esp8266/include/sys/types.h
Normal file
337
cpu/esp8266/include/sys/types.h
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief This file is a modification of original sys/types.h
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* This file is just a wrapper around sys/types.h to fix missing types
|
||||
* fsblkcnt_t and fsfilcnt_t needed in statvfs.h and to avoid type conflicts
|
||||
* with pthread types from pthread module.
|
||||
*/
|
||||
|
||||
|
||||
/* unified sys/types.h:
|
||||
start with sef's sysvi386 version.
|
||||
merge go32 version -- a few ifdefs.
|
||||
h8300hms, h8300xray, and sysvnecv70 disagree on the following types:
|
||||
|
||||
typedef int gid_t;
|
||||
typedef int uid_t;
|
||||
typedef int dev_t;
|
||||
typedef int ino_t;
|
||||
typedef int mode_t;
|
||||
typedef int caddr_t;
|
||||
|
||||
however, these aren't "reasonable" values, the sysvi386 ones make far
|
||||
more sense, and should work sufficiently well (in particular, h8300
|
||||
doesn't have a stat, and the necv70 doesn't matter.) -- eichin
|
||||
*/
|
||||
|
||||
#ifndef SYS_TYPES_H
|
||||
#define SYS_TYPES_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _FSBLKCNT_T_DECLARED
|
||||
#include <stdint.h>
|
||||
typedef uint32_t fsblkcnt_t;
|
||||
typedef uint32_t fsfilcnt_t;
|
||||
#define _FSBLKCNT_T_DECLARED
|
||||
#endif
|
||||
|
||||
#ifndef _SYS_TYPES_H
|
||||
|
||||
#include <_ansi.h>
|
||||
|
||||
#ifndef __INTTYPES_DEFINED__
|
||||
#define __INTTYPES_DEFINED__
|
||||
|
||||
#include <machine/_types.h>
|
||||
|
||||
#if defined(__rtems__) || defined(__XMK__)
|
||||
/*
|
||||
* The following section is RTEMS specific and is needed to more
|
||||
* closely match the types defined in the BSD sys/types.h.
|
||||
* This is needed to let the RTEMS/BSD TCP/IP stack compile.
|
||||
*/
|
||||
|
||||
/* deprecated */
|
||||
#if ___int8_t_defined
|
||||
typedef __uint8_t u_int8_t;
|
||||
#endif
|
||||
#if ___int16_t_defined
|
||||
typedef __uint16_t u_int16_t;
|
||||
#endif
|
||||
#if ___int32_t_defined
|
||||
typedef __uint32_t u_int32_t;
|
||||
#endif
|
||||
|
||||
#if ___int64_t_defined
|
||||
typedef __uint64_t u_int64_t;
|
||||
|
||||
/* deprecated */
|
||||
typedef __uint64_t u_quad_t;
|
||||
typedef __int64_t quad_t;
|
||||
typedef quad_t * qaddr_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ! __INTTYPES_DEFINED */
|
||||
|
||||
#ifndef __need_inttypes
|
||||
|
||||
#define _SYS_TYPES_H
|
||||
#include <sys/_types.h>
|
||||
|
||||
#ifdef __i386__
|
||||
#if defined (GO32) || defined (__MSDOS__)
|
||||
#define __MS_types__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
# include <stddef.h>
|
||||
# include <machine/types.h>
|
||||
|
||||
/* To ensure the stat struct's layout doesn't change when sizeof(int), etc.
|
||||
changes, we assume sizeof short and long never change and have all types
|
||||
used to define struct stat use them and not int where possible.
|
||||
Where not possible, _ST_INTxx are used. It would be preferable to not have
|
||||
such assumptions, but until the extra fluff is necessary, it's avoided.
|
||||
No 64 bit targets use stat yet. What to do about them is postponed
|
||||
until necessary. */
|
||||
#ifdef __GNUC__
|
||||
#define _ST_INT32 __attribute__ ((__mode__ (__SI__)))
|
||||
#else
|
||||
#define _ST_INT32
|
||||
#endif
|
||||
|
||||
# ifndef _POSIX_SOURCE
|
||||
|
||||
# define physadr physadr_t
|
||||
# define quad quad_t
|
||||
|
||||
#ifndef _BSDTYPES_DEFINED
|
||||
/* also defined in mingw/gmon.h and in w32api/winsock[2].h */
|
||||
#ifndef __u_char_defined
|
||||
typedef unsigned char u_char;
|
||||
#define __u_char_defined
|
||||
#endif
|
||||
#ifndef __u_short_defined
|
||||
typedef unsigned short u_short;
|
||||
#define __u_short_defined
|
||||
#endif
|
||||
#ifndef __u_int_defined
|
||||
typedef unsigned int u_int;
|
||||
#define __u_int_defined
|
||||
#endif
|
||||
#ifndef __u_long_defined
|
||||
typedef unsigned long u_long;
|
||||
#define __u_long_defined
|
||||
#endif
|
||||
#define _BSDTYPES_DEFINED
|
||||
#endif
|
||||
|
||||
typedef unsigned short ushort; /* System V compatibility */
|
||||
typedef unsigned int uint; /* System V compatibility */
|
||||
typedef unsigned long ulong; /* System V compatibility */
|
||||
# endif /*!_POSIX_SOURCE */
|
||||
|
||||
#ifndef __clock_t_defined
|
||||
typedef _CLOCK_T_ clock_t;
|
||||
#define __clock_t_defined
|
||||
#endif
|
||||
|
||||
#ifndef __time_t_defined
|
||||
typedef _TIME_T_ time_t;
|
||||
#define __time_t_defined
|
||||
#endif
|
||||
|
||||
#ifndef __timespec_defined
|
||||
#define __timespec_defined
|
||||
/* Time Value Specification Structures, P1003.1b-1993, p. 261 */
|
||||
|
||||
struct timespec {
|
||||
time_t tv_sec; /* Seconds */
|
||||
long tv_nsec; /* Nanoseconds */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct itimerspec {
|
||||
struct timespec it_interval; /* Timer period */
|
||||
struct timespec it_value; /* Timer expiration */
|
||||
};
|
||||
|
||||
#ifndef __daddr_t_defined
|
||||
typedef long daddr_t;
|
||||
#define __daddr_t_defined
|
||||
#endif
|
||||
#ifndef __caddr_t_defined
|
||||
typedef char * caddr_t;
|
||||
#define __caddr_t_defined
|
||||
#endif
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
#if defined(__MS_types__) || defined(__rtems__) || \
|
||||
defined(__sparc__) || defined(__SPU__)
|
||||
typedef unsigned long ino_t;
|
||||
#else
|
||||
typedef unsigned short ino_t;
|
||||
#endif
|
||||
#endif /*__CYGWIN__*/
|
||||
|
||||
#ifdef __MS_types__
|
||||
typedef unsigned long vm_offset_t;
|
||||
typedef unsigned long vm_size_t;
|
||||
|
||||
#define __BIT_TYPES_DEFINED__
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char u_int8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short u_int16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int u_int32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long u_int64_t;
|
||||
typedef int32_t register_t;
|
||||
#endif /* __MS_types__ */
|
||||
|
||||
/*
|
||||
* All these should be machine specific - right now they are all broken.
|
||||
* However, for all of Cygnus' embedded targets, we want them to all be
|
||||
* the same. Otherwise things like sizeof (struct stat) might depend on
|
||||
* how the file was compiled (e.g. -mint16 vs -mint32, etc.).
|
||||
*/
|
||||
|
||||
#ifndef __CYGWIN__ /* which defines these types in it's own types.h. */
|
||||
typedef _off_t off_t;
|
||||
typedef __dev_t dev_t;
|
||||
typedef __uid_t uid_t;
|
||||
typedef __gid_t gid_t;
|
||||
#endif
|
||||
|
||||
#if defined(__XMK__)
|
||||
typedef signed char pid_t;
|
||||
#else
|
||||
typedef int pid_t;
|
||||
#endif
|
||||
|
||||
#if defined(__rtems__)
|
||||
typedef _mode_t mode_t;
|
||||
#endif
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
typedef long key_t;
|
||||
#endif
|
||||
typedef _ssize_t ssize_t;
|
||||
|
||||
#if !defined(__CYGWIN__) && !defined(__rtems__)
|
||||
#ifdef __MS_types__
|
||||
typedef char * addr_t;
|
||||
typedef int mode_t;
|
||||
#else
|
||||
#if defined (__sparc__) && !defined (__sparc_v9__)
|
||||
#ifdef __svr4__
|
||||
typedef unsigned long mode_t;
|
||||
#else
|
||||
typedef unsigned short mode_t;
|
||||
#endif
|
||||
#else
|
||||
typedef unsigned int mode_t _ST_INT32;
|
||||
#endif
|
||||
#endif /* ! __MS_types__ */
|
||||
#endif /*__CYGWIN__*/
|
||||
|
||||
typedef unsigned short nlink_t;
|
||||
|
||||
/* We don't define fd_set and friends if we are compiling POSIX
|
||||
source, or if we have included (or may include as indicated
|
||||
by __USE_W32_SOCKETS) the W32api winsock[2].h header which
|
||||
defines Windows versions of them. Note that a program which
|
||||
includes the W32api winsock[2].h header must know what it is doing;
|
||||
it must not call the cygwin32 select function.
|
||||
*/
|
||||
# if !(defined (_POSIX_SOURCE) || defined (_WINSOCK_H) || defined (_WINSOCKAPI_) || defined (__USE_W32_SOCKETS))
|
||||
# define _SYS_TYPES_FD_SET
|
||||
# define NBBY 8 /* number of bits in a byte */
|
||||
/*
|
||||
* Select uses bit masks of file descriptors in longs.
|
||||
* These macros manipulate such bit fields (the filesystem macros use chars).
|
||||
* FD_SETSIZE may be defined by the user, but the default here
|
||||
* should be >= NOFILE (param.h).
|
||||
*/
|
||||
# ifndef FD_SETSIZE
|
||||
# define FD_SETSIZE 64
|
||||
# endif
|
||||
|
||||
typedef long fd_mask;
|
||||
# define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
|
||||
# ifndef howmany
|
||||
# define howmany(x,y) (((x)+((y)-1))/(y))
|
||||
# endif
|
||||
|
||||
/* We use a macro for fd_set so that including Sockets.h afterwards
|
||||
can work. */
|
||||
typedef struct _types_fd_set {
|
||||
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
|
||||
} _types_fd_set;
|
||||
|
||||
#define fd_set _types_fd_set
|
||||
|
||||
# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
|
||||
# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
|
||||
# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
|
||||
# define FD_ZERO(p) (__extension__ (void)({ \
|
||||
size_t __i; \
|
||||
char *__tmp = (char *)p; \
|
||||
for (__i = 0; __i < sizeof (*(p)); ++__i) \
|
||||
*__tmp++ = 0; \
|
||||
}))
|
||||
|
||||
# endif /* !(defined (_POSIX_SOURCE) || defined (_WINSOCK_H) || defined (_WINSOCKAPI_) || defined (__USE_W32_SOCKETS)) */
|
||||
|
||||
#undef __MS_types__
|
||||
#undef _ST_INT32
|
||||
|
||||
|
||||
#ifndef __clockid_t_defined
|
||||
typedef _CLOCKID_T_ clockid_t;
|
||||
#define __clockid_t_defined
|
||||
#endif
|
||||
|
||||
#ifndef __timer_t_defined
|
||||
typedef _TIMER_T_ timer_t;
|
||||
#define __timer_t_defined
|
||||
#endif
|
||||
|
||||
typedef unsigned long useconds_t;
|
||||
typedef long suseconds_t;
|
||||
|
||||
#endif /* !__need_inttypes */
|
||||
|
||||
#undef __need_inttypes
|
||||
|
||||
#endif /* _SYS_TYPES_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* SYS_TYPES_H */
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -35,12 +36,24 @@ extern void syscalls_init (void);
|
||||
/** System standard printf function */
|
||||
extern int printf(const char* format, ...);
|
||||
|
||||
/** Determine free heap size */
|
||||
unsigned int get_free_heap_size (void);
|
||||
|
||||
/** System standard puts function */
|
||||
extern int puts(const char * str);
|
||||
|
||||
/** Determine free heap size */
|
||||
extern unsigned int get_free_heap_size (void);
|
||||
|
||||
/** Time since boot in us (32bit version) */
|
||||
uint32_t system_get_time (void);
|
||||
|
||||
/** Time since boot in ms (32bit version) */
|
||||
uint32_t system_get_time_ms (void);
|
||||
|
||||
/** memset version that the compiler should not be allowed to optimize this */
|
||||
void *system_secure_memset(void *s, int c, size_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @brief Default configurations required by the SDK
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @file
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef USER_CONFIG_H
|
||||
#define USER_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default CPU frequency in MHz.
|
||||
* Possible values are 80 and 160.
|
||||
*/
|
||||
#ifndef ESP8266_CPU_FREQUENCY
|
||||
#define ESP8266_CPU_FREQUENCY 80
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USER_CONFIG_H */
|
||||
/** @} */
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -18,7 +18,7 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <stdint.h>
|
||||
@ -27,10 +27,9 @@
|
||||
#include "irq.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "esp_common.h"
|
||||
#include "esp/common_macros.h"
|
||||
#include "esp/xtensa_ops.h"
|
||||
#include "sdk/ets.h"
|
||||
#include "xtensa/xtensa_context.h"
|
||||
|
||||
/**
|
||||
@ -46,9 +45,9 @@ unsigned int IRAM irq_disable(void)
|
||||
uint32_t _saved_interrupt_level;
|
||||
|
||||
/* read and set interrupt level (RSIL) */
|
||||
__asm__ volatile ("rsil %0, " XTSTR(XCHAL_NUM_INTLEVELS+1) : "=a" (_saved_interrupt_level));
|
||||
__asm__ volatile ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) : "=a" (_saved_interrupt_level));
|
||||
DEBUG ("%s %02x(%02x)\n", __func__,
|
||||
(_saved_interrupt_level & 0xfffffff0) | (XCHAL_NUM_INTLEVELS+1),
|
||||
(_saved_interrupt_level & 0xfffffff0) | (XCHAL_EXCM_LEVEL),
|
||||
_saved_interrupt_level);
|
||||
return _saved_interrupt_level;
|
||||
}
|
||||
@ -62,7 +61,7 @@ unsigned int IRAM irq_enable(void)
|
||||
|
||||
/* read and set interrupt level (RSIL) */
|
||||
__asm__ volatile ("rsil %0, 0" : "=a" (_saved_interrupt_level));
|
||||
DEBUG ("%s %02x(%02x)\n", __func__,
|
||||
DEBUG ("%s %02x (%02x)\n", __func__,
|
||||
_saved_interrupt_level & 0xfffffff0, _saved_interrupt_level);
|
||||
return _saved_interrupt_level;
|
||||
}
|
||||
|
||||
@ -1,350 +0,0 @@
|
||||
PROVIDE ( Cache_Read_Disable = 0x400047f0 );
|
||||
PROVIDE ( Cache_Read_Enable = 0x40004678 );
|
||||
PROVIDE ( FilePacketSendReqMsgProc = 0x400035a0 );
|
||||
PROVIDE ( FlashDwnLdParamCfgMsgProc = 0x4000368c );
|
||||
PROVIDE ( FlashDwnLdStartMsgProc = 0x40003538 );
|
||||
PROVIDE ( FlashDwnLdStopReqMsgProc = 0x40003658 );
|
||||
PROVIDE ( GetUartDevice = 0x40003f4c );
|
||||
PROVIDE ( MD5Final = 0x40009900 );
|
||||
PROVIDE ( MD5Init = 0x40009818 );
|
||||
PROVIDE ( MD5Update = 0x40009834 );
|
||||
PROVIDE ( MemDwnLdStartMsgProc = 0x400036c4 );
|
||||
PROVIDE ( MemDwnLdStopReqMsgProc = 0x4000377c );
|
||||
PROVIDE ( MemPacketSendReqMsgProc = 0x400036f0 );
|
||||
PROVIDE ( RcvMsg = 0x40003eac );
|
||||
PROVIDE ( SHA1Final = 0x4000b648 );
|
||||
PROVIDE ( SHA1Init = 0x4000b584 );
|
||||
PROVIDE ( SHA1Transform = 0x4000a364 );
|
||||
PROVIDE ( SHA1Update = 0x4000b5a8 );
|
||||
PROVIDE ( SPI_read_status = 0x400043c8 );
|
||||
PROVIDE ( SPI_write_status = 0x40004400 );
|
||||
PROVIDE ( SPI_write_enable = 0x4000443c );
|
||||
PROVIDE ( Wait_SPI_Idle = 0x4000448c );
|
||||
PROVIDE ( Enable_QMode = 0x400044c0 );
|
||||
PROVIDE ( SPIEraseArea = 0x40004b44 );
|
||||
PROVIDE ( SPIEraseBlock = 0x400049b4 );
|
||||
PROVIDE ( SPIEraseChip = 0x40004984 );
|
||||
PROVIDE ( SPIEraseSector = 0x40004a00 );
|
||||
PROVIDE ( SPILock = 0x400048a8 );
|
||||
PROVIDE ( SPIParamCfg = 0x40004c2c );
|
||||
PROVIDE ( SPIRead = 0x40004b1c );
|
||||
PROVIDE ( SPIReadModeCnfig = 0x400048ec );
|
||||
PROVIDE ( SPIUnlock = 0x40004878 );
|
||||
PROVIDE ( SPIWrite = 0x40004a4c );
|
||||
PROVIDE ( SelectSpiFunction = 0x40003f58 );
|
||||
PROVIDE ( SendMsg = 0x40003cf4 );
|
||||
PROVIDE ( UartConnCheck = 0x40003230 );
|
||||
PROVIDE ( UartConnectProc = 0x400037a0 );
|
||||
PROVIDE ( UartDwnLdProc = 0x40003368 );
|
||||
PROVIDE ( UartGetCmdLn = 0x40003ef4 );
|
||||
PROVIDE ( UartRegReadProc = 0x4000381c );
|
||||
PROVIDE ( UartRegWriteProc = 0x400037ac );
|
||||
PROVIDE ( UartRxString = 0x40003c30 );
|
||||
PROVIDE ( Uart_Init = 0x40003a14 );
|
||||
PROVIDE ( _DebugExceptionVector = 0x40000010 );
|
||||
PROVIDE ( _DoubleExceptionVector = 0x40000070 );
|
||||
PROVIDE ( _KernelExceptionVector = 0x40000030 );
|
||||
PROVIDE ( _NMIExceptionVector = 0x40000020 );
|
||||
PROVIDE ( _ResetHandler = 0x400000a4 );
|
||||
PROVIDE ( _ResetVector = 0x40000080 );
|
||||
PROVIDE ( _UserExceptionVector = 0x40000050 );
|
||||
PROVIDE ( __adddf3 = 0x4000c538 );
|
||||
PROVIDE ( __addsf3 = 0x4000c180 );
|
||||
PROVIDE ( __divdf3 = 0x4000cb94 );
|
||||
PROVIDE ( __divdi3 = 0x4000ce60 );
|
||||
PROVIDE ( __divsi3 = 0x4000dc88 );
|
||||
PROVIDE ( __extendsfdf2 = 0x4000cdfc );
|
||||
PROVIDE ( __fixdfsi = 0x4000ccb8 );
|
||||
PROVIDE ( __fixunsdfsi = 0x4000cd00 );
|
||||
PROVIDE ( __fixunssfsi = 0x4000c4c4 );
|
||||
PROVIDE ( __floatsidf = 0x4000e2f0 );
|
||||
PROVIDE ( __floatsisf = 0x4000e2ac );
|
||||
PROVIDE ( __floatunsidf = 0x4000e2e8 );
|
||||
PROVIDE ( __floatunsisf = 0x4000e2a4 );
|
||||
PROVIDE ( __muldf3 = 0x4000c8f0 );
|
||||
PROVIDE ( __muldi3 = 0x40000650 );
|
||||
PROVIDE ( __mulsf3 = 0x4000c3dc );
|
||||
PROVIDE ( __subdf3 = 0x4000c688 );
|
||||
PROVIDE ( __subsf3 = 0x4000c268 );
|
||||
PROVIDE ( __truncdfsf2 = 0x4000cd5c );
|
||||
PROVIDE ( __udivdi3 = 0x4000d310 );
|
||||
PROVIDE ( __udivsi3 = 0x4000e21c );
|
||||
PROVIDE ( __umoddi3 = 0x4000d770 );
|
||||
PROVIDE ( __umodsi3 = 0x4000e268 );
|
||||
PROVIDE ( __umulsidi3 = 0x4000dcf0 );
|
||||
PROVIDE ( _rom_store = 0x4000e388 );
|
||||
PROVIDE ( _rom_store_table = 0x4000e328 );
|
||||
PROVIDE ( _start = 0x4000042c );
|
||||
PROVIDE ( _xtos_alloca_handler = 0x4000dbe0 );
|
||||
PROVIDE ( _xtos_c_wrapper_handler = 0x40000598 );
|
||||
PROVIDE ( _xtos_cause3_handler = 0x40000590 );
|
||||
PROVIDE ( _xtos_ints_off = 0x4000bda4 );
|
||||
PROVIDE ( _xtos_ints_on = 0x4000bd84 );
|
||||
PROVIDE ( _xtos_l1int_handler = 0x4000048c );
|
||||
PROVIDE ( _xtos_p_none = 0x4000dbf8 );
|
||||
PROVIDE ( _xtos_restore_intlevel = 0x4000056c );
|
||||
PROVIDE ( _xtos_return_from_exc = 0x4000dc54 );
|
||||
PROVIDE ( _xtos_set_exception_handler = 0x40000454 );
|
||||
PROVIDE ( _xtos_set_interrupt_handler = 0x4000bd70 );
|
||||
PROVIDE ( _xtos_set_interrupt_handler_arg = 0x4000bd28 );
|
||||
PROVIDE ( _xtos_set_intlevel = 0x4000dbfc );
|
||||
PROVIDE ( _xtos_set_min_intlevel = 0x4000dc18 );
|
||||
PROVIDE ( _xtos_set_vpri = 0x40000574 );
|
||||
PROVIDE ( _xtos_syscall_handler = 0x4000dbe4 );
|
||||
PROVIDE ( _xtos_unhandled_exception = 0x4000dc44 );
|
||||
PROVIDE ( _xtos_unhandled_interrupt = 0x4000dc3c );
|
||||
PROVIDE ( aes_decrypt = 0x400092d4 );
|
||||
PROVIDE ( aes_decrypt_deinit = 0x400092e4 );
|
||||
PROVIDE ( aes_decrypt_init = 0x40008ea4 );
|
||||
PROVIDE ( aes_unwrap = 0x40009410 );
|
||||
PROVIDE ( base64_decode = 0x40009648 );
|
||||
PROVIDE ( base64_encode = 0x400094fc );
|
||||
PROVIDE ( bzero = 0x4000de84 );
|
||||
PROVIDE ( cmd_parse = 0x40000814 );
|
||||
PROVIDE ( conv_str_decimal = 0x40000b24 );
|
||||
PROVIDE ( conv_str_hex = 0x40000cb8 );
|
||||
PROVIDE ( convert_para_str = 0x40000a60 );
|
||||
PROVIDE ( dtm_get_intr_mask = 0x400026d0 );
|
||||
PROVIDE ( dtm_params_init = 0x4000269c );
|
||||
PROVIDE ( dtm_set_intr_mask = 0x400026c8 );
|
||||
PROVIDE ( dtm_set_params = 0x400026dc );
|
||||
PROVIDE ( eprintf = 0x40001d14 );
|
||||
PROVIDE ( eprintf_init_buf = 0x40001cb8 );
|
||||
PROVIDE ( eprintf_to_host = 0x40001d48 );
|
||||
PROVIDE ( est_get_printf_buf_remain_len = 0x40002494 );
|
||||
PROVIDE ( est_reset_printf_buf_len = 0x4000249c );
|
||||
PROVIDE ( ets_bzero = 0x40002ae8 );
|
||||
PROVIDE ( ets_char2xdigit = 0x40002b74 );
|
||||
PROVIDE ( ets_delay_us = 0x40002ecc );
|
||||
PROVIDE ( ets_enter_sleep = 0x400027b8 );
|
||||
PROVIDE ( ets_external_printf = 0x40002578 );
|
||||
PROVIDE ( ets_get_cpu_frequency = 0x40002f0c );
|
||||
PROVIDE ( ets_getc = 0x40002bcc );
|
||||
PROVIDE ( ets_install_external_printf = 0x40002450 );
|
||||
PROVIDE ( ets_install_putc1 = 0x4000242c );
|
||||
PROVIDE ( ets_install_putc2 = 0x4000248c );
|
||||
PROVIDE ( ets_install_uart_printf = 0x40002438 );
|
||||
PROVIDE ( ets_intr_lock = 0x40000f74 );
|
||||
PROVIDE ( ets_intr_unlock = 0x40000f80 );
|
||||
PROVIDE ( ets_isr_attach = 0x40000f88 );
|
||||
PROVIDE ( ets_isr_mask = 0x40000f98 );
|
||||
PROVIDE ( ets_isr_unmask = 0x40000fa8 );
|
||||
PROVIDE ( ets_memcmp = 0x400018d4 );
|
||||
PROVIDE ( ets_memcpy = 0x400018b4 );
|
||||
PROVIDE ( ets_memmove = 0x400018c4 );
|
||||
PROVIDE ( ets_memset = 0x400018a4 );
|
||||
PROVIDE ( ets_post = 0x40000e24 );
|
||||
PROVIDE ( ets_printf = 0x400024cc );
|
||||
PROVIDE ( ets_putc = 0x40002be8 );
|
||||
PROVIDE ( ets_rtc_int_register = 0x40002a40 );
|
||||
PROVIDE ( ets_run = 0x40000e04 );
|
||||
PROVIDE ( ets_set_idle_cb = 0x40000dc0 );
|
||||
PROVIDE ( ets_set_user_start = 0x40000fbc );
|
||||
PROVIDE ( ets_str2macaddr = 0x40002af8 );
|
||||
PROVIDE ( ets_strcmp = 0x40002aa8 );
|
||||
PROVIDE ( ets_strcpy = 0x40002a88 );
|
||||
PROVIDE ( ets_strlen = 0x40002ac8 );
|
||||
PROVIDE ( ets_strncmp = 0x40002ab8 );
|
||||
PROVIDE ( ets_strncpy = 0x40002a98 );
|
||||
PROVIDE ( ets_strstr = 0x40002ad8 );
|
||||
PROVIDE ( ets_task = 0x40000dd0 );
|
||||
PROVIDE ( ets_timer_arm = 0x40002cc4 );
|
||||
PROVIDE ( ets_timer_disarm = 0x40002d40 );
|
||||
PROVIDE ( ets_timer_done = 0x40002d80 );
|
||||
PROVIDE ( ets_timer_handler_isr = 0x40002da8 );
|
||||
PROVIDE ( ets_timer_init = 0x40002e68 );
|
||||
PROVIDE ( ets_timer_setfn = 0x40002c48 );
|
||||
PROVIDE ( ets_uart_printf = 0x40002544 );
|
||||
PROVIDE ( ets_update_cpu_frequency = 0x40002f04 );
|
||||
PROVIDE ( ets_vprintf = 0x40001f00 );
|
||||
PROVIDE ( ets_wdt_disable = 0x400030f0 );
|
||||
PROVIDE ( ets_wdt_enable = 0x40002fa0 );
|
||||
PROVIDE ( ets_wdt_get_mode = 0x40002f34 );
|
||||
PROVIDE ( ets_wdt_init = 0x40003170 );
|
||||
PROVIDE ( ets_wdt_restore = 0x40003158 );
|
||||
PROVIDE ( ets_write_char = 0x40001da0 );
|
||||
PROVIDE ( get_first_seg = 0x4000091c );
|
||||
PROVIDE ( gpio_init = 0x40004c50 );
|
||||
PROVIDE ( gpio_input_get = 0x40004cf0 );
|
||||
PROVIDE ( gpio_intr_ack = 0x40004dcc );
|
||||
PROVIDE ( gpio_intr_handler_register = 0x40004e28 );
|
||||
PROVIDE ( gpio_intr_pending = 0x40004d88 );
|
||||
PROVIDE ( gpio_intr_test = 0x40004efc );
|
||||
PROVIDE ( gpio_output_set = 0x40004cd0 );
|
||||
PROVIDE ( gpio_pin_intr_state_set = 0x40004d90 );
|
||||
PROVIDE ( gpio_pin_wakeup_disable = 0x40004ed4 );
|
||||
PROVIDE ( gpio_pin_wakeup_enable = 0x40004e90 );
|
||||
PROVIDE ( gpio_register_get = 0x40004d5c );
|
||||
PROVIDE ( gpio_register_set = 0x40004d04 );
|
||||
PROVIDE ( hmac_md5 = 0x4000a2cc );
|
||||
PROVIDE ( hmac_md5_vector = 0x4000a160 );
|
||||
PROVIDE ( hmac_sha1 = 0x4000ba28 );
|
||||
PROVIDE ( hmac_sha1_vector = 0x4000b8b4 );
|
||||
PROVIDE ( lldesc_build_chain = 0x40004f40 );
|
||||
PROVIDE ( lldesc_num2link = 0x40005050 );
|
||||
PROVIDE ( lldesc_set_owner = 0x4000507c );
|
||||
PROVIDE ( main = 0x40000fec );
|
||||
PROVIDE ( md5_vector = 0x400097ac );
|
||||
PROVIDE ( mem_calloc = 0x40001c2c );
|
||||
PROVIDE ( mem_free = 0x400019e0 );
|
||||
PROVIDE ( mem_init = 0x40001998 );
|
||||
PROVIDE ( mem_malloc = 0x40001b40 );
|
||||
PROVIDE ( mem_realloc = 0x40001c6c );
|
||||
PROVIDE ( mem_trim = 0x40001a14 );
|
||||
PROVIDE ( mem_zalloc = 0x40001c58 );
|
||||
PROVIDE ( memcmp = 0x4000dea8 );
|
||||
PROVIDE ( memcpy = 0x4000df48 );
|
||||
PROVIDE ( memmove = 0x4000e04c );
|
||||
PROVIDE ( memset = 0x4000e190 );
|
||||
PROVIDE ( multofup = 0x400031c0 );
|
||||
PROVIDE ( pbkdf2_sha1 = 0x4000b840 );
|
||||
PROVIDE ( phy_get_romfuncs = 0x40006b08 );
|
||||
PROVIDE ( rand = 0x40000600 );
|
||||
PROVIDE ( rc4_skip = 0x4000dd68 );
|
||||
PROVIDE ( recv_packet = 0x40003d08 );
|
||||
PROVIDE ( remove_head_space = 0x40000a04 );
|
||||
PROVIDE ( rijndaelKeySetupDec = 0x40008dd0 );
|
||||
PROVIDE ( rijndaelKeySetupEnc = 0x40009300 );
|
||||
PROVIDE ( rom_abs_temp = 0x400060c0 );
|
||||
PROVIDE ( rom_ana_inf_gating_en = 0x40006b10 );
|
||||
PROVIDE ( rom_cal_tos_v50 = 0x40007a28 );
|
||||
PROVIDE ( rom_chip_50_set_channel = 0x40006f84 );
|
||||
PROVIDE ( rom_chip_v5_disable_cca = 0x400060d0 );
|
||||
PROVIDE ( rom_chip_v5_enable_cca = 0x400060ec );
|
||||
PROVIDE ( rom_chip_v5_rx_init = 0x4000711c );
|
||||
PROVIDE ( rom_chip_v5_sense_backoff = 0x4000610c );
|
||||
PROVIDE ( rom_chip_v5_tx_init = 0x4000718c );
|
||||
PROVIDE ( rom_dc_iq_est = 0x4000615c );
|
||||
PROVIDE ( rom_en_pwdet = 0x400061b8 );
|
||||
PROVIDE ( rom_get_bb_atten = 0x40006238 );
|
||||
PROVIDE ( rom_get_corr_power = 0x40006260 );
|
||||
PROVIDE ( rom_get_fm_sar_dout = 0x400062dc );
|
||||
PROVIDE ( rom_get_noisefloor = 0x40006394 );
|
||||
PROVIDE ( rom_get_power_db = 0x400063b0 );
|
||||
PROVIDE ( rom_i2c_readReg = 0x40007268 );
|
||||
PROVIDE ( rom_i2c_readReg_Mask = 0x4000729c );
|
||||
PROVIDE ( rom_i2c_writeReg = 0x400072d8 );
|
||||
PROVIDE ( rom_i2c_writeReg_Mask = 0x4000730c );
|
||||
PROVIDE ( rom_iq_est_disable = 0x40006400 );
|
||||
PROVIDE ( rom_iq_est_enable = 0x40006430 );
|
||||
PROVIDE ( rom_linear_to_db = 0x40006484 );
|
||||
PROVIDE ( rom_mhz2ieee = 0x400065a4 );
|
||||
PROVIDE ( rom_pbus_dco___SA2 = 0x40007bf0 );
|
||||
PROVIDE ( rom_pbus_debugmode = 0x4000737c );
|
||||
PROVIDE ( rom_pbus_enter_debugmode = 0x40007410 );
|
||||
PROVIDE ( rom_pbus_exit_debugmode = 0x40007448 );
|
||||
PROVIDE ( rom_pbus_force_test = 0x4000747c );
|
||||
PROVIDE ( rom_pbus_rd = 0x400074d8 );
|
||||
PROVIDE ( rom_pbus_set_rxgain = 0x4000754c );
|
||||
PROVIDE ( rom_pbus_set_txgain = 0x40007610 );
|
||||
PROVIDE ( rom_pbus_workmode = 0x40007648 );
|
||||
PROVIDE ( rom_pbus_xpd_rx_off = 0x40007688 );
|
||||
PROVIDE ( rom_pbus_xpd_rx_on = 0x400076cc );
|
||||
PROVIDE ( rom_pbus_xpd_tx_off = 0x400076fc );
|
||||
PROVIDE ( rom_pbus_xpd_tx_on = 0x40007740 );
|
||||
PROVIDE ( rom_pbus_xpd_tx_on__low_gain = 0x400077a0 );
|
||||
PROVIDE ( rom_phy_reset_req = 0x40007804 );
|
||||
PROVIDE ( rom_restart_cal = 0x4000781c );
|
||||
PROVIDE ( rom_rfcal_pwrctrl = 0x40007eb4 );
|
||||
PROVIDE ( rom_rfcal_rxiq = 0x4000804c );
|
||||
PROVIDE ( rom_rfcal_rxiq_set_reg = 0x40008264 );
|
||||
PROVIDE ( rom_rfcal_txcap = 0x40008388 );
|
||||
PROVIDE ( rom_rfcal_txiq = 0x40008610 );
|
||||
PROVIDE ( rom_rfcal_txiq_cover = 0x400088b8 );
|
||||
PROVIDE ( rom_rfcal_txiq_set_reg = 0x40008a70 );
|
||||
PROVIDE ( rom_rfpll_reset = 0x40007868 );
|
||||
PROVIDE ( rom_rfpll_set_freq = 0x40007968 );
|
||||
PROVIDE ( rom_rxiq_cover_mg_mp = 0x40008b6c );
|
||||
PROVIDE ( rom_rxiq_get_mis = 0x40006628 );
|
||||
PROVIDE ( rom_sar_init = 0x40006738 );
|
||||
PROVIDE ( rom_set_ana_inf_tx_scale = 0x4000678c );
|
||||
PROVIDE ( rom_set_channel_freq = 0x40006c50 );
|
||||
PROVIDE ( rom_set_loopback_gain = 0x400067c8 );
|
||||
PROVIDE ( rom_set_noise_floor = 0x40006830 );
|
||||
PROVIDE ( rom_set_rxclk_en = 0x40006550 );
|
||||
PROVIDE ( rom_set_txbb_atten = 0x40008c6c );
|
||||
PROVIDE ( rom_set_txclk_en = 0x4000650c );
|
||||
PROVIDE ( rom_set_txiq_cal = 0x40008d34 );
|
||||
PROVIDE ( rom_start_noisefloor = 0x40006874 );
|
||||
PROVIDE ( rom_start_tx_tone = 0x400068b4 );
|
||||
PROVIDE ( rom_stop_tx_tone = 0x4000698c );
|
||||
PROVIDE ( rom_tx_mac_disable = 0x40006a98 );
|
||||
PROVIDE ( rom_tx_mac_enable = 0x40006ad4 );
|
||||
PROVIDE ( rom_txtone_linear_pwr = 0x40006a1c );
|
||||
PROVIDE ( rom_write_rfpll_sdm = 0x400078dc );
|
||||
PROVIDE ( roundup2 = 0x400031b4 );
|
||||
PROVIDE ( rtc_enter_sleep = 0x40002870 );
|
||||
PROVIDE ( rtc_get_reset_reason = 0x400025e0 );
|
||||
PROVIDE ( rtc_intr_handler = 0x400029ec );
|
||||
PROVIDE ( rtc_set_sleep_mode = 0x40002668 );
|
||||
PROVIDE ( save_rxbcn_mactime = 0x400027a4 );
|
||||
PROVIDE ( save_tsf_us = 0x400027ac );
|
||||
PROVIDE ( send_packet = 0x40003c80 );
|
||||
PROVIDE ( sha1_prf = 0x4000ba48 );
|
||||
PROVIDE ( sha1_vector = 0x4000a2ec );
|
||||
PROVIDE ( sip_alloc_to_host_evt = 0x40005180 );
|
||||
PROVIDE ( sip_get_ptr = 0x400058a8 );
|
||||
PROVIDE ( sip_get_state = 0x40005668 );
|
||||
PROVIDE ( sip_init_attach = 0x4000567c );
|
||||
PROVIDE ( sip_install_rx_ctrl_cb = 0x4000544c );
|
||||
PROVIDE ( sip_install_rx_data_cb = 0x4000545c );
|
||||
PROVIDE ( sip_post = 0x400050fc );
|
||||
PROVIDE ( sip_post_init = 0x400056c4 );
|
||||
PROVIDE ( sip_reclaim_from_host_cmd = 0x4000534c );
|
||||
PROVIDE ( sip_reclaim_tx_data_pkt = 0x400052c0 );
|
||||
PROVIDE ( sip_send = 0x40005808 );
|
||||
PROVIDE ( sip_to_host_chain_append = 0x40005864 );
|
||||
PROVIDE ( sip_to_host_evt_send_done = 0x40005234 );
|
||||
PROVIDE ( slc_add_credits = 0x400060ac );
|
||||
PROVIDE ( slc_enable = 0x40005d90 );
|
||||
PROVIDE ( slc_from_host_chain_fetch = 0x40005f24 );
|
||||
PROVIDE ( slc_from_host_chain_recycle = 0x40005e94 );
|
||||
PROVIDE ( slc_init_attach = 0x40005c50 );
|
||||
PROVIDE ( slc_init_credit = 0x4000608c );
|
||||
PROVIDE ( slc_pause_from_host = 0x40006014 );
|
||||
PROVIDE ( slc_reattach = 0x40005c1c );
|
||||
PROVIDE ( slc_resume_from_host = 0x4000603c );
|
||||
PROVIDE ( slc_select_tohost_gpio = 0x40005dc0 );
|
||||
PROVIDE ( slc_select_tohost_gpio_mode = 0x40005db8 );
|
||||
PROVIDE ( slc_send_to_host_chain = 0x40005de4 );
|
||||
PROVIDE ( slc_set_host_io_max_window = 0x40006068 );
|
||||
PROVIDE ( slc_to_host_chain_recycle = 0x40005f10 );
|
||||
PROVIDE ( software_reset = 0x4000264c );
|
||||
PROVIDE ( spi_flash_attach = 0x40004644 );
|
||||
PROVIDE ( srand = 0x400005f0 );
|
||||
PROVIDE ( strcmp = 0x4000bdc8 );
|
||||
PROVIDE ( strcpy = 0x4000bec8 );
|
||||
PROVIDE ( strlen = 0x4000bf4c );
|
||||
PROVIDE ( strncmp = 0x4000bfa8 );
|
||||
PROVIDE ( strncpy = 0x4000c0a0 );
|
||||
PROVIDE ( strstr = 0x4000e1e0 );
|
||||
PROVIDE ( timer_insert = 0x40002c64 );
|
||||
PROVIDE ( uartAttach = 0x4000383c );
|
||||
PROVIDE ( uart_baudrate_detect = 0x40003924 );
|
||||
PROVIDE ( uart_buff_switch = 0x400038a4 );
|
||||
PROVIDE ( uart_div_modify = 0x400039d8 );
|
||||
PROVIDE ( uart_rx_intr_handler = 0x40003bbc );
|
||||
PROVIDE ( uart_rx_one_char = 0x40003b8c );
|
||||
PROVIDE ( uart_rx_one_char_block = 0x40003b64 );
|
||||
PROVIDE ( uart_rx_readbuff = 0x40003ec8 );
|
||||
PROVIDE ( uart_tx_one_char = 0x40003b30 );
|
||||
PROVIDE ( wepkey_128 = 0x4000bc40 );
|
||||
PROVIDE ( wepkey_64 = 0x4000bb3c );
|
||||
PROVIDE ( xthal_bcopy = 0x40000688 );
|
||||
PROVIDE ( xthal_copy123 = 0x4000074c );
|
||||
PROVIDE ( xthal_get_ccompare = 0x4000dd4c );
|
||||
PROVIDE ( xthal_get_ccount = 0x4000dd38 );
|
||||
PROVIDE ( xthal_get_interrupt = 0x4000dd58 );
|
||||
PROVIDE ( xthal_get_intread = 0x4000dd58 );
|
||||
PROVIDE ( xthal_memcpy = 0x400006c4 );
|
||||
PROVIDE ( xthal_set_ccompare = 0x4000dd40 );
|
||||
PROVIDE ( xthal_set_intclear = 0x4000dd60 );
|
||||
PROVIDE ( xthal_spill_registers_into_stack_nw = 0x4000e320 );
|
||||
PROVIDE ( xthal_window_spill = 0x4000e324 );
|
||||
PROVIDE ( xthal_window_spill_nw = 0x4000e320 );
|
||||
|
||||
PROVIDE ( Te0 = 0x3fffccf0 );
|
||||
PROVIDE ( Td0 = 0x3fffd100 );
|
||||
PROVIDE ( Td4s = 0x3fffd500);
|
||||
PROVIDE ( rcons = 0x3fffd0f0);
|
||||
PROVIDE ( UartDev = 0x3fffde10 );
|
||||
14
cpu/esp8266/ld/esp8266.peripherals.ld
Normal file
14
cpu/esp8266/ld/esp8266.peripherals.ld
Normal file
@ -0,0 +1,14 @@
|
||||
PROVIDE ( GPIO = 0x60000300);
|
||||
|
||||
PROVIDE ( uart0 = 0x60000000 );
|
||||
PROVIDE ( uart1 = 0x60000f00 );
|
||||
|
||||
PROVIDE ( frc1 = 0x60000600 );
|
||||
|
||||
PROVIDE ( rtc_sys_info = 0x60001100 );
|
||||
|
||||
PROVIDE ( SLC = 0x60000B00 );
|
||||
PROVIDE ( I2S = 0x60000e00 );
|
||||
|
||||
PROVIDE ( SPI1 = 0x60000100 );
|
||||
PROVIDE ( SPI0 = 0x60000200 );
|
||||
@ -1,17 +1,15 @@
|
||||
/**
|
||||
* This linker script is a modified version of eagle.app.v6.ld that
|
||||
* was generated from xt-genldscripts.tpp for LSP and shipped with
|
||||
* ESP8266_NONOS_SDK
|
||||
*/
|
||||
|
||||
/* Linker Script for ld -N */
|
||||
* This linker script is a combined and modified version of esp8266.ld and
|
||||
* esp8266.common.ld from ESP8266-RTOS-SDK.
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
dport0_0_seg : org = 0x3FF00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40210000, len = 0x5C000
|
||||
dram0_0_seg : org = 0x3FFE8000, len = 0x18000
|
||||
iram1_0_seg : org = 0x40100000, len = 0xC000
|
||||
irom0_0_seg : org = 0x40200010 + 0x10000, len = 0x80000 - 0x10 - 0x10000
|
||||
rtc_seg : org = 0x60001200, len = 0x200
|
||||
}
|
||||
|
||||
PHDRS
|
||||
@ -25,7 +23,7 @@ PHDRS
|
||||
|
||||
|
||||
/* Default entry point: */
|
||||
ENTRY(_call_user_start)
|
||||
ENTRY(call_user_start)
|
||||
EXTERN(_DebugExceptionVector)
|
||||
EXTERN(_DoubleExceptionVector)
|
||||
EXTERN(_KernelExceptionVector)
|
||||
@ -50,17 +48,6 @@ _memmap_cacheattr_wt_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
||||
|
||||
/* ROM variables */
|
||||
/* source: disassembly of boot rom at https://github.com/trebisky/esp8266 */
|
||||
PROVIDE( ets_task_min_prio = 0x3fffc6fc );
|
||||
PROVIDE( ets_idle_cb = 0x3fffdab0 );
|
||||
PROVIDE( ets_idle_arg = 0x3fffdab4 );
|
||||
PROVIDE( ets_task_exec_mask = 0x3fffdab8 );
|
||||
PROVIDE( ets_task_tab = 0x3fffdac0 );
|
||||
PROVIDE( flashchip = 0x3fffc714 );
|
||||
PROVIDE( sdk_flashchip = 0x3fffc718 );
|
||||
PROVIDE( ets_phy_mactime = 0x3ff20a00 );
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
@ -88,6 +75,15 @@ SECTIONS
|
||||
_dport0_data_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
/* RTC memory holds user's data/rodata */
|
||||
.rtc.data :
|
||||
{
|
||||
_rtc_data_start = ABSOLUTE(.);
|
||||
*(.rtc.data)
|
||||
*(.rtc.rodata)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > rtc_seg
|
||||
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
@ -108,26 +104,30 @@ SECTIONS
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
*(.sdk.version)
|
||||
/* TODO put only necessary .rodata to dram
|
||||
/* TODO put only necessary .rodata to dram */
|
||||
/* *(.rodata .rodata.*) */
|
||||
*libc.a:*.o(.rodata.* .rodata)
|
||||
*core.a:*(.rodata.* .rodata)
|
||||
*cpu.a:*(.rodata .rodata.*)
|
||||
*/
|
||||
*(.rodata .rodata.*)
|
||||
*libpp.a:(.rodata.* .rodata)
|
||||
*liblog.a:(.rodata.* .rodata)
|
||||
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||
*(.xt_except_table)
|
||||
*(.gcc_except_table)
|
||||
*(.gcc_except_table.*)
|
||||
*(.gnu.linkonce.e.*)
|
||||
*(.gnu.version_r)
|
||||
*(.eh_frame)
|
||||
. = (. + 3) & ~ 3;
|
||||
/* C++ constructor and destructor tables, properly ordered: */
|
||||
__init_array_start = ABSOLUTE(.);
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
@ -140,7 +140,7 @@ SECTIONS
|
||||
*(.xt_except_desc_end)
|
||||
*(.dynamic)
|
||||
*(.gnu.version_d)
|
||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||
_bss_table_start = ABSOLUTE(.);
|
||||
LONG(_bss_start)
|
||||
LONG(_bss_end)
|
||||
@ -165,7 +165,6 @@ SECTIONS
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN (8);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
_sheap = ABSOLUTE(.);
|
||||
@ -173,40 +172,39 @@ SECTIONS
|
||||
|
||||
} >dram0_0_seg :dram0_0_bss_phdr
|
||||
|
||||
/* ETS system memory starts at 0x3FFFC000 which is the top of the heap for the app */
|
||||
. = 0x3FFFC000;
|
||||
. = 0x3FFFFFF0;
|
||||
_heap_top = ABSOLUTE(.);
|
||||
_eheap = ABSOLUTE(.);
|
||||
|
||||
.text : ALIGN(4)
|
||||
.text : ALIGN(4) /* IRAM */
|
||||
{
|
||||
_stext = .;
|
||||
_text_start = ABSOLUTE(.);
|
||||
*(.UserEnter.text)
|
||||
LONG(_text_start)
|
||||
. = ALIGN(16);
|
||||
*(.DebugExceptionVector.text)
|
||||
*(.DebugExceptionVector.text) /* 0x40100010 */
|
||||
. = ALIGN(16);
|
||||
*(.NMIExceptionVector.text)
|
||||
*(.NMIExceptionVector.text) /* 0x40100020 */
|
||||
. = ALIGN(16);
|
||||
*(.KernelExceptionVector.text)
|
||||
*(.KernelExceptionVector.text) /* 0x40100030 */
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.UserExceptionVector.text)
|
||||
*(.UserExceptionVector.text) /* 0x40100050 */
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.DoubleExceptionVector.text)
|
||||
*(.DoubleExceptionVector.text) /* 0x40100070 */
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN (16);
|
||||
*(.UserExceptionTrampoline.text)
|
||||
*(.UserExceptionTrampoline.text) /* 0x40100090 */
|
||||
. = ALIGN (16);
|
||||
*(.entry.text)
|
||||
*(.init.literal)
|
||||
@ -214,30 +212,48 @@ SECTIONS
|
||||
|
||||
/* normal code should be in irom0 */
|
||||
/*
|
||||
*(.literal .text .literal.* .text.* .stub)
|
||||
*(.gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
*(.literal .text)
|
||||
*core.a:*(.literal .text .literal.* .text.*)
|
||||
*/
|
||||
|
||||
*gdbstub.a:*(.literal .text .literal.* .text.*)
|
||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
/* RIOT-OS compiled source files that use the .iram1.* section names for IRAM
|
||||
functions, etc. */
|
||||
*(.iram1.*)
|
||||
*(.iram1 .iram1.*)
|
||||
|
||||
/* SDK libraries expect their .text sections to link to iram, not irom */
|
||||
*libcrypto.a:*(.literal .text)
|
||||
*libmain.a:*(.literal .text .literal.* .text.*)
|
||||
*libnet80211.a:*(.literal .text)
|
||||
*libpp.a:*(.literal .text .literal.* .text.*)
|
||||
*libphy.a:*(.literal .text .literal.* .text.*)
|
||||
*libwpa.a:*(.literal .text)
|
||||
*libwpa2.a:*(.literal .text)
|
||||
*liblwip.a:*(.literal .text)
|
||||
/* SDK libraries that expect their .text or .data sections to link to iram */
|
||||
/* TODO *libcore.a:(.bss .data .bss.* .data.* COMMON) */
|
||||
*esp_idf_spi_flash.a:spi_flash_raw.o(.literal .text .literal.* .text.*)
|
||||
*esp_idf_esp8266.a:ets_printf.o(.literal .text .literal.* .text.*)
|
||||
/*
|
||||
*cpu.a:*.o(.literal .text .literal.* .text.*)
|
||||
*/
|
||||
*core.a:sched.o(.literal .text .literal.* .text.*)
|
||||
*esp_wifi.a:*(.literal .text .literal.* .text.*)
|
||||
*freertos.a:*(.literal .text .literal.* .text.*)
|
||||
*periph.a:*(.literal .text .literal.* .text.*)
|
||||
*xtimer.a:*(.literal .text .literal.* .text.*)
|
||||
|
||||
*libhal.a:clock.o(.literal .text .literal.* .text.*)
|
||||
*libhal.a:int_asm--set_intclear.o(.literal .text .literal.* .text.*)
|
||||
*libpp.a:esf_buf.o(.literal .text .literal.* .text.*)
|
||||
*libpp.a:lmac.o(.literal .text .literal.* .text.*)
|
||||
*libpp.a:pp.o(.literal .text .literal.* .text.*)
|
||||
*libpp.a:rate_control.o(.literal .text .literal.* .text.*)
|
||||
*libpp.a:trc.o(.literal .text .literal.* .text.*)
|
||||
*libpp.a:wdev.o(.literal .text .literal.* .text.*)
|
||||
*libphy.a:phy.o(.literal .text .literal.* .text.*)
|
||||
*libphy.a:phy_chip_v6_cal.o(.literal .text .literal.* .text.*)
|
||||
*libphy.a:phy_sleep.o(.literal .text .literal.* .text.*)
|
||||
|
||||
/* Xtensa basic functionality written in assembler should be placed in iram */
|
||||
*xtensa.a:*(.literal .text .literal.* .text.*)
|
||||
|
||||
/* libgcc integer functions also need to be in .text, as some are called before
|
||||
flash is mapped (also performance)
|
||||
*/
|
||||
/* libgcc functions required for debugging have to be in IRAM */
|
||||
*libgcc.a:unwind-dw2.o(.literal .text .literal.* .text.*)
|
||||
|
||||
/* libgcc integer functions also need to be in .text */
|
||||
/* some are called before flash is mapped and also for performance) */
|
||||
*libgcc.a:*i3.o(.literal .text .literal.* .text.*)
|
||||
|
||||
*libgcc.a:*mulsf3.o(.literal .text .literal.* .text.*)
|
||||
@ -245,6 +261,7 @@ SECTIONS
|
||||
*libgcc.a:*fixsfsi.o(.literal .text .literal.* .text.*)
|
||||
|
||||
/* libc also in IRAM */
|
||||
/*
|
||||
*libc.a:*malloc.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*mallocr.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*freer.o(.literal .text .literal.* .text.*)
|
||||
@ -260,6 +277,7 @@ SECTIONS
|
||||
*libc.a:*printf.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*findfp.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*fputwc.o(.literal .text .literal.* .text.*)
|
||||
*/
|
||||
|
||||
enc28j60.a:*(.literal .text .literal.* .text.*)
|
||||
|
||||
@ -274,15 +292,18 @@ SECTIONS
|
||||
{
|
||||
_irom0_text_start = ABSOLUTE(.);
|
||||
|
||||
*libmbedtls.a:(.literal .text .literal.* .text.*)
|
||||
|
||||
/* RIOT-OS compiled code goes into IROM by default
|
||||
(except for libgcc which is matched above.) */
|
||||
*(.literal .text .literal.* .text.* .rodata .rodata.*)
|
||||
/* RIOT-OS compiled code and RO data go into IROM by default */
|
||||
*(.literal .text .literal.* .text.*)
|
||||
*(.rodata .rodata.*)
|
||||
|
||||
/* Anything explicitly marked as "irom" or "irom0" should go here */
|
||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||
|
||||
. = ALIGN(16);
|
||||
__start_ksymatabesp_socket = .;
|
||||
*(ksymatabesp_socket)
|
||||
__stop_ksymatabesp_socket = .;
|
||||
|
||||
_irom0_text_end = ABSOLUTE(.);
|
||||
} >irom0_0_seg :irom0_0_phdr
|
||||
|
||||
@ -1,322 +0,0 @@
|
||||
/**
|
||||
* This linker script is a modified version of eagle.app.v6.ld that
|
||||
* was generated from xt-genldscripts.tpp for LSP and shipped with
|
||||
* ESP8266_NONOS_SDK
|
||||
*/
|
||||
|
||||
/* Linker Script for ld -N */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
dport0_0_seg : org = 0x3FF00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40210000, len = 0x5C000
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
dport0_0_phdr PT_LOAD;
|
||||
dram0_0_phdr PT_LOAD;
|
||||
dram0_0_bss_phdr PT_LOAD;
|
||||
iram1_0_phdr PT_LOAD;
|
||||
irom0_0_phdr PT_LOAD;
|
||||
}
|
||||
|
||||
|
||||
/* Default entry point: */
|
||||
ENTRY(call_user_start)
|
||||
EXTERN(_DebugExceptionVector)
|
||||
EXTERN(_DoubleExceptionVector)
|
||||
EXTERN(_KernelExceptionVector)
|
||||
EXTERN(_NMIExceptionVector)
|
||||
EXTERN(_UserExceptionVector)
|
||||
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
||||
/* Various memory-map dependent cache attribute settings: */
|
||||
_memmap_cacheattr_wb_base = 0x00000110;
|
||||
_memmap_cacheattr_wt_base = 0x00000110;
|
||||
_memmap_cacheattr_bp_base = 0x00000220;
|
||||
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
||||
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
||||
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
||||
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
||||
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
||||
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
||||
|
||||
/* System task handling variables */
|
||||
/* source: disassembly of boot rom at https://github.com/trebisky/esp8266 */
|
||||
PROVIDE( ets_task_min_prio = 0x3fffc6fc );
|
||||
PROVIDE( ets_idle_cb = 0x3fffdab0 );
|
||||
PROVIDE( ets_idle_arg = 0x3fffdab4 );
|
||||
PROVIDE( ets_task_exec_mask = 0x3fffdab8 );
|
||||
PROVIDE( ets_task_tab = 0x3fffdac0 );
|
||||
PROVIDE( flashchip = 0x3fffc714 );
|
||||
PROVIDE( sdk_flashchip = 0x3fffc718 );
|
||||
PROVIDE( _xt_interrupt_table = 0x3fffc200 );
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.dport0.rodata : ALIGN(4)
|
||||
{
|
||||
_dport0_rodata_start = ABSOLUTE(.);
|
||||
*(.dport0.rodata)
|
||||
*(.dport.rodata)
|
||||
_dport0_rodata_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.dport0.literal : ALIGN(4)
|
||||
{
|
||||
_dport0_literal_start = ABSOLUTE(.);
|
||||
*(.dport0.literal)
|
||||
*(.dport.literal)
|
||||
_dport0_literal_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.dport0.data : ALIGN(4)
|
||||
{
|
||||
_dport0_data_start = ABSOLUTE(.);
|
||||
*(.dport0.data)
|
||||
*(.dport.data)
|
||||
_dport0_data_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
*(.jcr)
|
||||
_data_end = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_phdr
|
||||
|
||||
/*
|
||||
* .rodata sections that are placed in RAM
|
||||
*
|
||||
* Usually, all .rodata sections are placed in RAM by the Espressif SDK
|
||||
* since IROM (flash) access requires 32-bit word aligned reads.
|
||||
*
|
||||
* However, thanks to the LoadStoreError handler from esp-open-rtos which is
|
||||
* also used in RIOT-OS, it is possible to place .rodata sections in IROM
|
||||
* (flash) to save RAM resources.
|
||||
*
|
||||
* Only .rodata data sections of compilation units that may be executed
|
||||
* while SPI flash is not mapped have to be stored in RAM. These are IRAM
|
||||
* functions that are called from interrupt context or SPI flash management
|
||||
* functions. Such compilation units have to be listed here.
|
||||
*
|
||||
* Furthermore, compilation units with constant data that are performance-
|
||||
* critical should be listed here as well.
|
||||
*/
|
||||
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
*(.sdk.version)
|
||||
|
||||
*core.a:*(.rodata.* .rodata)
|
||||
*cpu.a:*(.rodata .rodata.*)
|
||||
*esp.a:*(.rodata .rodata.*)
|
||||
*esp_now.a:*(.rodata .rodata.*)
|
||||
*esp_wifi.a:*(.rodata .rodata.*)
|
||||
*periph.a:*(.rodata.* .rodata)
|
||||
*sdk.a:*(.rodata .rodata.*)
|
||||
*xtensa.a:*(.rodata .rodata.*)
|
||||
|
||||
*libc.a:*.o(.rodata.* .rodata)
|
||||
*libpp.a:wdev.o(.rodata.* .rodata)
|
||||
*libmain.a:spi_flash.o(.rodata.* .rodata)
|
||||
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||
*(.xt_except_table)
|
||||
*(.gcc_except_table)
|
||||
*(.gnu.linkonce.e.*)
|
||||
*(.gnu.version_r)
|
||||
*(.eh_frame)
|
||||
/* C++ constructor and destructor tables, properly ordered: */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
/* C++ exception handlers table: */
|
||||
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc)
|
||||
*(.gnu.linkonce.h.*)
|
||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc_end)
|
||||
*(.dynamic)
|
||||
*(.gnu.version_d)
|
||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||
_bss_table_start = ABSOLUTE(.);
|
||||
LONG(_bss_start)
|
||||
LONG(_bss_end)
|
||||
_bss_table_end = ABSOLUTE(.);
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_phdr
|
||||
|
||||
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_bss_start = ABSOLUTE(.);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN (8);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
_sheap = ABSOLUTE(.);
|
||||
_heap_start = ABSOLUTE(.);
|
||||
|
||||
} >dram0_0_seg :dram0_0_bss_phdr
|
||||
|
||||
/* ETS system memory starts at 0x3FFFC000 which is the top of the heap for the app */
|
||||
. = 0x3FFFC000;
|
||||
_heap_top = ABSOLUTE(.);
|
||||
_eheap = ABSOLUTE(.);
|
||||
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
_stext = .;
|
||||
_text_start = ABSOLUTE(.);
|
||||
*(.UserEnter.text)
|
||||
. = ALIGN(16);
|
||||
*(.DebugExceptionVector.text)
|
||||
. = ALIGN(16);
|
||||
*(.NMIExceptionVector.text)
|
||||
. = ALIGN(16);
|
||||
*(.KernelExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.UserExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.DoubleExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN (16);
|
||||
*(.UserExceptionTrampoline.text)
|
||||
. = ALIGN (16);
|
||||
*(.entry.text)
|
||||
*(.init.literal)
|
||||
*(.init)
|
||||
|
||||
/* normal code should be in irom0 */
|
||||
/*
|
||||
*(.literal .text .literal.* .text.* .stub)
|
||||
*(.gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
*/
|
||||
|
||||
/* RIOT-OS compiled source files that use the .iram1.* section names for IRAM
|
||||
functions, etc. */
|
||||
*(.iram1.*)
|
||||
|
||||
/* SDK libraries expect their .text sections to link to iram, not irom */
|
||||
*libcrypto.a:*(.literal .text)
|
||||
*libmain.a:*(.literal .text .literal.* .text.*)
|
||||
*libnet80211.a:*(.literal .text)
|
||||
*libpp.a:*(.literal .text .literal.* .text.*)
|
||||
*libphy.a:*(.literal .text .literal.* .text.*)
|
||||
*libwpa.a:*(.literal .text)
|
||||
*libwpa2.a:*(.literal .text)
|
||||
*liblwip.a:*(.literal .text)
|
||||
|
||||
/* Xtensa basic functionality written in assembler should be placed in iram */
|
||||
*xtensa.a:*(.literal .text .literal.* .text.*)
|
||||
|
||||
/* libgcc integer functions also need to be in .text, as some are called before
|
||||
flash is mapped (also performance) */
|
||||
*libgcc.a:*i3.o(.literal .text .literal.* .text.*)
|
||||
|
||||
*libgcc.a:*mulsf3.o(.literal .text .literal.* .text.*)
|
||||
*libgcc.a:*divsf3.o(.literal .text .literal.* .text.*)
|
||||
*libgcc.a:*fixsfsi.o(.literal .text .literal.* .text.*)
|
||||
|
||||
/* libc also in IRAM */
|
||||
*libc.a:*malloc.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*mallocr.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*freer.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*memchr.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*memcpy.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*memset.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*memcmp.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*memmove.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*rand.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*bzero.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*lock.o(.literal .text .literal.* .text.*)
|
||||
|
||||
*libc.a:*findfp.o(.literal .text .literal.* .text.*)
|
||||
*libc.a:*fputwc.o(.literal .text .literal.* .text.*)
|
||||
|
||||
enc28j60.a:*(.literal .text .literal.* .text.*)
|
||||
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
|
||||
.irom0.text : ALIGN(4)
|
||||
{
|
||||
_irom0_text_start = ABSOLUTE(.);
|
||||
|
||||
*libmbedtls.a:(.literal .text .literal.* .text.*)
|
||||
|
||||
/* RIOT-OS compiled code goes into IROM by default
|
||||
(except for functions with section names defined in .text above.) */
|
||||
*(.literal .text .literal.* .text.* .rodata .rodata.*)
|
||||
|
||||
/* Anything explicitly marked as "irom" or "irom0" should go here */
|
||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||
|
||||
_irom0_text_end = ABSOLUTE(.);
|
||||
} >irom0_0_seg :irom0_0_phdr
|
||||
|
||||
.lit4 : ALIGN(4)
|
||||
{
|
||||
_lit4_start = ABSOLUTE(.);
|
||||
*(*.lit4)
|
||||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
}
|
||||
60
cpu/esp8266/ld/esp8266.rom.ld
Normal file
60
cpu/esp8266/ld/esp8266.rom.ld
Normal file
@ -0,0 +1,60 @@
|
||||
SPI_sector_erase = 0x400040c0;
|
||||
SPI_page_program = 0x40004174;
|
||||
SPI_read_data = 0x400042ac;
|
||||
SPI_read_status = 0x400043c8;
|
||||
SPI_write_status = 0x40004400;
|
||||
SPI_write_enable = 0x4000443c;
|
||||
Wait_SPI_Idle = 0x4000448c;
|
||||
Enable_QMode = 0x400044c0;
|
||||
Disable_QMode = 0x40004508;
|
||||
|
||||
Cache_Read_Enable = 0x40004678;
|
||||
Cache_Read_Disable = 0x400047f0;
|
||||
|
||||
lldesc_build_chain = 0x40004f40;
|
||||
lldesc_num2link = 0x40005050;
|
||||
lldesc_set_owner = 0x4000507c;
|
||||
|
||||
__adddf3 = 0x4000c538;
|
||||
__addsf3 = 0x4000c180;
|
||||
__divdf3 = 0x4000cb94;
|
||||
__divdi3 = 0x4000ce60;
|
||||
__divsi3 = 0x4000dc88;
|
||||
__extendsfdf2 = 0x4000cdfc;
|
||||
__fixdfsi = 0x4000ccb8;
|
||||
__fixunsdfsi = 0x4000cd00;
|
||||
__fixunssfsi = 0x4000c4c4;
|
||||
__floatsidf = 0x4000e2f0;
|
||||
__floatsisf = 0x4000e2ac;
|
||||
__floatunsidf = 0x4000e2e8;
|
||||
__floatunsisf = 0x4000e2a4;
|
||||
__muldf3 = 0x4000c8f0;
|
||||
__muldi3 = 0x40000650;
|
||||
__mulsf3 = 0x4000c3dc;
|
||||
__subdf3 = 0x4000c688;
|
||||
__subsf3 = 0x4000c268;
|
||||
__truncdfsf2 = 0x4000cd5c;
|
||||
__udivdi3 = 0x4000d310;
|
||||
__udivsi3 = 0x4000e21c;
|
||||
__umoddi3 = 0x4000d770;
|
||||
__umodsi3 = 0x4000e268;
|
||||
__umulsidi3 = 0x4000dcf0;
|
||||
|
||||
bzero = 0x4000de84;
|
||||
memcmp = 0x4000dea8;
|
||||
memcpy = 0x4000df48;
|
||||
memmove = 0x4000e04c;
|
||||
memset = 0x4000e190;
|
||||
|
||||
strcmp = 0x4000bdc8;
|
||||
strcpy = 0x4000bec8;
|
||||
strlen = 0x4000bf4c;
|
||||
strncmp = 0x4000bfa8;
|
||||
strncpy = 0x4000c0a0;
|
||||
strstr = 0x4000e1e0;
|
||||
|
||||
gpio_input_get = 0x40004cf0;
|
||||
gpio_pin_wakeup_disable = 0x40004ed4;
|
||||
gpio_pin_wakeup_enable = 0x40004e90;
|
||||
|
||||
ets_io_vprintf = 0x40001f00;
|
||||
@ -1,3 +1,3 @@
|
||||
MODULE = periph
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
include $(RIOTMAKE)/periph.mk
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -28,10 +28,10 @@
|
||||
#include "periph_conf.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "esp_common.h"
|
||||
#include "sdk/sdk.h"
|
||||
|
||||
#if defined(ADC_NUMOF) && ADC_NUMOF > 0
|
||||
extern uint16_t test_tout(void);
|
||||
|
||||
int adc_init(adc_t line)
|
||||
{
|
||||
@ -47,11 +47,10 @@ int adc_sample(adc_t line, adc_res_t res)
|
||||
CHECK_PARAM_RET (line < ADC_NUMOF, -1)
|
||||
CHECK_PARAM_RET (res == ADC_RES_10BIT, -1)
|
||||
|
||||
#ifdef MODULE_ESP_SDK
|
||||
return system_adc_read ();
|
||||
#else
|
||||
return test_tout(false);
|
||||
#endif
|
||||
return test_tout();
|
||||
}
|
||||
|
||||
#endif
|
||||
void adc_print_config(void)
|
||||
{
|
||||
printf("\tADC\t\tpins=[ A0 ]\n");
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -18,25 +18,42 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
#if MODULE_MTD
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
#include "esp_common.h"
|
||||
#include "irq_arch.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "mtd.h"
|
||||
|
||||
#include "c_types.h"
|
||||
#include "esp/spiflash.h"
|
||||
#include "spi_flash.h"
|
||||
#include "sdk/rom.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
#include "esp_partition.h"
|
||||
|
||||
#define SDK_FLASH_FUNCTIONS
|
||||
#ifdef MCU_ESP32
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#else /* MCU_ESP32 */
|
||||
|
||||
#include "rom_functions.h"
|
||||
#include "spi_flash.h"
|
||||
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define ESP_PART_TABLE_ADDR 0x8000 /* TODO configurable as used in Makefile.include */
|
||||
#define ESP_PART_TABLE_SIZE 0xC00
|
||||
#define ESP_PART_ENTRY_SIZE 0x20
|
||||
#define ESP_PART_ENTRY_MAGIC ESP_PARTITION_MAGIC
|
||||
|
||||
/* the external pointer to the system MTD device */
|
||||
mtd_dev_t* mtd0 = 0;
|
||||
@ -44,6 +61,18 @@ mtd_dev_t* mtd0 = 0;
|
||||
mtd_dev_t _flash_dev;
|
||||
mtd_desc_t _flash_driver;
|
||||
|
||||
#ifdef MCU_ESP8266
|
||||
|
||||
/* for source code compatibility with ESP32 SDK */
|
||||
#define esp_rom_spiflash_chip_t esp_spi_flash_chip_t
|
||||
#define g_rom_flashchip flashchip
|
||||
|
||||
/* defined in vendor/esp-idf/spi_flash.c */
|
||||
extern esp_spi_flash_chip_t flashchip;
|
||||
extern uint32_t spi_flash_get_id(void);
|
||||
|
||||
#endif /* MCU_ESP8266 */
|
||||
|
||||
/* forward declaration of mtd functions */
|
||||
static int _flash_init (mtd_dev_t *dev);
|
||||
static int _flash_read (mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t size);
|
||||
@ -55,60 +84,420 @@ static uint32_t _flash_beg; /* first byte addr of the flash drive in SPI flash
|
||||
static uint32_t _flash_end; /* first byte addr after the flash drive in SPI flash */
|
||||
static uint32_t _flash_size; /* resulting size of the flash drive in SPI flash */
|
||||
|
||||
#define SPIFFS_FLASH_BEGIN 0x80000 /* TODO determine real possible value */
|
||||
static esp_rom_spiflash_chip_t* _flashchip = NULL;
|
||||
|
||||
void flash_drive_init (void)
|
||||
/* flash_id determines the flash size in kByte */
|
||||
static const uint32_t flash_sizes[] = {
|
||||
256, /* last byte of id is 0x12 */
|
||||
512, /* last byte of id is 0x13 */
|
||||
1 * 1024, /* last byte of id is 0x14 */
|
||||
2 * 1024, /* last byte of id is 0x15 */
|
||||
4 * 1024, /* last byte of id is 0x16 */
|
||||
8 * 1024, /* last byte of id is 0x17 */
|
||||
16 * 1024 /* last byte of id is 0x18 */
|
||||
};
|
||||
|
||||
void spi_flash_drive_init (void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
|
||||
_flashchip = &g_rom_flashchip;
|
||||
assert(_flashchip);
|
||||
|
||||
#ifdef MCU_ESP8266
|
||||
_flashchip->deviceId = spi_flash_get_id();
|
||||
uint8_t devid_lb = _flashchip->deviceId >> 16 & 0xff;
|
||||
if (devid_lb >= 0x12 && devid_lb <= 0x18) {
|
||||
_flashchip->chip_size = flash_sizes[devid_lb - 0x12] << 10;
|
||||
}
|
||||
else {
|
||||
LOG_TAG_WARNING("spi_flash", "could not determine flash size, "
|
||||
"4 MBytes are used as default size\n");
|
||||
_flashchip->chip_size = 4 << 20;
|
||||
}
|
||||
#endif /* MCU_ESP8266 */
|
||||
|
||||
_flash_driver.init = &_flash_init;
|
||||
_flash_driver.read = &_flash_read;
|
||||
_flash_driver.write = &_flash_write;
|
||||
_flash_driver.erase = &_flash_erase;
|
||||
_flash_driver.power = &_flash_power;
|
||||
|
||||
_flash_beg = SPIFFS_FLASH_BEGIN;
|
||||
_flash_end = flashchip->chip_size - 5 * flashchip->sector_size;
|
||||
/* first, set the beginning of flash to 0x0 to read partition table */
|
||||
_flash_beg = 0x0;
|
||||
_flash_end = _flashchip->chip_size - 5 * _flashchip->sector_size;
|
||||
_flash_size = _flash_end - _flash_beg;
|
||||
|
||||
/* read in partition table an determine the top of all partitions */
|
||||
uint32_t part_addr = ESP_PART_TABLE_ADDR;
|
||||
uint8_t part_buf[ESP_PART_ENTRY_SIZE];
|
||||
bool part_read = true;
|
||||
uint32_t part_top = 0;
|
||||
esp_partition_info_t* part = (esp_partition_info_t*)part_buf;
|
||||
|
||||
while (part_read && part_addr < ESP_PART_TABLE_ADDR + ESP_PART_TABLE_SIZE) {
|
||||
spi_flash_read (part_addr, (void*)part_buf, ESP_PART_ENTRY_SIZE);
|
||||
|
||||
if (part->magic == ESP_PART_ENTRY_MAGIC) {
|
||||
DEBUG("%s partition @%08x size=%08x label=%s\n", __func__,
|
||||
part->pos.offset, part->pos.size, part->label);
|
||||
if (part->pos.offset + part->pos.size > part_top) {
|
||||
part_top = part->pos.offset + part->pos.size;
|
||||
}
|
||||
part_addr += ESP_PART_ENTRY_SIZE;
|
||||
}
|
||||
else {
|
||||
part_read = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
/* map the partition top address to next higher multiple of 0x100000 (1 MB) */
|
||||
part_top = (part_top + 0x100000) & ~0xfffff;
|
||||
#else /* MCU_ESP32 */
|
||||
/* map the partition top address to next higher multiple of 0x80000 (512 kB) */
|
||||
part_top = (part_top + 0x80000) & ~0x7ffff;
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
/*
|
||||
* if flash drive start address is not configured, use the determined
|
||||
* one otherwise check the configured one and use it
|
||||
*/
|
||||
#if SPI_FLASH_DRIVE_START
|
||||
if (part_top > SPI_FLASH_DRIVE_START) {
|
||||
LOG_TAG_ERROR("spi_flash", "configured MTD start address in SPI Flash is to less\n");
|
||||
}
|
||||
else if (SPI_FLASH_DRIVE_START % _flashchip->sector_size) {
|
||||
LOG_TAG_ERROR("spi_flash", "configured start address has to be a "
|
||||
"multiple of %d byte\n", _flashchip->sector_size);
|
||||
part_top = ((SPI_FLASH_DRIVE_START +
|
||||
_flashchip->sector_size)) & ~(_flashchip->sector_size-1);
|
||||
}
|
||||
else {
|
||||
part_top = SPI_FLASH_DRIVE_START;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* second, change flash parameters according to partition table */
|
||||
_flash_beg = part_top;
|
||||
_flash_end = _flashchip->chip_size - 5 * _flashchip->sector_size;
|
||||
_flash_size = _flash_end - _flash_beg; /* MUST be at least 3 sectors (0x3000) */
|
||||
|
||||
LOG_TAG_INFO("spi_flash", "MTD in SPI flash starts at address 0x%08x "
|
||||
"with a size of %d kbytes\n", _flash_beg, _flash_size >> 10);
|
||||
|
||||
_flash_dev.driver = &_flash_driver;
|
||||
_flash_dev.sector_count = _flash_size / flashchip->sector_size;
|
||||
_flash_dev.sector_count = _flash_size / _flashchip->sector_size;
|
||||
|
||||
mtd0 = &_flash_dev;
|
||||
|
||||
_flash_dev.pages_per_sector = flashchip->sector_size / flashchip->page_size;
|
||||
_flash_dev.page_size = flashchip->page_size;
|
||||
_flash_dev.pages_per_sector = _flashchip->sector_size / _flashchip->page_size;
|
||||
_flash_dev.page_size = _flashchip->page_size;
|
||||
|
||||
DEBUG("%s flashchip chip_size=%d block_size=%d sector_size=%d page_size=%d\n", __func__,
|
||||
flashchip->chip_size, flashchip->block_size,
|
||||
flashchip->sector_size, flashchip->page_size);
|
||||
_flashchip->chip_size, _flashchip->block_size,
|
||||
_flashchip->sector_size, _flashchip->page_size);
|
||||
DEBUG("%s flash_dev sector_count=%d pages_per_sector=%d page_size=%d\n", __func__,
|
||||
_flash_dev.sector_count, _flash_dev.pages_per_sector, _flash_dev.page_size);
|
||||
DEBUG("\n");
|
||||
}
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
|
||||
#define RETURN_WITH_ESP_ERR_CODE(err) do { \
|
||||
switch (err) { \
|
||||
case ESP_ROM_SPIFLASH_RESULT_OK : return ESP_OK; \
|
||||
case ESP_ROM_SPIFLASH_RESULT_ERR : return ESP_ERR_FLASH_OP_FAIL; \
|
||||
case ESP_ROM_SPIFLASH_RESULT_TIMEOUT: return ESP_ERR_FLASH_OP_TIMEOUT; \
|
||||
} \
|
||||
return ESP_FAIL; \
|
||||
} while(0)
|
||||
|
||||
uint8_t _flash_buf[ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM];
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_read(size_t addr, void *buff, size_t size)
|
||||
{
|
||||
DEBUG("%s addr=%08x size=%u buf=%p\n", __func__, addr, size, buff);
|
||||
|
||||
CHECK_PARAM_RET (buff != NULL, -ENOTSUP);
|
||||
|
||||
/* size must be within the flash address space */
|
||||
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
|
||||
|
||||
int result = ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
uint32_t len = size;
|
||||
|
||||
/* if addr is not 4 byte aligned, we need to read the first full word */
|
||||
if (addr & 0x3) {
|
||||
uint32_t word_addr = addr & ~0x3;
|
||||
uint32_t pos_in_word = addr & 0x3;
|
||||
uint32_t len_in_word = 4 - pos_in_word;
|
||||
len_in_word = (len_in_word < len) ? len_in_word : len;
|
||||
|
||||
/* disable interrupts and the cache */
|
||||
critical_enter();
|
||||
Cache_Read_Disable(PRO_CPU_NUM);
|
||||
|
||||
result = esp_rom_spiflash_read (word_addr, (uint32_t*)_flash_buf, 4);
|
||||
memcpy(buff, _flash_buf + pos_in_word, len_in_word);
|
||||
|
||||
/* enable interrupts and the cache */
|
||||
Cache_Read_Enable(PRO_CPU_NUM);
|
||||
critical_exit();
|
||||
|
||||
buff = (uint8_t*)buff + len_in_word;
|
||||
addr += len_in_word;
|
||||
len -= len_in_word;
|
||||
}
|
||||
|
||||
/* read all full words, maximum ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM
|
||||
in one read operation */
|
||||
while (len > 4 && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
uint32_t len_full_words = len & ~0x3;
|
||||
if (len_full_words > ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) {
|
||||
len_full_words = ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
|
||||
}
|
||||
|
||||
/* disable interrupts and the cache */
|
||||
critical_enter();
|
||||
Cache_Read_Disable(PRO_CPU_NUM);
|
||||
|
||||
result |= esp_rom_spiflash_read (addr, (uint32_t*)_flash_buf, len_full_words);
|
||||
memcpy(buff, _flash_buf, len_full_words);
|
||||
|
||||
/* enable interrupts and the cache */
|
||||
Cache_Read_Enable(PRO_CPU_NUM);
|
||||
critical_exit();
|
||||
|
||||
buff = (uint8_t*)buff + len_full_words;
|
||||
addr += len_full_words;
|
||||
len -= len_full_words;
|
||||
}
|
||||
|
||||
/* if there is some remaining, we need to prepare last word */
|
||||
if (len && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
/* disable interrupts and the cache */
|
||||
critical_enter();
|
||||
Cache_Read_Disable(PRO_CPU_NUM);
|
||||
|
||||
result |= esp_rom_spiflash_read (addr, (uint32_t*)_flash_buf, 4);
|
||||
memcpy(buff, _flash_buf, len);
|
||||
|
||||
/* enable interrupts and the cache */
|
||||
Cache_Read_Enable(PRO_CPU_NUM);
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
||||
RETURN_WITH_ESP_ERR_CODE(result);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_write(size_t addr, const void *buff, size_t size)
|
||||
{
|
||||
DEBUG("%s addr=%08x size=%u buf=%p\n", __func__, addr, size, buff);
|
||||
|
||||
CHECK_PARAM_RET (buff != NULL, -ENOTSUP);
|
||||
|
||||
/* size must be within the flash address space */
|
||||
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
|
||||
|
||||
/* prepare for write access */
|
||||
int result = esp_rom_spiflash_unlock();
|
||||
uint32_t len = size;
|
||||
|
||||
/* if addr is not 4 byte aligned, we need to prepare first full word */
|
||||
if (addr & 0x3 && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
uint32_t word_addr = addr & ~0x3;
|
||||
uint32_t pos_in_word = addr & 0x3;
|
||||
uint32_t len_in_word = 4 - pos_in_word;
|
||||
len_in_word = (len_in_word < len) ? len_in_word : len;
|
||||
|
||||
/* disable interrupts and the cache */
|
||||
critical_enter();
|
||||
Cache_Read_Disable(PRO_CPU_NUM);
|
||||
|
||||
result |= esp_rom_spiflash_read (word_addr, (uint32_t*)_flash_buf, 4);
|
||||
memcpy(_flash_buf + pos_in_word, buff, len_in_word);
|
||||
result |= esp_rom_spiflash_write (word_addr, (uint32_t*)_flash_buf, 4);
|
||||
|
||||
/* enable interrupts and the cache */
|
||||
Cache_Read_Enable(PRO_CPU_NUM);
|
||||
critical_exit();
|
||||
|
||||
buff = (uint8_t*)buff + len_in_word;
|
||||
addr += len_in_word;
|
||||
len -= len_in_word;
|
||||
}
|
||||
|
||||
/* write all full words, maximum ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM
|
||||
in one write operation */
|
||||
while (len > 4 && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
uint32_t len_full_words = len & ~0x3;
|
||||
if (len_full_words > ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM) {
|
||||
len_full_words = ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM;
|
||||
}
|
||||
|
||||
/* disable interrupts and the cache */
|
||||
critical_enter();
|
||||
Cache_Read_Disable(PRO_CPU_NUM);
|
||||
|
||||
memcpy(_flash_buf, buff, len_full_words);
|
||||
result |= esp_rom_spiflash_write (addr, (uint32_t*)_flash_buf, len_full_words);
|
||||
|
||||
/* enable interrupts and the cache */
|
||||
Cache_Read_Enable(PRO_CPU_NUM);
|
||||
critical_exit();
|
||||
|
||||
buff = (uint8_t*)buff + len_full_words;
|
||||
addr += len_full_words;
|
||||
len -= len_full_words;
|
||||
}
|
||||
|
||||
/* if there is some remaining, we need to prepare last word */
|
||||
if (len && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
/* disable interrupts and the cache */
|
||||
critical_enter();
|
||||
Cache_Read_Disable(PRO_CPU_NUM);
|
||||
|
||||
result |= esp_rom_spiflash_read (addr, (uint32_t*)_flash_buf, 4);
|
||||
memcpy(_flash_buf, buff, len);
|
||||
result |= esp_rom_spiflash_write (addr, (uint32_t*)_flash_buf, 4);
|
||||
|
||||
/* enable interrupts and the cache */
|
||||
Cache_Read_Enable(PRO_CPU_NUM);
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
/* reset write access */
|
||||
esp_rom_spiflash_lock();
|
||||
|
||||
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
||||
RETURN_WITH_ESP_ERR_CODE(result);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_erase_sector(size_t sector)
|
||||
{
|
||||
return spi_flash_erase_range(sector * _flashchip->sector_size, 1);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_erase_range(size_t addr, size_t size)
|
||||
{
|
||||
/* size must be within the flash address space */
|
||||
CHECK_PARAM_RET (addr + size <= _flash_end, -EOVERFLOW);
|
||||
|
||||
/* size must be a multiple of sector_size && at least one sector */
|
||||
CHECK_PARAM_RET (size >= _flashchip->sector_size, -ENOTSUP);
|
||||
CHECK_PARAM_RET (size % _flashchip->sector_size == 0, -ENOTSUP)
|
||||
|
||||
/* prepare for write access */
|
||||
uint32_t result = esp_rom_spiflash_unlock();
|
||||
|
||||
/* erase as many sectors as necessary */
|
||||
uint32_t sec = addr / _flashchip->sector_size;
|
||||
uint32_t cnt = size / _flashchip->sector_size;
|
||||
uint32_t sec_per_block = _flashchip->block_size / _flashchip->sector_size;
|
||||
|
||||
while (cnt && result == ESP_ROM_SPIFLASH_RESULT_OK) {
|
||||
/* disable interrupts and the cache */
|
||||
critical_enter();
|
||||
Cache_Read_Disable(PRO_CPU_NUM);
|
||||
|
||||
/* erase block-wise (64 kByte) if cnt is at least sec_per_block */
|
||||
if (cnt >= sec_per_block) {
|
||||
result = esp_rom_spiflash_erase_block (sec / sec_per_block);
|
||||
sec += sec_per_block;
|
||||
cnt -= sec_per_block;
|
||||
}
|
||||
else {
|
||||
result = esp_rom_spiflash_erase_sector (sec++);
|
||||
cnt--;
|
||||
}
|
||||
|
||||
/* enable interrupts and the cache */
|
||||
Cache_Read_Enable(PRO_CPU_NUM);
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
/* reset write access */
|
||||
esp_rom_spiflash_lock();
|
||||
|
||||
/* return with the ESP-IDF error code that is mapped from ROM error code */
|
||||
RETURN_WITH_ESP_ERR_CODE(result);
|
||||
}
|
||||
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
const esp_partition_t* esp_partition_find_first(esp_partition_type_t type,
|
||||
esp_partition_subtype_t subtype,
|
||||
const char* label)
|
||||
{
|
||||
uint32_t info_addr = ESP_PART_TABLE_ADDR;
|
||||
uint8_t info_buf[ESP_PART_ENTRY_SIZE];
|
||||
bool info_read = true;
|
||||
|
||||
esp_partition_info_t* info = (esp_partition_info_t*)info_buf;
|
||||
esp_partition_t* part;
|
||||
|
||||
while (info_read && info_addr < ESP_PART_TABLE_ADDR + ESP_PART_TABLE_SIZE) {
|
||||
spi_flash_read (info_addr, (void*)info_buf, ESP_PART_ENTRY_SIZE);
|
||||
|
||||
if (info->magic == ESP_PART_ENTRY_MAGIC) {
|
||||
DEBUG("%s partition @%08x size=%08x label=%s\n", __func__,
|
||||
info->pos.offset, info->pos.size, info->label);
|
||||
if ((info->type == type) &&
|
||||
(info->subtype == subtype || subtype == ESP_PARTITION_SUBTYPE_ANY) &&
|
||||
(label == NULL || strcmp((const char*)info->label, label) == 0)) {
|
||||
part = malloc(sizeof(esp_partition_t));
|
||||
part->type = info->type;
|
||||
part->subtype = info->subtype;
|
||||
part->address = info->pos.offset;
|
||||
part->size = info->pos.size;
|
||||
part->encrypted = info->flags & PART_FLAG_ENCRYPTED;
|
||||
strncpy(part->label, (const char*)info->label, sizeof(info->label));
|
||||
part->label[sizeof(part->label) - 1] = 0x0;
|
||||
|
||||
return part;
|
||||
}
|
||||
info_addr += ESP_PART_ENTRY_SIZE;
|
||||
}
|
||||
else {
|
||||
info_read = false;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t esp_partition_erase_range(const esp_partition_t* part,
|
||||
size_t addr, size_t size)
|
||||
{
|
||||
CHECK_PARAM_RET(part != NULL, ESP_ERR_INVALID_ARG);
|
||||
|
||||
/* start addr and size must be inside the partition */
|
||||
CHECK_PARAM_RET(addr <= part->size, ESP_ERR_INVALID_ARG);
|
||||
CHECK_PARAM_RET(addr + size <= part->size, ESP_ERR_INVALID_SIZE);
|
||||
/* start addr and size must be a multiple of sector size */
|
||||
CHECK_PARAM_RET(addr % SPI_FLASH_SEC_SIZE == 0, ESP_ERR_INVALID_ARG);
|
||||
CHECK_PARAM_RET(size % SPI_FLASH_SEC_SIZE == 0, ESP_ERR_INVALID_SIZE);
|
||||
|
||||
return spi_flash_erase_range(part->address + addr, size);
|
||||
}
|
||||
|
||||
|
||||
static int _flash_init (mtd_dev_t *dev)
|
||||
{
|
||||
DEBUG("%s dev=%p driver=%p\n", __func__, dev, &_flash_driver);
|
||||
|
||||
CHECK_PARAM_RET (dev == &_flash_dev, -ENODEV);
|
||||
|
||||
#ifdef SPI_FLASH_CHIP_SIZE
|
||||
if (SPI_FLASH_CHIP_SIZE <= SPIFFS_FLASH_BEGIN) {
|
||||
#else
|
||||
if (flashchip->chip_size <= SPIFFS_FLASH_BEGIN) {
|
||||
#endif
|
||||
if (_flashchip->chip_size <= _flash_beg) {
|
||||
LOG_ERROR("Flash size is equal or less than %d Byte, "
|
||||
"SPIFFS cannot be used\n", SPIFFS_FLASH_BEGIN);
|
||||
"SPIFFS cannot be used\n", _flash_beg);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SPI_FLASH_BUF_SIZE 64
|
||||
uint8_t _flash_buf[SPI_FLASH_BUF_SIZE];
|
||||
|
||||
static int _flash_read (mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t size)
|
||||
{
|
||||
DEBUG("%s dev=%p addr=%08x size=%u buf=%p\n", __func__, dev, addr, size, buff);
|
||||
@ -119,58 +508,7 @@ static int _flash_read (mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t siz
|
||||
/* size must be within the flash address space */
|
||||
CHECK_PARAM_RET (_flash_beg + addr + size <= _flash_end, -EOVERFLOW);
|
||||
|
||||
#ifndef SDK_FLASH_FUNCTIONS
|
||||
bool result = spiflash_read (_flash_beg + addr, buff, size);
|
||||
return result ? (int)size : -EIO;
|
||||
#else
|
||||
critical_enter();
|
||||
|
||||
/* it would be great if would work in that way, but would be too easy :-( */
|
||||
/* memcpy(buff, (void*)(_flash_beg + addr + 0x40200000), size); */
|
||||
|
||||
int result = SPI_FLASH_RESULT_OK;
|
||||
uint32_t len = size;
|
||||
|
||||
/* if addr is not 4 byte aligned, we need to read the first full word */
|
||||
if (addr & 0x3) {
|
||||
uint32_t word_addr = addr & ~0x3;
|
||||
uint32_t pos_in_word = addr & 0x3;
|
||||
uint32_t len_in_word = 4 - pos_in_word;
|
||||
len_in_word = (len_in_word < len) ? len_in_word : len;
|
||||
|
||||
result = spi_flash_read (_flash_beg + word_addr, (uint32_t*)_flash_buf, 4);
|
||||
memcpy(buff, _flash_buf + pos_in_word, len_in_word);
|
||||
|
||||
buff = (uint8_t*)buff + len_in_word;
|
||||
addr += len_in_word;
|
||||
len -= len_in_word;
|
||||
}
|
||||
|
||||
/* read all full words, maximum SPI_FLASH_BUF_SIZE in one write operation */
|
||||
while (result == SPI_FLASH_RESULT_OK && len > 4) {
|
||||
uint32_t len_full_words = len & ~0x3;
|
||||
|
||||
if (len_full_words > SPI_FLASH_BUF_SIZE) {
|
||||
len_full_words = SPI_FLASH_BUF_SIZE;
|
||||
}
|
||||
|
||||
result |= spi_flash_read (_flash_beg + addr, (uint32_t*)_flash_buf, len_full_words);
|
||||
memcpy(buff, _flash_buf, len_full_words);
|
||||
|
||||
buff = (uint8_t*)buff + len_full_words;
|
||||
addr += len_full_words;
|
||||
len -= len_full_words;
|
||||
}
|
||||
|
||||
/* if there is some remaining, we need to prepare last word */
|
||||
if (result == SPI_FLASH_RESULT_OK && len) {
|
||||
result |= spi_flash_read (_flash_beg + addr, (uint32_t*)_flash_buf, 4);
|
||||
memcpy(buff, _flash_buf, len);
|
||||
}
|
||||
|
||||
critical_exit();
|
||||
return (result == SPI_FLASH_RESULT_OK) ? (int)size : -EIO;
|
||||
#endif
|
||||
return (spi_flash_read(_flash_beg + addr, buff, size) == ESP_OK) ? (int)size : -EIO;
|
||||
}
|
||||
|
||||
static int _flash_write (mtd_dev_t *dev, const void *buff, uint32_t addr, uint32_t size)
|
||||
@ -183,60 +521,11 @@ static int _flash_write (mtd_dev_t *dev, const void *buff, uint32_t addr, uint32
|
||||
/* size must be within the flash address space */
|
||||
CHECK_PARAM_RET (_flash_beg + addr + size <= _flash_end, -EOVERFLOW);
|
||||
|
||||
#ifndef SDK_FLASH_FUNCTIONS
|
||||
/* addr + size must be within a page */
|
||||
CHECK_PARAM_RET (size <= _flashchip->page_size, -EOVERFLOW);
|
||||
CHECK_PARAM_RET ((addr % _flashchip->page_size) + size <= _flashchip->page_size, -EOVERFLOW);
|
||||
|
||||
bool result = spiflash_write (_flash_beg + addr, (uint8_t*)buff, size);
|
||||
return result ? (int)size : -EIO;
|
||||
|
||||
#else
|
||||
|
||||
critical_enter();
|
||||
|
||||
int result = SPI_FLASH_RESULT_OK;
|
||||
uint32_t len = size;
|
||||
|
||||
/* if addr is not 4 byte aligned, we need to prepare first full word */
|
||||
if (addr & 0x3) {
|
||||
uint32_t word_addr = addr & ~0x3;
|
||||
uint32_t pos_in_word = addr & 0x3;
|
||||
uint32_t len_in_word = 4 - pos_in_word;
|
||||
len_in_word = (len_in_word < len) ? len_in_word : len;
|
||||
|
||||
result = spi_flash_read (_flash_beg + word_addr, (uint32_t*)_flash_buf, 4);
|
||||
memcpy(_flash_buf + pos_in_word, buff, len_in_word);
|
||||
result |= spi_flash_write (_flash_beg + word_addr, (uint32_t*)_flash_buf, 4);
|
||||
|
||||
buff = (uint8_t*)buff + len_in_word;
|
||||
addr += len_in_word;
|
||||
len -= len_in_word;
|
||||
}
|
||||
|
||||
/* write all full words, maximum SPI_FLASH_BUF_SIZE in one write operation */
|
||||
while (result == SPI_FLASH_RESULT_OK && len > 4) {
|
||||
uint32_t len_full_words = len & ~0x3;
|
||||
|
||||
if (len_full_words > SPI_FLASH_BUF_SIZE) {
|
||||
len_full_words = SPI_FLASH_BUF_SIZE;
|
||||
}
|
||||
|
||||
memcpy(_flash_buf, buff, len_full_words);
|
||||
result |= spi_flash_write (_flash_beg + addr, (uint32_t*)_flash_buf, len_full_words);
|
||||
|
||||
buff = (uint8_t*)buff + len_full_words;
|
||||
addr += len_full_words;
|
||||
len -= len_full_words;
|
||||
}
|
||||
|
||||
/* if there is some remaining, we need to prepare last word */
|
||||
if (result == SPI_FLASH_RESULT_OK && len) {
|
||||
result |= spi_flash_read (_flash_beg + addr, (uint32_t*)_flash_buf, 4);
|
||||
memcpy(_flash_buf, buff, len);
|
||||
result |= spi_flash_write (_flash_beg + addr, (uint32_t*)_flash_buf, 4);
|
||||
}
|
||||
|
||||
critical_exit();
|
||||
return (result == SPI_FLASH_RESULT_OK) ? (int)size : -EIO;
|
||||
#endif
|
||||
return (spi_flash_write(_flash_beg + addr, buff, size) == ESP_OK) ? (int)size : -EIO;
|
||||
}
|
||||
|
||||
static int _flash_erase (mtd_dev_t *dev, uint32_t addr, uint32_t size)
|
||||
@ -249,34 +538,10 @@ static int _flash_erase (mtd_dev_t *dev, uint32_t addr, uint32_t size)
|
||||
CHECK_PARAM_RET (_flash_beg + addr + size <= _flash_end, -EOVERFLOW);
|
||||
|
||||
/* size must be a multiple of sector_size && at least one sector */
|
||||
CHECK_PARAM_RET (size >= flashchip->sector_size, -ENOTSUP);
|
||||
CHECK_PARAM_RET (size % flashchip->sector_size == 0, -ENOTSUP)
|
||||
CHECK_PARAM_RET (size >= _flashchip->sector_size, -EOVERFLOW);
|
||||
CHECK_PARAM_RET (size % _flashchip->sector_size == 0, -EOVERFLOW)
|
||||
|
||||
#ifndef SDK_FLASH_FUNCTIONS
|
||||
bool result = false;
|
||||
uint32_t count = size / flashchip->sector_size;
|
||||
while (count--) {
|
||||
uint32_t sec = _flash_beg + addr + count * flashchip->sector_size;
|
||||
if (!(result = spiflash_erase_sector (sec))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result ? 0 : -EIO;
|
||||
#else
|
||||
critical_enter();
|
||||
|
||||
uint32_t result = SPI_FLASH_RESULT_OK;
|
||||
uint32_t count = size / flashchip->sector_size;
|
||||
while (count--) {
|
||||
uint32_t sec = (_flash_beg + addr) / flashchip->sector_size + count;
|
||||
if ((result = spi_flash_erase_sector (sec)) != SPI_FLASH_RESULT_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
critical_exit();
|
||||
return result;
|
||||
#endif
|
||||
return (spi_flash_erase_range(_flash_beg + addr, size) == ESP_OK) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int _flash_power (mtd_dev_t *dev, enum mtd_power_state power)
|
||||
@ -285,3 +550,5 @@ static int _flash_power (mtd_dev_t *dev, enum mtd_power_state power)
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
#endif /* MODULE_MTD */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -26,17 +26,17 @@
|
||||
#include "log.h"
|
||||
#include "periph/gpio.h" /* RIOT gpio.h */
|
||||
|
||||
#include "c_types.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "ets_sys.h"
|
||||
#include "esp8266/eagle_soc.h"
|
||||
#include "esp8266/gpio_register.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "sdk/ets.h"
|
||||
#include "esp/gpio_regs.h"
|
||||
#include "esp/iomux_regs.h"
|
||||
#include "esp/rtc_regs.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "gpio_common.h"
|
||||
#include "esp_common.h"
|
||||
#include "gpio_arch.h"
|
||||
#include "irq_arch.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
const uint8_t _gpio_to_iomux[] = { 12, 5, 13, 4, 14, 15, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3 };
|
||||
const uint8_t _iomux_to_gpio[] = { 12, 13, 14, 15, 3, 1, 6, 7, 8, 9, 10, 11, 0, 2, 4, 5 };
|
||||
|
||||
_gpio_pin_usage_t _gpio_pin_usage [GPIO_PIN_NUMOF] =
|
||||
gpio_pin_usage_t _gpio_pin_usage [GPIO_PIN_NUMOF] =
|
||||
{
|
||||
_GPIO, /* gpio0 */
|
||||
|
||||
@ -75,6 +75,12 @@ _gpio_pin_usage_t _gpio_pin_usage [GPIO_PIN_NUMOF] =
|
||||
_GPIO /* gpio16 */
|
||||
};
|
||||
|
||||
/* String representation of usage types */
|
||||
const char* _gpio_pin_usage_str[] =
|
||||
{
|
||||
"GPIO", "I2C", "PWM", "SPI", "SPI Flash", "UART", "N/A"
|
||||
};
|
||||
|
||||
int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
{
|
||||
DEBUG("%s: %d %d\n", __func__, pin, mode);
|
||||
@ -285,3 +291,20 @@ void gpio_toggle (gpio_t pin)
|
||||
|
||||
GPIO.OUT ^= BIT(pin);
|
||||
}
|
||||
|
||||
int gpio_set_pin_usage(gpio_t pin, gpio_pin_usage_t usage)
|
||||
{
|
||||
CHECK_PARAM_RET(pin < GPIO_PIN_NUMOF, -1);
|
||||
_gpio_pin_usage [pin] = usage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gpio_pin_usage_t gpio_get_pin_usage (gpio_t pin)
|
||||
{
|
||||
return (pin < GPIO_PIN_NUMOF) ? _gpio_pin_usage[pin] : _NOT_EXIST;
|
||||
}
|
||||
|
||||
const char* gpio_get_pin_usage_str(gpio_t pin)
|
||||
{
|
||||
return _gpio_pin_usage_str[_gpio_pin_usage[((pin < GPIO_PIN_NUMOF) ? pin : _NOT_EXIST)]];
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -22,8 +22,13 @@
|
||||
#include "cpu.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/hwrng.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "esp/wdev_regs.h"
|
||||
#ifdef MCU_ESP32
|
||||
static const uint32_t* RNG_DATA_REG = (uint32_t*)0x3ff75144;
|
||||
#else
|
||||
static const uint32_t* RNG_DATA_REG = (uint32_t*)0x3ff20e44;
|
||||
#endif
|
||||
|
||||
void hwrng_init(void)
|
||||
{
|
||||
@ -37,7 +42,7 @@ void hwrng_read(void *buf, unsigned int num)
|
||||
|
||||
while (count < num) {
|
||||
/* read next 4 bytes of random data */
|
||||
uint32_t tmp = WDEV.HWRNG;
|
||||
uint32_t tmp = *RNG_DATA_REG;
|
||||
|
||||
/* copy data into result vector */
|
||||
for (int i = 0; i < 4 && count < num; i++) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -7,8 +7,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_esp8266
|
||||
* @ingroup drivers_periph_i2c
|
||||
* @ingroup cpu_esp8266
|
||||
* @ingroup drivers_periph_i2c
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
@ -22,18 +22,16 @@
|
||||
/*
|
||||
PLEASE NOTE:
|
||||
|
||||
Some parts of the implementation bases on the bit-banging implementation as
|
||||
described in [wikipedia](https://en.wikipedia.org/wiki/I%C2%B2C) as well as
|
||||
its implementation in [esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos.git).
|
||||
These parts are under the copyright of their respective owners.
|
||||
The implementation bases on the bit-banging I2C master implementation as
|
||||
described in [wikipedia](https://en.wikipedia.org/wiki/I%C2%B2C#Example_of_bit-banging_the_I%C2%B2C_master_protocol).
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "log.h"
|
||||
@ -42,20 +40,36 @@
|
||||
#include "periph/gpio.h"
|
||||
#include "periph/i2c.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "esp_common.h"
|
||||
#include "gpio_arch.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
|
||||
/* max clock stretching counter */
|
||||
#define I2C_CLOCK_STRETCH 200
|
||||
|
||||
/* gpio access macros */
|
||||
#define GPIO_SET(l,h,b) if (b < 32) GPIO.l = BIT(b); else GPIO.h.val = BIT(32-b)
|
||||
#define GPIO_GET(l,h,b) ((b < 32) ? GPIO.l & BIT(b) : GPIO.h.val & BIT(32-b))
|
||||
|
||||
#else /* MCU_ESP32 */
|
||||
|
||||
#include "esp/gpio_regs.h"
|
||||
#include "sdk/ets.h"
|
||||
|
||||
#if defined(I2C_NUMOF) && I2C_NUMOF > 0
|
||||
/* max clock stretching counter (ca. 10 ms) */
|
||||
#define I2C_CLOCK_STRETCH 40000
|
||||
|
||||
/* has to be declared as extern since it is not possible to include */
|
||||
/* user_interface.h due to conflicts with gpio_init */
|
||||
/* following functions have to be declared as extern since it is not possible */
|
||||
/* to include user_interface.h due to conflicts with gpio_init */
|
||||
extern uint8_t system_get_cpu_freq(void);
|
||||
extern bool system_update_cpu_freq(uint8_t freq);
|
||||
|
||||
/* max clock stretching counter (ca. 10 ms) */
|
||||
#define I2C_CLOCK_STRETCH 40000
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -71,50 +85,42 @@ typedef struct
|
||||
uint32_t sda_bit; /* gpio bit mask for faster access */
|
||||
|
||||
uint32_t delay;
|
||||
mutex_t lock;
|
||||
|
||||
} _i2c_bus_t;
|
||||
|
||||
static _i2c_bus_t _i2c_bus[] =
|
||||
{
|
||||
#if defined(I2C0_SDA) && defined(I2C0_SCL)
|
||||
{
|
||||
.speed = I2C0_SPEED,
|
||||
.sda = I2C0_SDA,
|
||||
.scl = I2C0_SCL
|
||||
},
|
||||
#endif
|
||||
#if defined(I2C1_SDA) && defined(I2C1_SCL)
|
||||
{
|
||||
.speed = I2C1_SPEED,
|
||||
.sda = I2C1_SDA,
|
||||
.scl = I2C1_SCL
|
||||
},
|
||||
#endif
|
||||
#if defined(I2C2_SDA) && defined(I2C2_SCL)
|
||||
{
|
||||
.speed = I2C2_SPEED,
|
||||
.sda = I2C2_SDA,
|
||||
.scl = I2C2_SCL
|
||||
},
|
||||
#endif
|
||||
};
|
||||
static _i2c_bus_t _i2c_bus[I2C_NUMOF] = {};
|
||||
|
||||
/* to ensure that I2C is always optimized with -O2 to use the defined delays */
|
||||
#pragma GCC optimize ("O2")
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
static const uint32_t _i2c_delays[][3] =
|
||||
{
|
||||
/* values specify one half-period and are only valid for -O2 option */
|
||||
/* value = [period - 0.25 us (240 MHz) / 0.5us(160MHz) / 1.0us(80MHz)] */
|
||||
/* * cycles per second / 2 */
|
||||
/* 1 us = 16 cycles (80 MHz) / 32 cycles (160 MHz) / 48 cycles (240) */
|
||||
/* values for 80, 160, 240 MHz */
|
||||
[I2C_SPEED_LOW] = {790, 1590, 2390}, /* 10 kbps (period 100 us) */
|
||||
[I2C_SPEED_NORMAL] = { 70, 150, 230}, /* 100 kbps (period 10 us) */
|
||||
[I2C_SPEED_FAST] = { 11, 31, 51}, /* 400 kbps (period 2.5 us) */
|
||||
[I2C_SPEED_FAST_PLUS] = { 0, 7, 15}, /* 1 Mbps (period 1 us) */
|
||||
[I2C_SPEED_HIGH] = { 0, 0, 0} /* 3.4 Mbps (period 0.3 us) not working */
|
||||
};
|
||||
#else /* MCU_ESP32 */
|
||||
static const uint32_t _i2c_delays[][2] =
|
||||
{
|
||||
/* values specify one half-period and are only valid for -O2 option */
|
||||
/* values specify one half-period and are only valid for -O2 option */
|
||||
/* value = [period - 0.5us(160MHz) or 1.0us(80MHz)] * cycles per second / 2 */
|
||||
/* cycles per us = ca. 20 (80 MHz) / ca. 40 (160 MHz) */
|
||||
[I2C_SPEED_LOW] = {1990, 989}, /* 10 kbps (period 100 us) */
|
||||
[I2C_SPEED_NORMAL] = { 190, 89}, /* 100 kbps (period 10 us) */
|
||||
[I2C_SPEED_FAST] = { 40, 16}, /* 400 kbps (period 2.5 us) */
|
||||
[I2C_SPEED_FAST_PLUS] = { 13, 0}, /* 1 Mbps (period 1 us) */
|
||||
/* 1 us = 20 cycles (80 MHz) / 40 cycles (160 MHz) */
|
||||
[I2C_SPEED_LOW] = {989, 1990}, /* 10 kbps (period 100 us) */
|
||||
[I2C_SPEED_NORMAL] = { 89, 190}, /* 100 kbps (period 10 us) */
|
||||
[I2C_SPEED_FAST] = { 16, 40}, /* 400 kbps (period 2.5 us) */
|
||||
[I2C_SPEED_FAST_PLUS] = { 0, 13}, /* 1 Mbps (period 1 us) */
|
||||
[I2C_SPEED_HIGH] = { 0, 0} /* 3.4 Mbps (period 0.3 us) is not working */
|
||||
};
|
||||
|
||||
static mutex_t i2c_bus_lock[I2C_NUMOF] = { MUTEX_INIT };
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
/* forward declaration of internal functions */
|
||||
|
||||
@ -136,51 +142,86 @@ static void _i2c_abort (_i2c_bus_t* bus, const char* func);
|
||||
static void _i2c_clear (_i2c_bus_t* bus);
|
||||
|
||||
/* implementation of i2c interface */
|
||||
|
||||
void i2c_init(i2c_t dev)
|
||||
{
|
||||
if (I2C_NUMOF != ARRAY_SIZE(_i2c_bus)) {
|
||||
LOG_INFO("I2C_NUMOF does not match number of I2C_SDA_x/I2C_SCL_x definitions\n");
|
||||
LOG_INFO("Please check your board configuration in 'board.h'\n");
|
||||
assert(I2C_NUMOF < ARRAY_SIZE(_i2c_bus));
|
||||
assert(dev < I2C_NUMOF_MAX);
|
||||
assert(dev < I2C_NUMOF);
|
||||
|
||||
if (i2c_config[dev].speed == I2C_SPEED_HIGH) {
|
||||
LOG_TAG_INFO("i2c", "I2C_SPEED_HIGH is not supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_PARAM (dev < I2C_NUMOF)
|
||||
mutex_init(&_i2c_bus[dev].lock);
|
||||
|
||||
if (_i2c_bus[dev].speed == I2C_SPEED_HIGH) {
|
||||
LOG_INFO("I2C_SPEED_HIGH is not supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
i2c_acquire (dev);
|
||||
_i2c_bus[dev].scl = i2c_config[dev].scl;
|
||||
_i2c_bus[dev].sda = i2c_config[dev].sda;
|
||||
_i2c_bus[dev].speed = i2c_config[dev].speed;
|
||||
|
||||
_i2c_bus[dev].dev = dev;
|
||||
_i2c_bus[dev].delay =_i2c_delays[_i2c_bus[dev].speed][ets_get_cpu_frequency() == 80 ? 1 : 0];
|
||||
_i2c_bus[dev].scl_bit = BIT(_i2c_bus[dev].scl); /* store bit mask for faster access */
|
||||
_i2c_bus[dev].sda_bit = BIT(_i2c_bus[dev].sda); /* store bit mask for faster access */
|
||||
_i2c_bus[dev].started = false; /* for handling of repeated start condition */
|
||||
|
||||
DEBUG ("%s: scl=%d sda=%d speed=%d\n", __func__,
|
||||
_i2c_bus[dev].scl, _i2c_bus[dev].sda, _i2c_bus[dev].speed);
|
||||
switch (ets_get_cpu_frequency()) {
|
||||
case 80: _i2c_bus[dev].delay = _i2c_delays[_i2c_bus[dev].speed][0]; break;
|
||||
case 160: _i2c_bus[dev].delay = _i2c_delays[_i2c_bus[dev].speed][1]; break;
|
||||
#ifdef MCU_ESP32
|
||||
case 240: _i2c_bus[dev].delay = _i2c_delays[_i2c_bus[dev].speed][2]; break;
|
||||
#endif
|
||||
default : LOG_TAG_INFO("i2c", "I2C software implementation is not "
|
||||
"supported for this CPU frequency: %d MHz\n",
|
||||
ets_get_cpu_frequency());
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG("%s: scl=%d sda=%d speed=%d\n", __func__,
|
||||
_i2c_bus[dev].scl, _i2c_bus[dev].sda, _i2c_bus[dev].speed);
|
||||
|
||||
/* reset the GPIO usage if the pins were used for I2C before */
|
||||
if (gpio_get_pin_usage(_i2c_bus[dev].scl) == _I2C) {
|
||||
gpio_set_pin_usage(_i2c_bus[dev].scl, _GPIO);
|
||||
}
|
||||
if (gpio_get_pin_usage(_i2c_bus[dev].sda) == _I2C) {
|
||||
gpio_set_pin_usage(_i2c_bus[dev].sda, _GPIO);
|
||||
}
|
||||
|
||||
/* Configure and initialize SDA and SCL pin. */
|
||||
#ifdef MCU_ESP32
|
||||
/*
|
||||
* Configure and initialize SDA and SCL pin.
|
||||
* Note: Due to critical timing required by the I2C software
|
||||
* implementation, the ESP8266 GPIOs can not be used directly in GPIO_OD_PU
|
||||
* mode. Instead, the GPIOs are configured in GPIO_IN_PU mode with
|
||||
* open-drain output driver. Signal levels are then realized as following:
|
||||
* ESP32 pins are used in input/output mode with open-drain output driver.
|
||||
* Signal levels are then realized as following:
|
||||
*
|
||||
* - HIGH: Output value 1 lets the pin floating and is pulled-up to high.
|
||||
* - LOW : Output value 0 actively drives the pin to low.
|
||||
*/
|
||||
if (gpio_init(_i2c_bus[dev].scl, GPIO_IN_OD_PU) ||
|
||||
gpio_init(_i2c_bus[dev].sda, GPIO_IN_OD_PU)) {
|
||||
return;
|
||||
}
|
||||
#else /* MCU_ESP32 */
|
||||
/*
|
||||
* Due to critical timing required by the I2C software implementation,
|
||||
* the ESP8266 GPIOs can not be used directly in GPIO_OD_PU mode.
|
||||
* Instead, the GPIOs are configured in GPIO_IN_PU mode with open-drain
|
||||
* output driver. Signal levels are then realized as following:
|
||||
*
|
||||
* - HIGH: The GPIO is used in the configured GPIO_IN_PU mode. In this
|
||||
* mode, the output driver is in open-drain mode and pulled-up.
|
||||
* - LOW : The GPIO is temporarily switched to GPIO_OD_PU mode. In this
|
||||
* mode, the output value 0, which is written during
|
||||
* initialization, actively drives the output to low.
|
||||
* initialization, actively drives the pin to low.
|
||||
*/
|
||||
gpio_init (_i2c_bus[dev].scl, GPIO_IN_PU);
|
||||
gpio_init (_i2c_bus[dev].sda, GPIO_IN_PU);
|
||||
gpio_clear (_i2c_bus[dev].scl);
|
||||
gpio_clear (_i2c_bus[dev].sda);
|
||||
if (gpio_init(_i2c_bus[dev].scl, GPIO_IN_PU) ||
|
||||
gpio_init(_i2c_bus[dev].sda, GPIO_IN_PU)) {
|
||||
return;
|
||||
}
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
/* store the usage type in GPIO table */
|
||||
gpio_set_pin_usage(_i2c_bus[dev].scl, _I2C);
|
||||
gpio_set_pin_usage(_i2c_bus[dev].sda, _I2C);
|
||||
|
||||
/* set SDA and SCL to be floating and pulled-up to high */
|
||||
_i2c_sda_high (&_i2c_bus[dev]);
|
||||
@ -189,16 +230,14 @@ void i2c_init(i2c_t dev)
|
||||
/* clear the bus if necessary (SDA is driven permanently low) */
|
||||
_i2c_clear (&_i2c_bus[dev]);
|
||||
|
||||
i2c_release (dev);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int i2c_acquire(i2c_t dev)
|
||||
{
|
||||
CHECK_PARAM_RET (dev < I2C_NUMOF, -1)
|
||||
assert(dev < I2C_NUMOF);
|
||||
|
||||
mutex_lock(&i2c_bus_lock[dev]);
|
||||
mutex_lock(&_i2c_bus[dev].lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -206,7 +245,7 @@ void i2c_release(i2c_t dev)
|
||||
{
|
||||
assert(dev < I2C_NUMOF);
|
||||
|
||||
mutex_unlock(&i2c_bus_lock[dev]);
|
||||
mutex_unlock(&_i2c_bus[dev].lock);
|
||||
}
|
||||
|
||||
int /* IRAM */ i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len, uint8_t flags)
|
||||
@ -214,7 +253,8 @@ int /* IRAM */ i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len,
|
||||
DEBUG ("%s: dev=%u addr=%02x data=%p len=%d flags=%01x\n",
|
||||
__func__, dev, addr, data, len, flags);
|
||||
|
||||
CHECK_PARAM_RET (dev < I2C_NUMOF, -EINVAL);
|
||||
assert(dev < I2C_NUMOF);
|
||||
|
||||
CHECK_PARAM_RET (len > 0, -EINVAL);
|
||||
CHECK_PARAM_RET (data != NULL, -EINVAL);
|
||||
|
||||
@ -235,7 +275,7 @@ int /* IRAM */ i2c_read_bytes(i2c_t dev, uint16_t addr, void *data, size_t len,
|
||||
/* prepare 10 bit address bytes */
|
||||
uint8_t addr1 = 0xf0 | (addr & 0x0300) >> 7 | I2C_READ;
|
||||
uint8_t addr2 = addr & 0xff;
|
||||
/* send address bytes wit read flag */
|
||||
/* send address bytes with read flag */
|
||||
if ((res = _i2c_write_byte (bus, addr1)) != 0 ||
|
||||
(res = _i2c_write_byte (bus, addr2)) != 0) {
|
||||
/* abort transfer */
|
||||
@ -275,7 +315,8 @@ int /* IRAM */ i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_
|
||||
DEBUG ("%s: dev=%u addr=%02x data=%p len=%d flags=%01x\n",
|
||||
__func__, dev, addr, data, len, flags);
|
||||
|
||||
CHECK_PARAM_RET (dev < I2C_NUMOF, -EINVAL);
|
||||
assert(dev < I2C_NUMOF);
|
||||
|
||||
CHECK_PARAM_RET (len > 0, -EINVAL);
|
||||
CHECK_PARAM_RET (data != NULL, -EINVAL);
|
||||
|
||||
@ -348,74 +389,99 @@ void i2c_poweroff(i2c_t dev)
|
||||
static inline void _i2c_delay (_i2c_bus_t* bus)
|
||||
{
|
||||
/* produces a delay */
|
||||
/* ca. 20 cycles = 1 us (80 MHz) or ca. 40 cycles = 1 us (160 MHz) */
|
||||
|
||||
uint32_t cycles = bus->delay;
|
||||
if (cycles) {
|
||||
__asm__ volatile ("1: _addi.n %0, %0, -1 \n"
|
||||
" bnez %0, 1b \n" : "=r" (cycles) : "0" (cycles));
|
||||
__asm__ volatile ("1: _addi.n %0, %0, -1 \n"
|
||||
" bnez %0, 1b \n" : "=r" (cycles) : "0" (cycles));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Due to critical timing required by the I2C software implementation,
|
||||
* the ESP8266 GPIOs can not be used directly in GPIO_OD_PU mode. Instead,
|
||||
* the GPIOs are configured in GPIO_IN_PU mode with open-drain output driver.
|
||||
* Signal levels are then realized as following:
|
||||
* Please note: SDA and SDL pins are used in GPIO_OD_PU mode
|
||||
* (open-drain with pull-ups).
|
||||
*
|
||||
* - HIGH: The GPIO is used in the configured GPIO_IN_PU mode. In this mode,
|
||||
* the output driver is in open-drain mode and pulled-up.
|
||||
* - LOW : The GPIO is temporarily switched to GPIO_OD_PU mode. In this mode,
|
||||
* the output value 0, which is written during initialization,
|
||||
* actively drives the output to low.
|
||||
* Setting a pin which is in open-drain mode leaves the pin floating and
|
||||
* the signal is pulled up to high. The signal can then be actively driven
|
||||
* to low by a slave. A read operation returns the current signal at the pin.
|
||||
*
|
||||
* Clearing a pin which is in open-drain mode actively drives the signal to
|
||||
* low.
|
||||
*/
|
||||
|
||||
static inline bool _i2c_scl_read(_i2c_bus_t* bus)
|
||||
{
|
||||
/* read SCL status */
|
||||
/* read SCL status (pin is in open-drain mode and set) */
|
||||
#ifdef MCU_ESP32
|
||||
return GPIO_GET(in, in1, bus->scl);
|
||||
#else /* MCU_ESP32 */
|
||||
return GPIO.IN & bus->scl_bit;
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
static inline bool _i2c_sda_read(_i2c_bus_t* bus)
|
||||
{
|
||||
/* read SDA status */
|
||||
/* read SDA status (pin is in open-drain mode and set) */
|
||||
#ifdef MCU_ESP32
|
||||
return GPIO_GET(in, in1, bus->sda);
|
||||
#else /* MCU_ESP32 */
|
||||
return GPIO.IN & bus->sda_bit;
|
||||
}
|
||||
|
||||
static inline void _i2c_scl_low(_i2c_bus_t* bus)
|
||||
{
|
||||
/*
|
||||
* set SCL signal low (switch temporarily to GPIO_OD_PU where the
|
||||
* written output value 0 drives the pin actively to low)
|
||||
*/
|
||||
GPIO.ENABLE_OUT_SET = bus->scl_bit;
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
static inline void _i2c_scl_high(_i2c_bus_t* bus)
|
||||
{
|
||||
#ifdef MCU_ESP32
|
||||
/* set SCL signal high (pin is in open-drain mode and pulled-up) */
|
||||
GPIO_SET(out_w1ts, out1_w1ts, bus->scl);
|
||||
#else /* MCU_ESP32 */
|
||||
/*
|
||||
* set SCL signal high (switch back to GPIO_IN_PU mode, that is the pin is
|
||||
* in open-drain mode and pulled-up to high)
|
||||
*/
|
||||
GPIO.ENABLE_OUT_CLEAR = bus->scl_bit;
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
static inline void _i2c_sda_low(_i2c_bus_t* bus)
|
||||
static inline void _i2c_scl_low(_i2c_bus_t* bus)
|
||||
{
|
||||
#ifdef MCU_ESP32
|
||||
/* set SCL signal low (actively driven to low) */
|
||||
GPIO_SET(out_w1tc, out1_w1tc, bus->scl);
|
||||
#else /* MCU_ESP32 */
|
||||
/*
|
||||
* set SDA signal low (switch temporarily to GPIO_OD_PU where the
|
||||
* set SCL signal low (switch temporarily to GPIO_OD_PU where the
|
||||
* written output value 0 drives the pin actively to low)
|
||||
*/
|
||||
GPIO.ENABLE_OUT_SET = bus->sda_bit;
|
||||
GPIO.ENABLE_OUT_SET = bus->scl_bit;
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
static inline void _i2c_sda_high(_i2c_bus_t* bus)
|
||||
{
|
||||
#ifdef MCU_ESP32
|
||||
/* set SDA signal high (pin is in open-drain mode and pulled-up) */
|
||||
GPIO_SET(out_w1ts, out1_w1ts, bus->sda);
|
||||
#else /* MCU_ESP32 */
|
||||
/*
|
||||
* set SDA signal high (switch back to GPIO_IN_PU mode, that is the pin is
|
||||
* in open-drain mode and pulled-up to high)
|
||||
*/
|
||||
GPIO.ENABLE_OUT_CLEAR = bus->sda_bit;
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
static inline void _i2c_sda_low(_i2c_bus_t* bus)
|
||||
{
|
||||
#ifdef MCU_ESP32
|
||||
/* set SDA signal low (actively driven to low) */
|
||||
GPIO_SET(out_w1tc, out1_w1tc, bus->sda);
|
||||
#else /* MCU_ESP32 */
|
||||
/*
|
||||
* set SDA signal low (switch temporarily to GPIO_OD_PU where the
|
||||
* written output value 0 drives the pin actively to low)
|
||||
*/
|
||||
GPIO.ENABLE_OUT_SET = bus->sda_bit;
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
static void _i2c_clear(_i2c_bus_t* bus)
|
||||
@ -500,7 +566,7 @@ static /* IRAM */ int _i2c_start_cond(_i2c_bus_t* bus)
|
||||
/* SDA = passive HIGH (floating and pulled-up) */
|
||||
_i2c_sda_high (bus);
|
||||
|
||||
/* t_VD;DAT not neccessary */
|
||||
/* t_VD;DAT not necessary */
|
||||
/* _i2c_delay (bus); */
|
||||
|
||||
/* SCL = passive HIGH (floating and pulled-up) */
|
||||
@ -724,7 +790,7 @@ static /* IRAM */ int _i2c_read_byte(_i2c_bus_t* bus, uint8_t *byte, bool ack)
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
*byte = (*byte << 1) | bit;
|
||||
*byte = (*byte << 1) | (bit ? 1 : 0);
|
||||
}
|
||||
|
||||
/* write acknowledgement flag */
|
||||
@ -735,17 +801,8 @@ static /* IRAM */ int _i2c_read_byte(_i2c_bus_t* bus, uint8_t *byte, bool ack)
|
||||
|
||||
void i2c_print_config(void)
|
||||
{
|
||||
for (unsigned bus = 0; bus < I2C_NUMOF; bus++) {
|
||||
LOG_INFO("\tI2C_DEV(%d): scl=%d sda=%d\n",
|
||||
bus, _i2c_bus[bus].scl, _i2c_bus[bus].sda);
|
||||
for (unsigned dev = 0; dev < I2C_NUMOF; dev++) {
|
||||
printf("\tI2C_DEV(%u)\tscl=%d sda=%d\n",
|
||||
dev, i2c_config[dev].scl, i2c_config[dev].sda);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* if defined(I2C_NUMOF) && I2C_NUMOF */
|
||||
|
||||
void i2c_print_config(void)
|
||||
{
|
||||
LOG_INFO("\tI2C: no devices\n");
|
||||
}
|
||||
|
||||
#endif /* if defined(I2C_NUMOF) && I2C_NUMOF */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -18,31 +18,28 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "irq.h"
|
||||
|
||||
#include "esp/xtensa_ops.h"
|
||||
#include "sdk/ets_task.h"
|
||||
#include "sdk/sdk.h"
|
||||
|
||||
#include "syscalls.h"
|
||||
|
||||
void pm_set_lowest(void)
|
||||
{
|
||||
DEBUG ("%s\n", __func__);
|
||||
DEBUG ("%s enter to sleep @%u\n", __func__, system_get_time());
|
||||
|
||||
#if !defined(QEMU)
|
||||
DEBUG ("%s enter to sleep @%u\n", __func__, phy_get_mactime());
|
||||
/* reset system watchdog timer */
|
||||
system_wdt_feed();
|
||||
|
||||
#ifndef MODULE_ESP_QEMU
|
||||
/* passive wait for interrupt to leave lowest power mode */
|
||||
__asm__ volatile ("waiti 0");
|
||||
|
||||
DEBUG ("%s exit from sleep @%u\n", __func__, phy_get_mactime());
|
||||
#endif
|
||||
|
||||
DEBUG ("%s exit from sleep @%u\n", __func__, system_get_time());
|
||||
|
||||
/* reset system watchdog timer */
|
||||
system_wdt_feed();
|
||||
}
|
||||
|
||||
void pm_off(void)
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include "cpu.h"
|
||||
@ -27,21 +27,19 @@
|
||||
#include "periph/pwm.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "esp_common.h"
|
||||
#include "esp/iomux_regs.h"
|
||||
#include "esp/timer_regs.h"
|
||||
#include "gpio_common.h"
|
||||
#include "sdk/ets.h"
|
||||
|
||||
#if defined(PWM_NUMOF) && PWM_NUMOF > 0
|
||||
#include "gpio_arch.h"
|
||||
#include "sdk/sdk.h"
|
||||
#include "xtensa/xtensa_api.h"
|
||||
|
||||
#define TIMER_FRC1_CLKDIV_16 BIT(2)
|
||||
#define TIMER_FRC1_CLKDIV_256 BIT(3)
|
||||
|
||||
#define ETS_FRC1_INT_ENABLE ETS_FRC1_INTR_ENABLE
|
||||
#define ETS_FRC1_INT_DISABLE ETS_FRC1_INTR_DISABLE
|
||||
#define ETS_FRC1_INT_ATTACH ETS_FRC_TIMER1_INTR_ATTACH
|
||||
#define ETS_FRC1_NMI_ATTACH ETS_FRC_TIMER1_NMI_INTR_ATTACH
|
||||
#define ETS_FRC1_INT_ENABLE() xt_ints_on(BIT(ETS_FRC_TIMER1_INUM))
|
||||
#define ETS_FRC1_INT_DISABLE() xt_ints_off(BIT(ETS_FRC_TIMER1_INUM))
|
||||
#define ETS_FRC1_INT_ATTACH(f, a) xt_set_interrupt_handler(ETS_FRC_TIMER1_INUM, f, a)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -65,8 +63,6 @@ typedef struct
|
||||
|
||||
static _pwm_dev_t _pwm_dev;
|
||||
|
||||
static const uint32_t _pwm_channel_gpios[] = PWM0_CHANNEL_GPIOS;
|
||||
|
||||
static void _pwm_timer_handler (void* arg)
|
||||
{
|
||||
irq_isr_enter ();
|
||||
@ -119,14 +115,15 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
{
|
||||
DEBUG ("%s pwm=%u mode=%u freq=%u, res=%u\n", __func__, pwm, mode, freq, res);
|
||||
|
||||
uint8_t _pwm_channel_gpio_num = sizeof(_pwm_channel_gpios) >> 2;
|
||||
uint8_t _pwm_channel_gpio_num = sizeof(pwm0_channels) >> 2;
|
||||
|
||||
CHECK_PARAM_RET (pwm < PWM_NUMOF, 0);
|
||||
CHECK_PARAM_RET (freq > 0, 0);
|
||||
CHECK_PARAM_RET (_pwm_channel_gpio_num <= PWM_CHANNEL_NUM_MAX, 0);
|
||||
assert(pwm < PWM_NUMOF_MAX);
|
||||
assert(pwm < PWM_NUMOF);
|
||||
assert(freq > 0);
|
||||
assert(_pwm_channel_gpio_num <= PWM_CHANNEL_NUM_MAX);
|
||||
|
||||
/* maximum number of cycles per second (freq*res) should not be greater than */
|
||||
/* 100.000 (period of 10 us), reduce freq if neccessary and keep resolution */
|
||||
/* 100.000 (period of 10 us), reduce freq if necessary and keep resolution */
|
||||
if (res * freq > PWM_MAX_CPS) {
|
||||
freq = PWM_MAX_CPS / res;
|
||||
}
|
||||
@ -138,21 +135,21 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
_pwm_dev.mode = mode;
|
||||
|
||||
for (int i = 0; i < _pwm_channel_gpio_num; i++) {
|
||||
if (_gpio_pin_usage[_pwm_channel_gpios[i]] != _GPIO) {
|
||||
if (gpio_get_pin_usage(pwm0_channels[i]) != _GPIO) {
|
||||
LOG_ERROR("GPIO%d is used for something else and cannot be used as PWM output\n", i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gpio_init(_pwm_channel_gpios[i], GPIO_OUT) < 0) {
|
||||
if (gpio_init(pwm0_channels[i], GPIO_OUT) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
gpio_clear (_pwm_channel_gpios[i]);
|
||||
gpio_clear (pwm0_channels[i]);
|
||||
|
||||
_pwm_dev.chn[_pwm_dev.chn_num].duty = 0;
|
||||
_pwm_dev.chn[_pwm_dev.chn_num].next_on = 0;
|
||||
_pwm_dev.chn[_pwm_dev.chn_num].next_off = 0;
|
||||
_pwm_dev.chn[_pwm_dev.chn_num].gpio = _pwm_channel_gpios[i];
|
||||
_pwm_dev.chn[_pwm_dev.chn_num].gpio = pwm0_channels[i];
|
||||
|
||||
_pwm_dev.chn_num++;
|
||||
}
|
||||
@ -169,7 +166,7 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
|
||||
uint8_t pwm_channels(pwm_t pwm)
|
||||
{
|
||||
CHECK_PARAM_RET (pwm < PWM_NUMOF, 0);
|
||||
assert(pwm < PWM_NUMOF);
|
||||
|
||||
return _pwm_dev.chn_num;
|
||||
}
|
||||
@ -178,9 +175,9 @@ void pwm_set(pwm_t pwm, uint8_t channel, uint16_t value)
|
||||
{
|
||||
DEBUG("%s pwm=%u channel=%u value=%u\n", __func__, pwm, channel, value);
|
||||
|
||||
CHECK_PARAM (pwm < PWM_NUMOF);
|
||||
CHECK_PARAM (channel < _pwm_dev.chn_num);
|
||||
CHECK_PARAM (value <= _pwm_dev.res);
|
||||
assert(pwm < PWM_NUMOF);
|
||||
assert(channel < _pwm_dev.chn_num);
|
||||
assert(value <= _pwm_dev.res);
|
||||
|
||||
uint32_t state = irq_disable();
|
||||
uint32_t phase = _pwm_dev.cycles - _pwm_dev.cycles % _pwm_dev.res;
|
||||
@ -226,25 +223,16 @@ void pwm_poweron(pwm_t pwm)
|
||||
|
||||
void pwm_poweroff(pwm_t pwm)
|
||||
{
|
||||
CHECK_PARAM (pwm < PWM_NUMOF);
|
||||
assert(pwm < PWM_NUMOF);
|
||||
|
||||
_pwm_stop ();
|
||||
}
|
||||
|
||||
void pwm_print_config(void)
|
||||
{
|
||||
LOG_INFO("\tPWM_DEV(0): channels=[ ");
|
||||
for (unsigned i = 0; i < sizeof(_pwm_channel_gpios) >> 2; i++) {
|
||||
LOG_INFO("%d ", _pwm_channel_gpios[i]);
|
||||
printf("\tPWM_DEV(0)\tchannels=[ ");
|
||||
for (unsigned i = 0; i < sizeof(pwm0_channels) >> 2; i++) {
|
||||
printf("%d ", pwm0_channels[i]);
|
||||
}
|
||||
LOG_INFO("]\n");
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
#else /* defined(PWM_NUMOF) && PWM_NUMOF > 0 */
|
||||
|
||||
void pwm_print_config(void)
|
||||
{
|
||||
LOG_INFO("\tPWM: no devices\n");
|
||||
}
|
||||
|
||||
#endif /* defined(PWM_NUMOF) && PWM_NUMOF > 0 */
|
||||
|
||||
@ -26,9 +26,9 @@
|
||||
#include "log.h"
|
||||
#include "periph/rtc.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "esp_common.h"
|
||||
|
||||
#include "sdk/ets.h"
|
||||
#include "sdk/sdk.h"
|
||||
|
||||
void rtc_init(void)
|
||||
{
|
||||
|
||||
@ -21,32 +21,77 @@
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
#include "common.h"
|
||||
#include "esp_common.h"
|
||||
#include "log.h"
|
||||
|
||||
#if defined(MODULE_PERIPH_SPI)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mutex.h"
|
||||
#include "periph/spi.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "gpio_arch.h"
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_struct.h"
|
||||
|
||||
#else /* MCU_ESP32 */
|
||||
|
||||
#include "esp/iomux_regs.h"
|
||||
#include "esp/spi_regs.h"
|
||||
#include "esp8266/spi_register.h"
|
||||
#include "esp8266/spi_struct.h"
|
||||
|
||||
#include "gpio_common.h"
|
||||
#define SPI_DOUTDIN (BIT(0))
|
||||
|
||||
#define SPI_BUS_NUM 2
|
||||
#define SPI_BLOCK_SIZE 64 /* number of bytes per SPI transfer */
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
static mutex_t _spi_lock[SPI_BUS_NUM] = { MUTEX_INIT };
|
||||
#define SPI_BLOCK_SIZE 64 /* number of bytes per SPI transfer */
|
||||
|
||||
/* indicate whether SPI interface were already initilized */
|
||||
static bool _spi_initialized[SPI_BUS_NUM] = { false };
|
||||
/* pins of FSI are fixed */
|
||||
#define FSPI_SCK GPIO6
|
||||
#define FSPI_MISO GPIO7
|
||||
#define FSPI_MOSI GPIO8
|
||||
|
||||
/* indicate whether pins of the SPI interface were already initilized */
|
||||
static bool _spi_pins_initialized[SPI_BUS_NUM] = { false };
|
||||
/** structure which describes all properties of one SPI bus */
|
||||
struct _spi_bus_t {
|
||||
spi_dev_t* regs; /* pointer to register data struct of the SPI device */
|
||||
mutex_t lock; /* mutex for each possible SPI interface */
|
||||
bool initialized; /* interface already initialized */
|
||||
bool pins_initialized; /* pins interface initialized */
|
||||
#ifdef MCU_ESP32
|
||||
uint8_t mod; /* peripheral hardware module of the SPI interface */
|
||||
uint8_t int_src; /* peripheral interrupt source used by the SPI device */
|
||||
uint8_t signal_sck; /* SCK signal from the controller */
|
||||
uint8_t signal_mosi; /* MOSI signal from the controller */
|
||||
uint8_t signal_miso; /* MISO signal to the controller */
|
||||
#endif /* MCU_ESP32 */
|
||||
};
|
||||
|
||||
static struct _spi_bus_t _spi[] = {
|
||||
#ifdef SPI0_CTRL
|
||||
{
|
||||
.initialized = false,
|
||||
.pins_initialized = false,
|
||||
.lock = MUTEX_INIT
|
||||
},
|
||||
#endif
|
||||
#ifdef SPI1_CTRL
|
||||
{
|
||||
.initialized = false,
|
||||
.pins_initialized = false,
|
||||
.lock = MUTEX_INIT
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* GPIOs that were once initialized as SPI interface pins can not be used
|
||||
@ -57,23 +102,48 @@ static bool _spi_pins_initialized[SPI_BUS_NUM] = { false };
|
||||
* the *spi_init_cs* function or the *spi_acquire* function when the interface
|
||||
* is used for the first time.
|
||||
*/
|
||||
void IRAM spi_init (spi_t bus)
|
||||
void IRAM_ATTR spi_init (spi_t bus)
|
||||
{
|
||||
assert(bus < SPI_NUMOF_MAX);
|
||||
assert(bus < SPI_NUMOF);
|
||||
|
||||
switch (spi_config[bus].ctrl) {
|
||||
#ifdef MCU_ESP32
|
||||
case HSPI: _spi[bus].regs = &SPI2;
|
||||
_spi[bus].mod = PERIPH_HSPI_MODULE;
|
||||
_spi[bus].int_src = ETS_SPI2_INTR_SOURCE;
|
||||
_spi[bus].signal_sck = HSPICLK_OUT_IDX;
|
||||
_spi[bus].signal_mosi = HSPID_OUT_IDX;
|
||||
_spi[bus].signal_miso = HSPIQ_IN_IDX;
|
||||
break;
|
||||
case VSPI: _spi[bus].regs = &SPI3;
|
||||
_spi[bus].mod = PERIPH_VSPI_MODULE;
|
||||
_spi[bus].int_src = ETS_SPI3_INTR_SOURCE;
|
||||
_spi[bus].signal_sck = VSPICLK_OUT_IDX;
|
||||
_spi[bus].signal_mosi = VSPID_OUT_IDX;
|
||||
_spi[bus].signal_miso = VSPIQ_IN_IDX;
|
||||
break;
|
||||
#else /* MCU_ESP32 */
|
||||
case HSPI: _spi[bus].regs = &SPI1;
|
||||
break;
|
||||
#endif /* MCU_ESP32 */
|
||||
default: LOG_TAG_ERROR("spi", "invalid SPI interface controller "
|
||||
"used for SPI_DEV(%d)\n", bus);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void _spi_init_internal(spi_t bus)
|
||||
/* Internal initialization function when the interface is used the first time */
|
||||
static void IRAM_ATTR _spi_init_internal(spi_t bus)
|
||||
{
|
||||
/* only one physical SPI(1) bus (HSPI) can be used for peripherals */
|
||||
/* RIOT's SPI_DEV(0) is mapped to SPI(1) bus (HSPI) */
|
||||
/* TODO SPI overlap mode SPI and HSPI */
|
||||
CHECK_PARAM (bus == SPI_DEV(0));
|
||||
assert(bus < SPI_NUMOF);
|
||||
|
||||
/* avoid multiple initializations */
|
||||
if (_spi_initialized[bus]) {
|
||||
if (_spi[bus].initialized) {
|
||||
return;
|
||||
}
|
||||
_spi_initialized[bus] = true;
|
||||
_spi[bus].initialized = true;
|
||||
|
||||
DEBUG("%s bus=%u\n", __func__, bus);
|
||||
|
||||
@ -82,139 +152,176 @@ void _spi_init_internal(spi_t bus)
|
||||
|
||||
/* check whether pins could be initialized, otherwise return, CS is not
|
||||
initialized in spi_init_pins */
|
||||
if (_gpio_pin_usage[SPI0_SCK_GPIO] != _SPI &&
|
||||
_gpio_pin_usage[SPI0_MOSI_GPIO] != _SPI &&
|
||||
_gpio_pin_usage[SPI0_MISO_GPIO] != _SPI) {
|
||||
if (gpio_get_pin_usage(spi_config[bus].sck) != _SPI &&
|
||||
gpio_get_pin_usage(spi_config[bus].miso) != _SPI &&
|
||||
gpio_get_pin_usage(spi_config[bus].mosi) != _SPI &&
|
||||
gpio_get_pin_usage(spi_config[bus].cs) != _SPI) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* set bus into a defined state */
|
||||
SPI(bus).USER0 = SPI_USER0_MOSI | SPI_USER0_CLOCK_IN_EDGE | SPI_USER0_DUPLEX;
|
||||
SPI(bus).USER0 |= SPI_USER0_CS_SETUP | SPI_USER0_CS_HOLD;
|
||||
#ifdef MCU_ESP32
|
||||
/* enable (power on) the according SPI module */
|
||||
periph_module_enable(_spi[bus].mod);
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
/* bring the bus into a defined state */
|
||||
_spi[bus].regs->user.val = SPI_USR_MOSI | SPI_CK_I_EDGE | SPI_DOUTDIN |
|
||||
SPI_CS_SETUP | SPI_CS_HOLD;
|
||||
|
||||
/* set byte order to little endian for read and write operations */
|
||||
SPI(bus).USER0 &= ~(SPI_USER0_WR_BYTE_ORDER | SPI_USER0_RD_BYTE_ORDER);
|
||||
_spi[bus].regs->user.wr_byte_order = 0;
|
||||
_spi[bus].regs->user.rd_byte_order = 0;
|
||||
|
||||
/* set bit order to most significant first for read and write operations */
|
||||
SPI(bus).CTRL0 = 0; /* ~(SPI_CTRL0_WR_BIT_ORDER | SPI_CTRL0_RD_BIT_ORDER); */
|
||||
_spi[bus].regs->ctrl.wr_bit_order = 0;
|
||||
_spi[bus].regs->ctrl.rd_bit_order = 0;
|
||||
|
||||
DEBUG("%s SPI(bus).USER0=%08x SPI(bus).CTRL0=%08x\n",
|
||||
__func__, SPI(bus).USER0, SPI(bus).CTRL0);
|
||||
/* reset all DIO or QIO flags */
|
||||
_spi[bus].regs->ctrl.fread_qio = 0;
|
||||
_spi[bus].regs->ctrl.fread_dio = 0;
|
||||
_spi[bus].regs->ctrl.fread_quad = 0;
|
||||
_spi[bus].regs->ctrl.fread_dual = 0;
|
||||
|
||||
/* disable fast read mode and write protection */
|
||||
_spi[bus].regs->ctrl.fastrd_mode = 0;
|
||||
#ifdef MCU_ESP32
|
||||
_spi[bus].regs->ctrl.wp = 0;
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
/* acquire and release to set default parameters */
|
||||
spi_acquire(bus, GPIO_UNDEF, SPI_MODE_0, SPI_CLK_1MHZ);
|
||||
spi_release(bus);
|
||||
}
|
||||
|
||||
void spi_init_pins(spi_t bus)
|
||||
{
|
||||
/* see spi_init */
|
||||
CHECK_PARAM (bus == SPI_DEV(0));
|
||||
assert(bus < SPI_NUMOF);
|
||||
|
||||
/* call initialization of the SPI interface if it is not initialized yet */
|
||||
if (!_spi_initialized[bus]) {
|
||||
if (!_spi[bus].initialized) {
|
||||
_spi_init_internal(bus);
|
||||
}
|
||||
|
||||
/* avoid multiple pin initializations */
|
||||
if (_spi_pins_initialized[bus]) {
|
||||
if (_spi[bus].pins_initialized) {
|
||||
return;
|
||||
}
|
||||
_spi_pins_initialized[bus] = true;
|
||||
_spi[bus].pins_initialized = true;
|
||||
|
||||
DEBUG("%s bus=%u\n", __func__, bus);
|
||||
|
||||
uint32_t iomux_func = (bus == 0) ? IOMUX_FUNC(1) : IOMUX_FUNC(2);
|
||||
if (gpio_init (spi_config[bus].sck, GPIO_OUT) ||
|
||||
gpio_init (spi_config[bus].mosi, GPIO_OUT) ||
|
||||
gpio_init (spi_config[bus].miso, GPIO_IN)) {
|
||||
LOG_TAG_ERROR("spi",
|
||||
"SPI_DEV(%d) pins could not be initialized\n", bus);
|
||||
return;
|
||||
}
|
||||
if (spi_init_cs(bus, spi_config[bus].cs) != SPI_OK) {
|
||||
LOG_TAG_ERROR("spi",
|
||||
"SPI_DEV(%d) CS signal could not be initialized\n",
|
||||
bus);
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the usage type in GPIO table */
|
||||
gpio_set_pin_usage(spi_config[bus].sck, _SPI);
|
||||
gpio_set_pin_usage(spi_config[bus].mosi, _SPI);
|
||||
gpio_set_pin_usage(spi_config[bus].miso, _SPI);
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
/* connect SCK and MOSI pins to the output signal through the GPIO matrix */
|
||||
GPIO.func_out_sel_cfg[spi_config[bus].sck].func_sel = _spi[bus].signal_sck;
|
||||
GPIO.func_out_sel_cfg[spi_config[bus].mosi].func_sel = _spi[bus].signal_mosi;
|
||||
/* connect MISO input signal to the MISO pin through the GPIO matrix */
|
||||
GPIO.func_in_sel_cfg[_spi[bus].signal_miso].sig_in_sel = 1;
|
||||
GPIO.func_in_sel_cfg[_spi[bus].signal_miso].sig_in_inv = 0;
|
||||
GPIO.func_in_sel_cfg[_spi[bus].signal_miso].func_sel = spi_config[bus].miso;
|
||||
#else /* MCU_ESP32 */
|
||||
/*
|
||||
* CS is handled as normal GPIO ouptut. Due to the small number of GPIOs
|
||||
* CS is handled as normal GPIO output. Due to the small number of GPIOs
|
||||
* we have, we do not initialize the default CS pin here. Either the app
|
||||
* uses spi_init_cs to initialize the CS pin explicitly, or we initialize
|
||||
* the default CS when spi_aquire is used first time.
|
||||
*/
|
||||
IOMUX.PIN[_gpio_to_iomux[SPI0_MISO_GPIO]] &= ~IOMUX_PIN_FUNC_MASK;
|
||||
IOMUX.PIN[_gpio_to_iomux[SPI0_MOSI_GPIO]] &= ~IOMUX_PIN_FUNC_MASK;
|
||||
IOMUX.PIN[_gpio_to_iomux[SPI0_SCK_GPIO]] &= ~IOMUX_PIN_FUNC_MASK;
|
||||
uint32_t iomux_func = IOMUX_FUNC(2);
|
||||
|
||||
IOMUX.PIN[_gpio_to_iomux[SPI0_MISO_GPIO]] |= iomux_func;
|
||||
IOMUX.PIN[_gpio_to_iomux[SPI0_MOSI_GPIO]] |= iomux_func;
|
||||
IOMUX.PIN[_gpio_to_iomux[SPI0_SCK_GPIO]] |= iomux_func;
|
||||
IOMUX.PIN[_gpio_to_iomux[spi_config[bus].miso]] &= ~IOMUX_PIN_FUNC_MASK;
|
||||
IOMUX.PIN[_gpio_to_iomux[spi_config[bus].mosi]] &= ~IOMUX_PIN_FUNC_MASK;
|
||||
IOMUX.PIN[_gpio_to_iomux[spi_config[bus].sck]] &= ~IOMUX_PIN_FUNC_MASK;
|
||||
|
||||
_gpio_pin_usage [SPI0_MISO_GPIO] = _SPI; /* pin cannot be used for anything else */
|
||||
_gpio_pin_usage [SPI0_MOSI_GPIO] = _SPI; /* pin cannot be used for anything else */
|
||||
_gpio_pin_usage [SPI0_SCK_GPIO] = _SPI; /* pin cannot be used for anything else */
|
||||
IOMUX.PIN[_gpio_to_iomux[spi_config[bus].miso]] |= iomux_func;
|
||||
IOMUX.PIN[_gpio_to_iomux[spi_config[bus].mosi]] |= iomux_func;
|
||||
IOMUX.PIN[_gpio_to_iomux[spi_config[bus].sck]] |= iomux_func;
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
int spi_init_cs(spi_t bus, spi_cs_t cs)
|
||||
{
|
||||
DEBUG("%s bus=%u cs=%u\n", __func__, bus, cs);
|
||||
|
||||
/* see spi_init */
|
||||
CHECK_PARAM_RET (bus == SPI_DEV(0), SPI_NODEV);
|
||||
assert(bus < SPI_NUMOF);
|
||||
|
||||
/* call initialization of the SPI interface if it is not initialized yet */
|
||||
if (!_spi_initialized[bus]) {
|
||||
if (!_spi[bus].initialized) {
|
||||
_spi_init_internal(bus);
|
||||
}
|
||||
|
||||
/* return if pin is already initialized as SPI CS signal */
|
||||
if (_gpio_pin_usage [cs] == _SPI) {
|
||||
if (gpio_get_pin_usage(cs) == _SPI) {
|
||||
return SPI_OK;
|
||||
}
|
||||
|
||||
if (_gpio_pin_usage [cs] != _GPIO) {
|
||||
/* check whether CS pin is used otherwise */
|
||||
if (gpio_get_pin_usage(cs) != _GPIO) {
|
||||
return SPI_NOCS;
|
||||
}
|
||||
|
||||
/* initialize the pin */
|
||||
gpio_init(cs, GPIO_OUT);
|
||||
gpio_set (cs);
|
||||
gpio_set(cs);
|
||||
|
||||
_gpio_pin_usage [cs] = _SPI; /* pin cannot be used for anything else */
|
||||
/* pin cannot be used for anything else */
|
||||
gpio_set_pin_usage(cs, _SPI);
|
||||
|
||||
return SPI_OK;
|
||||
}
|
||||
|
||||
int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
|
||||
int IRAM_ATTR spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
|
||||
{
|
||||
DEBUG("%s bus=%u cs=%u mode=%u clk=%u\n", __func__, bus, cs, mode, clk);
|
||||
|
||||
/* see spi_init */
|
||||
CHECK_PARAM_RET (bus == SPI_DEV(0), SPI_NODEV);
|
||||
assert(bus < SPI_NUMOF);
|
||||
|
||||
/* call initialization of the SPI interface if it is not initialized yet */
|
||||
if (!_spi_initialized[bus]) {
|
||||
if (!_spi[bus].initialized) {
|
||||
_spi_init_internal(bus);
|
||||
}
|
||||
|
||||
/* if parameter cs is GPIO_UNDEF, the default CS pin is used */
|
||||
cs = (cs == GPIO_UNDEF) ? SPI0_CS0_GPIO : cs;
|
||||
cs = (cs == GPIO_UNDEF) ? spi_config[bus].cs : cs;
|
||||
|
||||
/* if the CS pin used is not yet initialized, we do it now */
|
||||
if (_gpio_pin_usage[cs] != _SPI && spi_init_cs(bus, cs) != SPI_OK) {
|
||||
LOG_ERROR("SPI_DEV(%d) CS signal could not be initialized\n", bus);
|
||||
if (gpio_get_pin_usage(cs) != _SPI && spi_init_cs(bus, cs) != SPI_OK) {
|
||||
LOG_TAG_ERROR("spi",
|
||||
"SPI_DEV(%d) CS signal could not be initialized\n",
|
||||
bus);
|
||||
return SPI_NOCS;
|
||||
}
|
||||
|
||||
/* lock the bus */
|
||||
mutex_lock(&_spi_lock[bus]);
|
||||
mutex_lock(&_spi[bus].lock);
|
||||
|
||||
/* set SPI mode */
|
||||
bool cpha = (mode == SPI_MODE_1 || mode == SPI_MODE_3);
|
||||
bool cpol = (mode == SPI_MODE_2 || mode == SPI_MODE_3);
|
||||
|
||||
if (cpol) {
|
||||
cpha = !cpha; /* CPHA must be inverted when CPOL = 1 */
|
||||
}
|
||||
|
||||
if (cpha) {
|
||||
SPI(bus).USER0 |= SPI_USER0_CLOCK_OUT_EDGE;
|
||||
}
|
||||
else {
|
||||
SPI(bus).USER0 &= ~SPI_USER0_CLOCK_OUT_EDGE;
|
||||
}
|
||||
|
||||
if (cpol) {
|
||||
SPI(bus).PIN |= SPI_PIN_IDLE_EDGE;
|
||||
}
|
||||
else {
|
||||
SPI(bus).PIN &= ~SPI_PIN_IDLE_EDGE;
|
||||
}
|
||||
/*
|
||||
* set SPI mode
|
||||
* see ESP32 Technical Reference, Table 25 and Section 7.4.2
|
||||
*/
|
||||
_spi[bus].regs->pin.ck_idle_edge = (mode == SPI_MODE_2 || mode == SPI_MODE_3);
|
||||
_spi[bus].regs->user.ck_out_edge = (mode == SPI_MODE_1 || mode == SPI_MODE_2);
|
||||
_spi[bus].regs->ctrl2.miso_delay_mode = (mode == SPI_MODE_0 || mode == SPI_MODE_3) ? 2 : 1;
|
||||
_spi[bus].regs->ctrl2.miso_delay_num = 0;
|
||||
_spi[bus].regs->ctrl2.mosi_delay_mode = 0;
|
||||
_spi[bus].regs->ctrl2.mosi_delay_num = 0;
|
||||
|
||||
/* set SPI clock
|
||||
* see ESP8266 Technical Reference Appendix 2 - SPI registers
|
||||
@ -248,31 +355,53 @@ int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
|
||||
spi_clkdiv_pre--;
|
||||
spi_clkcnt_N--;
|
||||
|
||||
DEBUG("%s spi_clkdiv_prev=%u spi_clkcnt_N=%u\n", __func__, spi_clkdiv_pre, spi_clkcnt_N);
|
||||
DEBUG("%s spi_clkdiv_prev=%u spi_clkcnt_N=%u\n",
|
||||
__func__, spi_clkdiv_pre, spi_clkcnt_N);
|
||||
|
||||
/* SPI clock is derived from system bus frequency and should not be affected by */
|
||||
/* CPU clock */
|
||||
#ifdef MCU_ESP8266
|
||||
IOMUX.CONF &= ~IOMUX_CONF_SPI1_CLOCK_EQU_SYS_CLOCK;
|
||||
#endif
|
||||
|
||||
IOMUX.CONF &= ~(bus == 0 ? IOMUX_CONF_SPI0_CLOCK_EQU_SYS_CLOCK
|
||||
: IOMUX_CONF_SPI1_CLOCK_EQU_SYS_CLOCK);
|
||||
SPI(bus).CLOCK = VAL2FIELD_M (SPI_CLOCK_DIV_PRE, spi_clkdiv_pre) |
|
||||
VAL2FIELD_M (SPI_CLOCK_COUNT_NUM, spi_clkcnt_N) |
|
||||
VAL2FIELD_M (SPI_CLOCK_COUNT_HIGH, (spi_clkcnt_N+1)/2-1) |
|
||||
VAL2FIELD_M (SPI_CLOCK_COUNT_LOW, spi_clkcnt_N);
|
||||
/* SPI clock is derived from APB clock by dividers */
|
||||
_spi[bus].regs->clock.clk_equ_sysclk = 0;
|
||||
|
||||
DEBUG("%s IOMUX.CONF=%08x SPI(bus).CLOCK=%08x\n",
|
||||
__func__, IOMUX.CONF, SPI(bus).CLOCK);
|
||||
/* set SPI clock dividers */
|
||||
_spi[bus].regs->clock.clkdiv_pre = spi_clkdiv_pre;
|
||||
_spi[bus].regs->clock.clkcnt_n = spi_clkcnt_N;
|
||||
_spi[bus].regs->clock.clkcnt_h = (spi_clkcnt_N+1)/2-1;
|
||||
_spi[bus].regs->clock.clkcnt_l = spi_clkcnt_N;
|
||||
|
||||
DEBUG("%s bus %d: SPI_CLOCK_REG=%08x\n",
|
||||
__func__, bus, _spi[bus].regs->clock.val);
|
||||
|
||||
return SPI_OK;
|
||||
}
|
||||
|
||||
void spi_release(spi_t bus)
|
||||
void IRAM_ATTR spi_release(spi_t bus)
|
||||
{
|
||||
/* see spi_init */
|
||||
CHECK_PARAM (bus == SPI_DEV(0));
|
||||
DEBUG("%s bus=%u\n", __func__, bus);
|
||||
|
||||
assert(bus < SPI_NUMOF);
|
||||
|
||||
/* release the bus */
|
||||
mutex_unlock(&_spi_lock[bus]);
|
||||
mutex_unlock(&_spi[bus].lock);
|
||||
}
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
static const char* _spi_names[] = { "CSPI", "FSPI", "HSPI", "VSPI" };
|
||||
#else /* MCU_ESP32 */
|
||||
static const char* _spi_names[] = { "FSPI", "HSPI" };
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
void spi_print_config(void)
|
||||
{
|
||||
for (unsigned bus = 0; bus < SPI_NUMOF; bus++) {
|
||||
printf("\tSPI_DEV(%u)\t%s ", bus, _spi_names[spi_config[bus].ctrl]);
|
||||
printf("sck=%d " , spi_config[bus].sck);
|
||||
printf("miso=%d ", spi_config[bus].miso);
|
||||
printf("mosi=%d ", spi_config[bus].mosi);
|
||||
printf("cs=%d\n" , spi_config[bus].cs);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -284,29 +413,37 @@ void spi_release(spi_t bus)
|
||||
* https://github.com/SuperHouse/esp-open-rtos/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
inline static void _set_size(uint8_t bus, uint8_t bytes)
|
||||
inline static void IRAM_ATTR _set_size(uint8_t bus, uint8_t bytes)
|
||||
{
|
||||
uint32_t bits = ((uint32_t)bytes << 3) - 1;
|
||||
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_MISO_BITLEN, bits);
|
||||
SPI(bus).USER1 = SET_FIELD(SPI(bus).USER1, SPI_USER1_MOSI_BITLEN, bits);
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
_spi[bus].regs->mosi_dlen.val = bits;
|
||||
_spi[bus].regs->miso_dlen.val = bits;
|
||||
#else /* MCU_ESP32 */
|
||||
_spi[bus].regs->user1.usr_mosi_bitlen = bits;
|
||||
_spi[bus].regs->user1.usr_miso_bitlen = bits;
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
inline static void _wait(uint8_t bus)
|
||||
inline static void IRAM_ATTR _wait(uint8_t bus)
|
||||
{
|
||||
while (SPI(bus).CMD & SPI_CMD_USR) {}
|
||||
/* SPI_CMD_REG.SPI_USR is cleared when operation has been finished */
|
||||
while (_spi[bus].regs->cmd.usr) {}
|
||||
}
|
||||
|
||||
inline static void _start(uint8_t bus)
|
||||
inline static void IRAM_ATTR _start(uint8_t bus)
|
||||
{
|
||||
SPI(bus).CMD |= SPI_CMD_USR;
|
||||
/* set SPI_CMD_REG.SPI_USR to start an operation */
|
||||
_spi[bus].regs->cmd.usr = 1;
|
||||
}
|
||||
|
||||
inline static void _store_data(uint8_t bus, const void *data, size_t len)
|
||||
inline static void IRAM_ATTR _store_data(uint8_t bus, const void *data, size_t len)
|
||||
{
|
||||
uint8_t words = len / 4;
|
||||
uint8_t tail = len % 4;
|
||||
|
||||
memcpy((void *)SPI(bus).W, data, len - tail);
|
||||
memcpy((void *)_spi[bus].regs->data_buf, data, len - tail);
|
||||
|
||||
if (!tail) {
|
||||
return;
|
||||
@ -317,12 +454,12 @@ inline static void _store_data(uint8_t bus, const void *data, size_t len)
|
||||
for (uint8_t i = 0; i < tail; i++) {
|
||||
last = last | (offs[i] << (i * 8));
|
||||
}
|
||||
SPI(bus).W[words] = last;
|
||||
_spi[bus].regs->data_buf[words] = last;
|
||||
}
|
||||
|
||||
static const uint8_t spi_empty_out[SPI_BLOCK_SIZE] = { 0 };
|
||||
|
||||
static void _spi_buf_transfer(uint8_t bus, const void *out, void *in, size_t len)
|
||||
static void IRAM_ATTR _spi_buf_transfer(uint8_t bus, const void *out, void *in, size_t len)
|
||||
{
|
||||
DEBUG("%s bus=%u out=%p in=%p len=%u\n", __func__, bus, out, in, len);
|
||||
|
||||
@ -333,15 +470,14 @@ static void _spi_buf_transfer(uint8_t bus, const void *out, void *in, size_t len
|
||||
_start(bus);
|
||||
_wait(bus);
|
||||
if (in) {
|
||||
memcpy(in, (void *)SPI(bus).W, len);
|
||||
memcpy(in, (void *)_spi[bus].regs->data_buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
|
||||
const void *out, void *in, size_t len)
|
||||
void IRAM_ATTR spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
|
||||
const void *out, void *in, size_t len)
|
||||
{
|
||||
/* see spi_init */
|
||||
CHECK_PARAM (bus == SPI_DEV(0));
|
||||
assert(bus < SPI_NUMOF);
|
||||
|
||||
DEBUG("%s bus=%u cs=%u cont=%d out=%p in=%p len=%u\n",
|
||||
__func__, bus, cs, cont, out, in, len);
|
||||
@ -360,9 +496,7 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cs != SPI_CS_UNDEF) {
|
||||
gpio_clear (cs);
|
||||
}
|
||||
gpio_clear(cs != SPI_CS_UNDEF ? cs : spi_config[bus].cs);
|
||||
|
||||
size_t blocks = len / SPI_BLOCK_SIZE;
|
||||
uint8_t tail = len % SPI_BLOCK_SIZE;
|
||||
@ -382,8 +516,8 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
|
||||
in ? (uint8_t *)in + blocks * SPI_BLOCK_SIZE : NULL, tail);
|
||||
}
|
||||
|
||||
if (!cont && (cs != SPI_CS_UNDEF)) {
|
||||
gpio_set (cs);
|
||||
if (!cont) {
|
||||
gpio_set(cs != SPI_CS_UNDEF ? cs : spi_config[bus].cs);
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
@ -396,21 +530,3 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void spi_print_config(void)
|
||||
{
|
||||
LOG_INFO("\tSPI_DEV(0): ");
|
||||
LOG_INFO("sck=%d " , SPI0_SCK_GPIO);
|
||||
LOG_INFO("miso=%d ", SPI0_MISO_GPIO);
|
||||
LOG_INFO("mosi=%d ", SPI0_MOSI_GPIO);
|
||||
LOG_INFO("cs=%d\n" , SPI0_CS0_GPIO);
|
||||
}
|
||||
|
||||
#else /* MODULE_PERIPH_SPI */
|
||||
|
||||
void spi_print_config(void)
|
||||
{
|
||||
LOG_INFO("\tSPI: no devices\n");
|
||||
}
|
||||
|
||||
#endif /* MODULE_PERIPH_SPI */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -27,9 +27,10 @@
|
||||
#include "xtimer.h"
|
||||
#include "periph/timer.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "irq_arch.h"
|
||||
#include "esp/common_macros.h"
|
||||
#include "esp_common.h"
|
||||
#include "irq_arch.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "sdk/sdk.h"
|
||||
#include "xtensa/hal.h"
|
||||
|
||||
@ -295,18 +296,14 @@ static void IRAM __timer_channel_stop (struct hw_timer_t* timer, struct hw_chann
|
||||
|
||||
void timer_print_config(void)
|
||||
{
|
||||
for (int i = 0; i < HW_TIMER_NUMOF; i++) {
|
||||
LOG_INFO("\tTIMER_DEV(%d): %d channel(s)\n", i,
|
||||
ARRAY_SIZE(timers[i].channels));
|
||||
for (unsigned i = 0; i < HW_TIMER_NUMOF; i++) {
|
||||
printf("\tTIMER_DEV(%u)\t%d channel(s)\n", i,
|
||||
ARRAY_SIZE(timers[i].channels));
|
||||
}
|
||||
}
|
||||
|
||||
#else /* MODULE_ESP_SW_TIMER */
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
#error Software timers are not available in Non-SDK version, use USE_SDK=1 to enable SDK-version.
|
||||
#else
|
||||
|
||||
/* software timer based on os_timer_arm functions */
|
||||
|
||||
#define OS_TIMER_NUMOF 1
|
||||
@ -319,6 +316,8 @@ void timer_print_config(void)
|
||||
#define OS_TIMER_DELTA_RSHIFT 16
|
||||
#define OS_TIMER_CORRECTION 4
|
||||
|
||||
extern void os_timer_arm_us(os_timer_t *ptimer, uint32_t time, bool repeat_flag);
|
||||
|
||||
/* Since hardware timer FRC1 is needed to implement PWM, we have to map our */
|
||||
/* timer using the exsting ETS timer with 1 us clock rate */
|
||||
|
||||
@ -560,12 +559,10 @@ static void IRAM __timer_channel_stop (struct phy_timer_t* timer, struct phy_cha
|
||||
|
||||
void timer_print_config(void)
|
||||
{
|
||||
for (int i = 0; i < OS_TIMER_NUMOF; i++) {
|
||||
LOG_INFO("\tTIMER_DEV(%d): %d channel(s)\n", i,
|
||||
ARRAY_SIZE(timers[i].channels));
|
||||
for (unsigned i = 0; i < OS_TIMER_NUMOF; i++) {
|
||||
printf("\tTIMER_DEV(%u)\t%d channel(s)\n", i,
|
||||
ARRAY_SIZE(timers[i].channels));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NON_SDK */
|
||||
|
||||
#endif /* MODULE_ESP_SW_TIMER */
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -19,147 +19,461 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "esp_common.h"
|
||||
#include "cpu.h"
|
||||
#include "irq_arch.h"
|
||||
#include "log.h"
|
||||
#include "sched.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "periph/gpio.h"
|
||||
#include "periph/uart.h"
|
||||
|
||||
#include "eagle_soc.h"
|
||||
#include "stdio_uart.h"
|
||||
|
||||
#include "esp/common_macros.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "xtensa/xtensa_api.h"
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
|
||||
#include "gpio_arch.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/uart_struct.h"
|
||||
|
||||
#undef UART_CLK_FREQ
|
||||
#define UART_CLK_FREQ rtc_clk_apb_freq_get() /* APB_CLK is used */
|
||||
|
||||
#else /* MCU_ESP32 */
|
||||
|
||||
#include "esp8266/uart_struct.h"
|
||||
|
||||
#ifdef MODULE_ESP_QEMU
|
||||
#include "esp/uart_regs.h"
|
||||
#include "sdk/sdk.h"
|
||||
#endif /* MODULE_ESP_QEMU */
|
||||
|
||||
/**
|
||||
* @brief Allocate memory to store the callback functions.
|
||||
*/
|
||||
static uart_isr_ctx_t isr_ctx[UART_NUMOF];
|
||||
#define UART0 uart0
|
||||
#define UART1 uart1
|
||||
#define CPU_INUM_UART ETS_UART_INUM
|
||||
|
||||
static uint8_t IRAM __uart_rx_one_char (uart_t uart);
|
||||
static void __uart_tx_one_char(uart_t uart, uint8_t data);
|
||||
static void __uart_intr_enable (uart_t uart);
|
||||
static void IRAM __uart_intr_handler (void *para);
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
struct uart_hw_t {
|
||||
uart_dev_t* regs; /* pointer to register data struct of the UART device */
|
||||
uint8_t pin_txd; /* TxD pin used */
|
||||
uint8_t pin_rxd; /* RxD pin used */
|
||||
bool used; /* indicates whether UART is used */
|
||||
uint32_t baudrate; /* used baudrate */
|
||||
uart_data_bits_t data; /* used data bits */
|
||||
uart_stop_bits_t stop; /* used stop bits */
|
||||
uart_parity_t parity; /* used parity bits */
|
||||
uart_isr_ctx_t isr_ctx; /* callback functions */
|
||||
#ifdef MCU_ESP32
|
||||
uint8_t mod; /* peripheral hardware module of the UART interface */
|
||||
uint8_t signal_txd; /* TxD signal from the controller */
|
||||
uint8_t signal_rxd; /* RxD signal to the controller */
|
||||
uint8_t int_src; /* peripheral interrupt source used by the UART device */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* hardware resources */
|
||||
static struct uart_hw_t _uarts[] = {
|
||||
{
|
||||
.regs = &UART0,
|
||||
.used = false,
|
||||
.baudrate = STDIO_UART_BAUDRATE,
|
||||
.data = UART_DATA_BITS_8,
|
||||
.stop = UART_STOP_BITS_1,
|
||||
.parity = UART_PARITY_NONE,
|
||||
#ifdef MCU_ESP32
|
||||
.mod = PERIPH_UART0_MODULE,
|
||||
.signal_txd = U0TXD_OUT_IDX,
|
||||
.signal_rxd = U0RXD_IN_IDX,
|
||||
.int_src = ETS_UART0_INTR_SOURCE
|
||||
},
|
||||
{
|
||||
.regs = &UART1,
|
||||
.used = false,
|
||||
.baudrate = STDIO_UART_BAUDRATE,
|
||||
.data = UART_DATA_BITS_8,
|
||||
.stop = UART_STOP_BITS_1,
|
||||
.parity = UART_PARITY_NONE,
|
||||
.mod = PERIPH_UART1_MODULE,
|
||||
.signal_txd = U1TXD_OUT_IDX,
|
||||
.signal_rxd = U1RXD_IN_IDX,
|
||||
.int_src = ETS_UART1_INTR_SOURCE
|
||||
},
|
||||
{
|
||||
.regs = &UART2,
|
||||
.used = false,
|
||||
.baudrate = STDIO_UART_BAUDRATE,
|
||||
.data = UART_DATA_BITS_8,
|
||||
.stop = UART_STOP_BITS_1,
|
||||
.parity = UART_PARITY_NONE,
|
||||
.mod = PERIPH_UART2_MODULE,
|
||||
.signal_txd = U2TXD_OUT_IDX,
|
||||
.signal_rxd = U2RXD_IN_IDX,
|
||||
.int_src = ETS_UART2_INTR_SOURCE
|
||||
#endif /* MCU_ESP32 */
|
||||
},
|
||||
};
|
||||
|
||||
/* declaration of external functions */
|
||||
extern void uart_div_modify(uint8_t uart_no, uint32_t div);
|
||||
|
||||
/* forward declaration of internal functions */
|
||||
static int _uart_set_baudrate(uart_t uart, uint32_t baudrate);
|
||||
static int _uart_set_mode(uart_t uart, uart_data_bits_t data_bits,
|
||||
uart_parity_t parity, uart_stop_bits_t stop_bits);
|
||||
static uint8_t IRAM _uart_rx_one_char(uart_t uart);
|
||||
static void _uart_tx_one_char(uart_t uart, uint8_t data);
|
||||
static void _uart_intr_enable(uart_t uart);
|
||||
static void _uart_config (uart_t uart);
|
||||
static void IRAM _uart_intr_handler(void *para);
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
{
|
||||
CHECK_PARAM_RET (uart < UART_NUMOF, -1);
|
||||
|
||||
DEBUG("%s uart=%d, rate=%d, rx_cb=%p, arg=%p\n", __func__, uart, baudrate, rx_cb, arg);
|
||||
|
||||
/* setup the baudrate */
|
||||
uart_div_modify(uart, UART_CLK_FREQ / baudrate);
|
||||
assert(uart < UART_NUMOF_MAX);
|
||||
assert(uart < UART_NUMOF);
|
||||
|
||||
_uarts[uart].pin_txd = uart_config[uart].txd;
|
||||
_uarts[uart].pin_rxd = uart_config[uart].rxd;
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
/* UART1 and UART2 have configurable pins */
|
||||
if ((uart == UART_DEV(1) || uart == UART_DEV(2))) {
|
||||
|
||||
/* reset the pins when they were already used as UART pins */
|
||||
if (gpio_get_pin_usage(_uarts[uart].pin_txd) == _UART) {
|
||||
gpio_set_pin_usage(_uarts[uart].pin_txd, _GPIO);
|
||||
}
|
||||
if (gpio_get_pin_usage(_uarts[uart].pin_rxd) == _UART) {
|
||||
gpio_set_pin_usage(_uarts[uart].pin_rxd, _GPIO);
|
||||
}
|
||||
|
||||
/* try to initialize the pins as GPIOs first */
|
||||
if (gpio_init(_uarts[uart].pin_txd, GPIO_OUT) ||
|
||||
gpio_init(_uarts[uart].pin_rxd, GPIO_IN)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* store the usage type in GPIO table */
|
||||
gpio_set_pin_usage(_uarts[uart].pin_txd, _UART);
|
||||
gpio_set_pin_usage(_uarts[uart].pin_rxd, _UART);
|
||||
|
||||
/* connect TxD pin to the TxD output signal through the GPIO matrix */
|
||||
GPIO.func_out_sel_cfg[_uarts[uart].pin_txd].func_sel = _uarts[uart].signal_txd;
|
||||
|
||||
/* connect RxD input signal to the RxD pin through the GPIO matrix */
|
||||
GPIO.func_in_sel_cfg[_uarts[uart].signal_rxd].sig_in_sel = 1;
|
||||
GPIO.func_in_sel_cfg[_uarts[uart].signal_rxd].sig_in_inv = 0;
|
||||
GPIO.func_in_sel_cfg[_uarts[uart].signal_rxd].func_sel = _uarts[uart].pin_rxd;
|
||||
}
|
||||
#endif
|
||||
_uarts[uart].baudrate = baudrate;
|
||||
|
||||
/* register interrupt context */
|
||||
isr_ctx[uart].rx_cb = rx_cb;
|
||||
isr_ctx[uart].arg = arg;
|
||||
_uarts[uart].isr_ctx.rx_cb = rx_cb;
|
||||
_uarts[uart].isr_ctx.arg = arg;
|
||||
|
||||
if (rx_cb) {
|
||||
ets_isr_attach (ETS_UART_INUM, __uart_intr_handler, 0);
|
||||
|
||||
/* since reading is done byte for byte we set the RX FIFO FULL */
|
||||
/* interrupt level to 1 byte */
|
||||
UART(uart).CONF1 = SET_FIELD(UART(uart).CONF1, UART_CONF1_RXFIFO_FULL_THRESHOLD, 1);
|
||||
|
||||
/* enable the RX FIFO FULL interrupt */
|
||||
__uart_intr_enable (uart);
|
||||
}
|
||||
/* enable and configure the according UART module */
|
||||
uart_poweron(uart);
|
||||
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
#if MODULE_PERIPH_UART_MODECFG
|
||||
int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity,
|
||||
uart_stop_bits_t stop_bits)
|
||||
{
|
||||
return _uart_set_mode(uart, data_bits, parity, stop_bits);
|
||||
}
|
||||
#endif
|
||||
|
||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
{
|
||||
CHECK_PARAM (uart < UART_NUMOF);
|
||||
CHECK_PARAM(uart < UART_NUMOF);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
__uart_tx_one_char(uart, data[i]);
|
||||
_uart_tx_one_char(uart, data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweron (uart_t uart)
|
||||
{
|
||||
/* UART can't be powered on/off, just return */
|
||||
CHECK_PARAM(uart < UART_NUMOF);
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
periph_module_enable(_uarts[uart].mod);
|
||||
#endif
|
||||
_uart_config(uart);
|
||||
}
|
||||
|
||||
void uart_poweroff (uart_t uart)
|
||||
{
|
||||
/* UART can't be powered on/off, just return */
|
||||
CHECK_PARAM(uart < UART_NUMOF);
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
periph_module_disable(_uarts[uart].mod);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IRAM __uart_intr_handler (void *arg)
|
||||
/* systemwide UART initializations */
|
||||
void uart_system_init (void)
|
||||
{
|
||||
for (unsigned uart = 0; uart < UART_NUMOF; uart++) {
|
||||
/* reset all UART interrupt status registers */
|
||||
_uarts[uart].regs->int_clr.val = ~0;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_print_config(void)
|
||||
{
|
||||
for (unsigned uart = 0; uart < UART_NUMOF; uart++) {
|
||||
printf("\tUART_DEV(%u)\ttxd=%d rxd=%d\n", uart,
|
||||
uart_config[uart].txd, uart_config[uart].rxd);
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM _uart_intr_handler(void *arg)
|
||||
{
|
||||
/* to satisfy the compiler */
|
||||
(void)arg;
|
||||
|
||||
irq_isr_enter ();
|
||||
irq_isr_enter();
|
||||
|
||||
DEBUG("%s \n", __func__);
|
||||
/* UART0, UART1, UART2 peripheral interrupt sources are routed to the same
|
||||
interrupt, so we have to use the status to distinguish interruptees */
|
||||
for (unsigned uart = 0; uart < UART_NUMOF; uart++) {
|
||||
if (_uarts[uart].used) {
|
||||
DEBUG("%s uart=%d int_st=%08x\n", __func__,
|
||||
uart, _uarts[uart].regs->int_st.val);
|
||||
|
||||
/*
|
||||
* UART0 and UART1 interrupts are combined togther. So we have to
|
||||
* iterate over all UART devices and test the INT_STATUS register for
|
||||
* interrupts
|
||||
*/
|
||||
for (int i = 0; i < UART_NUMOF; i++) {
|
||||
uart_t uart = UART_DEV(0); /* UartDev.buff_uart_no; */
|
||||
if (UART(uart).INT_STATUS & UART_INT_STATUS_RXFIFO_FULL) {
|
||||
/* clear interrupt flag */
|
||||
uint8_t data = __uart_rx_one_char (uart);
|
||||
if (_uarts[uart].used && _uarts[uart].regs->int_st.rxfifo_full) {
|
||||
/* read one byte of data */
|
||||
uint8_t data = _uart_rx_one_char (uart);
|
||||
/* if registered, call the RX callback function */
|
||||
if (_uarts[uart].isr_ctx.rx_cb) {
|
||||
_uarts[uart].isr_ctx.rx_cb(_uarts[uart].isr_ctx.arg, data);
|
||||
}
|
||||
/* clear interrupt flag */
|
||||
_uarts[uart].regs->int_clr.rxfifo_full = 1;
|
||||
}
|
||||
|
||||
/* call registered RX callback function */
|
||||
isr_ctx[uart].rx_cb(isr_ctx[uart].arg, data);
|
||||
|
||||
/* clear interrupt flag */
|
||||
UART(uart).INT_CLEAR |= UART_INT_CLEAR_RXFIFO_FULL;
|
||||
}
|
||||
else {
|
||||
/* TODO handle other type of interrupts, for the moment just clear them */
|
||||
UART(uart).INT_CLEAR = 0x1f;
|
||||
/* TODO handle other types of interrupts, for the moment just clear them */
|
||||
_uarts[uart].regs->int_clr.val = ~0x0;
|
||||
}
|
||||
}
|
||||
irq_isr_exit ();
|
||||
|
||||
irq_isr_exit();
|
||||
}
|
||||
|
||||
/* RX/TX FIFO capacity is 128 byte */
|
||||
#define UART_FIFO_MAX 1
|
||||
#define UART_FIFO_MAX 128
|
||||
|
||||
/* receive one data byte with wait */
|
||||
static uint8_t IRAM __uart_rx_one_char (uart_t uart)
|
||||
static uint8_t IRAM _uart_rx_one_char (uart_t uart)
|
||||
{
|
||||
/* uint8_t fifo_len = FIELD2VAL(UART_STATUS_RXFIFO_COUNT, UART(uart).STATUS); */
|
||||
|
||||
#if defined(MODULE_ESP_QEMU) && defined(MCU_ESP8266)
|
||||
/* wait until at least von byte is in RX FIFO */
|
||||
while (!FIELD2VAL(UART_STATUS_RXFIFO_COUNT, UART(uart).STATUS)) {}
|
||||
|
||||
/* read the lowest byte from RX FIFO register */
|
||||
return UART(uart).FIFO & 0xff; /* only bit 0 ... 7 */
|
||||
#else
|
||||
/* wait until at least von byte is in RX FIFO */
|
||||
while (!_uarts[uart].regs->status.rxfifo_cnt) {}
|
||||
|
||||
/* read the lowest byte from RX FIFO register */
|
||||
return _uarts[uart].regs->fifo.rw_byte;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* send one data byte with wait */
|
||||
static void __uart_tx_one_char(uart_t uart, uint8_t data)
|
||||
static void _uart_tx_one_char(uart_t uart, uint8_t data)
|
||||
{
|
||||
/* wait until at least one byte is avaiable in the TX FIFO */
|
||||
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(uart).STATUS) >= UART_FIFO_MAX) {}
|
||||
/* wait until at least one byte is available in the TX FIFO */
|
||||
while (_uarts[uart].regs->status.txfifo_cnt >= UART_FIFO_MAX) {}
|
||||
|
||||
/* send the byte by placing it in the TX FIFO */
|
||||
/* send the byte by placing it in the TX FIFO using MPU */
|
||||
#ifdef MCU_ESP32
|
||||
WRITE_PERI_REG(UART_FIFO_AHB_REG(uart), data);
|
||||
#else /* MCU_ESP32 */
|
||||
#ifdef MODULE_ESP_QEMU
|
||||
UART(uart).FIFO = data;
|
||||
#else /* MODULE_ESP_QEMU */
|
||||
_uarts[uart].regs->fifo.rw_byte = data;
|
||||
#endif /* MODULE_ESP_QEMU */
|
||||
#endif /* MCU_ESP32 */
|
||||
}
|
||||
|
||||
static void __uart_intr_enable(uart_t uart)
|
||||
static void _uart_intr_enable(uart_t uart)
|
||||
{
|
||||
UART(uart).INT_ENABLE |= UART_INT_ENABLE_RXFIFO_FULL;
|
||||
ETS_INTR_ENABLE(ETS_UART_INUM);
|
||||
_uarts[uart].regs->int_ena.rxfifo_full = 1;
|
||||
_uarts[uart].regs->int_clr.rxfifo_full = 1;
|
||||
_uarts[uart].used = true;
|
||||
|
||||
DEBUG("%s %08x\n", __func__, UART(uart).INT_ENABLE);
|
||||
DEBUG("%s %08x\n", __func__, _uarts[uart].regs->int_ena.val);
|
||||
}
|
||||
|
||||
void uart_print_config(void)
|
||||
static void _uart_config(uart_t uart)
|
||||
{
|
||||
LOG_INFO("\tUART_DEV(0): txd=%d rxd=%d\n", UART0_TXD, UART0_RXD);
|
||||
assert(uart < UART_NUMOF);
|
||||
|
||||
while (_uarts[uart].regs->status.txfifo_cnt != 0) { }
|
||||
#if 0
|
||||
/* setup the baudrate */
|
||||
if (uart == UART_DEV(0) || uart == UART_DEV(1)) {
|
||||
/* for UART0 and UART1, we can us the ROM function */
|
||||
uart_div_modify(uart, (UART_CLK_FREQ << 4) / _uarts[uart].baudrate);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (_uart_set_baudrate(uart, _uarts[uart].baudrate) != UART_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* set number of data bits, stop bits and parity mode */
|
||||
if (_uart_set_mode(uart, _uarts[uart].data, _uarts[uart].stop,
|
||||
_uarts[uart].parity) != UART_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* reset the FIFOs */
|
||||
_uarts[uart].regs->conf0.rxfifo_rst = 1;
|
||||
_uarts[uart].regs->conf0.rxfifo_rst = 0;
|
||||
_uarts[uart].regs->conf0.txfifo_rst = 1;
|
||||
_uarts[uart].regs->conf0.txfifo_rst = 0;
|
||||
|
||||
if (_uarts[uart].isr_ctx.rx_cb) {
|
||||
/* since reading can only be done byte by byte, we set
|
||||
UART_RXFIFO_FULL_THRHD interrupt level to 1 byte */
|
||||
_uarts[uart].regs->conf1.rxfifo_full_thrhd = 1;
|
||||
|
||||
/* enable the RX FIFO FULL interrupt */
|
||||
_uart_intr_enable(uart);
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
/* route all UART interrupt sources to same the CPU interrupt */
|
||||
intr_matrix_set(PRO_CPU_NUM, _uarts[uart].int_src, CPU_INUM_UART);
|
||||
#endif /* MCU_ESP32 */
|
||||
|
||||
/* we have to enable therefore the CPU interrupt here */
|
||||
xt_set_interrupt_handler(CPU_INUM_UART, _uart_intr_handler, NULL);
|
||||
xt_ints_on(BIT(CPU_INUM_UART));
|
||||
}
|
||||
}
|
||||
|
||||
static int _uart_set_baudrate(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
DEBUG("%s uart=%d, rate=%d\n", __func__, uart, baudrate);
|
||||
|
||||
CHECK_PARAM_RET (uart < UART_NUMOF, -1);
|
||||
|
||||
/* wait until TX FIFO is empty */
|
||||
while (_uarts[uart].regs->status.txfifo_cnt != 0) { }
|
||||
|
||||
critical_enter();
|
||||
|
||||
_uarts[uart].baudrate = baudrate;
|
||||
|
||||
#ifdef MCU_ESP32
|
||||
/* use APB_CLK */
|
||||
_uarts[uart].regs->conf0.tick_ref_always_on = 1;
|
||||
/* compute and set the integral and the decimal part */
|
||||
uint32_t clk_div = (UART_CLK_FREQ << 4) / _uarts[uart].baudrate;
|
||||
_uarts[uart].regs->clk_div.div_int = clk_div >> 4;
|
||||
_uarts[uart].regs->clk_div.div_frag = clk_div & 0xf;
|
||||
#else
|
||||
/* compute and set clock divider */
|
||||
uint32_t clk_div = UART_CLK_FREQ / _uarts[uart].baudrate;
|
||||
_uarts[uart].regs->clk_div.val = clk_div & 0xFFFFF;
|
||||
#endif
|
||||
|
||||
critical_exit();
|
||||
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
static int _uart_set_mode(uart_t uart, uart_data_bits_t data_bits,
|
||||
uart_parity_t parity, uart_stop_bits_t stop_bits)
|
||||
{
|
||||
DEBUG("%s uart=%d, data_bits=%d parity=%d stop_bits=%d\n", __func__,
|
||||
uart, data_bits, parity, stop_bits);
|
||||
|
||||
CHECK_PARAM_RET (uart < UART_NUMOF, UART_NODEV);
|
||||
|
||||
critical_enter();
|
||||
|
||||
/* set number of data bits */
|
||||
switch (data_bits) {
|
||||
case UART_DATA_BITS_5: _uarts[uart].regs->conf0.bit_num = 0; break;
|
||||
case UART_DATA_BITS_6: _uarts[uart].regs->conf0.bit_num = 1; break;
|
||||
case UART_DATA_BITS_7: _uarts[uart].regs->conf0.bit_num = 2; break;
|
||||
case UART_DATA_BITS_8: _uarts[uart].regs->conf0.bit_num = 3; break;
|
||||
default: LOG_TAG_ERROR("uart", "invalid number of data bits\n");
|
||||
critical_exit();
|
||||
return UART_NOMODE;
|
||||
}
|
||||
/* store changed number of data bits in configuration */
|
||||
_uarts[uart].data = data_bits;
|
||||
|
||||
/* set number of stop bits */
|
||||
#ifdef MCU_ESP32
|
||||
/* workaround for hardware bug when stop bits are set to 2-bit mode. */
|
||||
switch (stop_bits) {
|
||||
case UART_STOP_BITS_1: _uarts[uart].regs->conf0.stop_bit_num = 1;
|
||||
_uarts[uart].regs->rs485_conf.dl1_en = 0;
|
||||
break;
|
||||
case UART_STOP_BITS_2: _uarts[uart].regs->conf0.stop_bit_num = 1;
|
||||
_uarts[uart].regs->rs485_conf.dl1_en = 1;
|
||||
break;
|
||||
default: LOG_TAG_ERROR("uart", "invalid number of stop bits\n");
|
||||
critical_exit();
|
||||
return UART_NOMODE;
|
||||
}
|
||||
#else
|
||||
switch (stop_bits) {
|
||||
case UART_STOP_BITS_1: _uarts[uart].regs->conf0.stop_bit_num = 1; break;
|
||||
case UART_STOP_BITS_2: _uarts[uart].regs->conf0.stop_bit_num = 3; break;
|
||||
default: LOG_TAG_ERROR("uart", "invalid number of stop bits\n");
|
||||
critical_exit();
|
||||
return UART_NOMODE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* store changed number of stop bits in configuration */
|
||||
_uarts[uart].stop = stop_bits;
|
||||
|
||||
/* set parity mode */
|
||||
switch (parity) {
|
||||
case UART_PARITY_NONE: _uarts[uart].regs->conf0.parity_en = 0;
|
||||
break;
|
||||
case UART_PARITY_EVEN: _uarts[uart].regs->conf0.parity = 0;
|
||||
_uarts[uart].regs->conf0.parity_en = 1;
|
||||
break;
|
||||
case UART_PARITY_ODD: _uarts[uart].regs->conf0.parity = 1;
|
||||
_uarts[uart].regs->conf0.parity_en = 1;
|
||||
break;
|
||||
default: LOG_TAG_ERROR("uart", "invalid or unsupported parity mode\n");
|
||||
critical_exit();
|
||||
return UART_NOMODE;
|
||||
}
|
||||
/* store changed parity in configuration */
|
||||
_uarts[uart].parity = parity;
|
||||
|
||||
critical_exit();
|
||||
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
MODULE=sdk
|
||||
MODULE=esp_sdk
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -16,8 +16,35 @@
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
#ifndef MODULE_ESP_SDK
|
||||
|
||||
#include "sdk/ets.h"
|
||||
#include <string.h>
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
#include "eagle_soc.h"
|
||||
#include "sdk/sdk.h"
|
||||
|
||||
uint8_t ets_get_cpu_frequency(void)
|
||||
{
|
||||
return system_get_cpu_freq();
|
||||
}
|
||||
|
||||
void *ets_memcpy(void *dst, const void *src, size_t size)
|
||||
{
|
||||
return memcpy(dst, src, size);
|
||||
}
|
||||
|
||||
void ets_wdt_disable(void)
|
||||
{
|
||||
SET_PERI_REG_BITS(EDGE_INT_ENABLE_REG, BIT0, 0, BIT0);
|
||||
SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, WDT_CTL_EN_MASK, 0, WDT_CTL_EN_LSB);
|
||||
}
|
||||
|
||||
void ets_wdt_enable (void)
|
||||
{
|
||||
SET_PERI_REG_BITS(EDGE_INT_ENABLE_REG, BIT0, 1, BIT0);
|
||||
SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, WDT_CTL_EN_MASK, 1, WDT_CTL_EN_LSB);
|
||||
}
|
||||
|
||||
void ets_install_putc1(void (*p)(char c))
|
||||
{
|
||||
os_install_putc1(p);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -21,27 +21,25 @@
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "c_types.h"
|
||||
#include "ets_sys.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* interrupts that are not defined in espressif/ets_sys.h */
|
||||
/* interrupts that are not defined in rom/ets_sys.h */
|
||||
#define ETS_WDEV_INUM 0 /* WDEV process FIQ interrupt */
|
||||
#define ETS_RTC_INUM 3 /* RTC interrupt */
|
||||
#define ETS_CCOM_INUM 6 /* CCOMPARE0 match interrupt */
|
||||
#define ETS_SOFT_INUM 7 /* software interrupt */
|
||||
#define ETS_WDT_INUM 8 /* SDK watchdog timer */
|
||||
#define ETS_FRC2_INUM 10 /* SDK FRC2 timer interrupt */
|
||||
|
||||
/*
|
||||
* The following functions are mappings or dummies for source code
|
||||
* compatibility of SDK and NON-SDK version
|
||||
* compatibility of NONOS-SDK and RTOS-SDK version
|
||||
*/
|
||||
|
||||
#include "xtensa/xtensa_api.h"
|
||||
@ -50,30 +48,20 @@ extern "C" {
|
||||
#define ets_isr_unmask(x) xt_ints_on(x)
|
||||
#define ets_isr_attach(i,f,a) xt_set_interrupt_handler(i,f,a)
|
||||
|
||||
#define ETS_INTR_ENABLE(inum) ets_isr_unmask((1<<inum))
|
||||
#define ETS_INTR_DISABLE(inum) ets_isr_mask((1<<inum))
|
||||
|
||||
#define _xtos_set_exception_handler(n,f) xt_set_exception_handler(n,f)
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
extern void ets_delay_us(uint16_t us);
|
||||
extern void ets_timer_arm_new(ETSTimer *ptimer, uint32_t ms_us, int repeat_flag, int is_ms);
|
||||
extern void ets_timer_disarm(ETSTimer *ptimer);
|
||||
extern void ets_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *arg);
|
||||
#endif
|
||||
|
||||
extern void ets_timer_arm(ETSTimer *ptimer, uint32_t ms, bool repeat_flag);
|
||||
extern void ets_timer_handler_isr(void);
|
||||
|
||||
extern void ets_install_uart_printf(void);
|
||||
extern void ets_install_putc1(void (*p)(char c));
|
||||
extern int ets_uart_printf(const char *format, ...);
|
||||
|
||||
extern int ets_putc(int);
|
||||
extern int ets_printf(const char * format, ...);
|
||||
extern int ets_vprintf(void *function, const char *format, va_list arg);
|
||||
|
||||
extern uint8_t ets_get_cpu_frequency(void);
|
||||
extern void ets_update_cpu_frequency(uint8_t);
|
||||
extern void ets_update_cpu_frequency(uint8_t);
|
||||
|
||||
extern void *ets_memcpy(void *to, const void *from, size_t size);
|
||||
extern int ets_vprintf(const char *fmt, va_list ap);
|
||||
extern int ets_printf(const char *fmt, ...);
|
||||
extern int ets_putc(int c);
|
||||
extern void ets_install_putc1(void (*p)(char c));
|
||||
|
||||
extern void *ets_memcpy(void *dst, const void *src, size_t size);
|
||||
|
||||
extern void ets_wdt_disable(void);
|
||||
extern void ets_wdt_enable (void);
|
||||
|
||||
@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* PLEASE NOTE: This file is only used in SDK version
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internally, the SDK uses its own priority-based multitasking system,
|
||||
* the *ETS*, to handle hardware components such as the WiFi interface, or to
|
||||
* implement event-driven functions such as software timers. ETS periodically
|
||||
* executes all ETS tasks with pending events in an infinite loop with the ROM
|
||||
* function *ets_run*.
|
||||
*
|
||||
* ETS doesn't process interrupts directly in interrupt service routines.
|
||||
* Instead, they use the *ets_post* ROM function to send an event to one of the
|
||||
* ETS tasks, which then processes the interrupts asynchronously. Context
|
||||
* switches are not possible in interrupt service routines.
|
||||
*
|
||||
* To use SDK functions and keep the system alive, ETS tasks with pending
|
||||
* events have to be handled. For that purpose
|
||||
*
|
||||
* - the *ets_task_func* RIOT thread with highest possible priority is used
|
||||
* - the ROM functions *ets_run* and *ets_post* are overwritten.
|
||||
*
|
||||
* The *ets_task_func* RIOT thread is waiting for a thread flag, which is set
|
||||
* by the *ets_post function* at the end of an ETS interrupt service routine.
|
||||
* The flag indicates that there are ETS tasks with pending events that need
|
||||
* to be executed. The *ets_task_func* RIOT thread then calls the *ets_run*
|
||||
* function, which performs all ETS tasks with pending events exactly once.
|
||||
*
|
||||
* Thus, when a hardware component used by the SDK triggers an interrupt, e.g.
|
||||
* the WiFi interface, the interrupt sevice routine posts an event to the ETS
|
||||
* task by calling the *ets_post* function. The overwritten version of this
|
||||
* function sets the thread flag of the *ets_task_func* thread. The thread
|
||||
* then calls function *ets_run* to process pending events.
|
||||
*/
|
||||
|
||||
#ifdef MODULE_ESP_SDK
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include <stdio.h>
|
||||
|
||||
#include "irq_arch.h"
|
||||
#include "mutex.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "esp/common_macros.h"
|
||||
#include "sdk/ets_task.h"
|
||||
#include "sdk/sdk.h"
|
||||
|
||||
static uint8_t min_prio = 0;
|
||||
|
||||
/* helper function for *ets_run* */
|
||||
uint8_t ets_highest_1_bit (uint32_t mask)
|
||||
{
|
||||
__asm__ volatile ("nsau %0, %1;" :"=r"(mask) : "r"(mask));
|
||||
return 32 - mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the execution of all pending ETS tasks. This is necessary to
|
||||
* keep the underlying ETS system used by the SDK alive. It is called from
|
||||
* the RIOT thread *ets_task_func*.
|
||||
*/
|
||||
void IRAM ets_tasks_run (void)
|
||||
{
|
||||
#if ENABLE_DEBUG
|
||||
uint32_t _entry = phy_get_mactime();
|
||||
uint32_t _exit;
|
||||
ets_printf("ets_tasks_run @%lu\n", _entry);
|
||||
#endif
|
||||
|
||||
/* reset hardware watchdog here */
|
||||
system_soft_wdt_feed();
|
||||
|
||||
while (1) {
|
||||
uint8_t hbit;
|
||||
int state = irq_disable();
|
||||
hbit = ets_highest_1_bit (ets_task_exec_mask);
|
||||
if (min_prio < hbit) {
|
||||
ets_task_tcb_t* task = &ets_task_tab[hbit-1];
|
||||
ETSEvent * event = &task->queue[task->qposr++];
|
||||
if (task->qposr == task->qlength) {
|
||||
task->qposr = 0;
|
||||
}
|
||||
if (--task->qpending == 0) {
|
||||
ets_task_exec_mask &= ~task->maskbit;
|
||||
}
|
||||
ets_task_min_prio = hbit;
|
||||
irq_restore(state);
|
||||
task->task(event);
|
||||
ets_task_min_prio = min_prio;
|
||||
}
|
||||
else {
|
||||
irq_restore(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
_exit = phy_get_mactime();
|
||||
ets_printf("ets_tasks_run @%lu for %lu us\n", _entry, _exit - _entry);
|
||||
#endif
|
||||
|
||||
/* reset hardware watchdog here again */
|
||||
system_soft_wdt_feed();
|
||||
}
|
||||
|
||||
|
||||
#define THREAD_FLAG_ETS_THREAD (1 << 0)
|
||||
static volatile thread_t* ets_thread = NULL;
|
||||
|
||||
/*
|
||||
* Thread *ets_task_func* is waiting for the thread flag THREAD_FLAG_ETS_THREAD
|
||||
* indicating that ETS tasks have pending events and need to be executed. When
|
||||
* the thread flag is set, it calls the *ets_run* function, which performs
|
||||
* all ETS tasks with pending events exactly once. The thread flag is set by
|
||||
* the *ets_post* function, which is called at the end of an ETS interrupt
|
||||
* service routine.
|
||||
*/
|
||||
void *ets_task_func(void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
|
||||
ets_thread = sched_active_thread;
|
||||
while (1) {
|
||||
thread_flags_wait_one(THREAD_FLAG_ETS_THREAD);
|
||||
ets_tasks_run();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* helper macro for *ets_post */
|
||||
#define irom_cache_enabled() (*((uint32_t*)0x60000208) & (1 << 17))
|
||||
|
||||
/* ETS timer task priority */
|
||||
#define TIMER_TASK_PRIORITY 31
|
||||
|
||||
/* reference to the *ets_post* ROM function */
|
||||
typedef uint32_t (*ets_post_function_t)(uint32_t prio, ETSSignal sig, ETSParam par);
|
||||
static ets_post_function_t ets_post_rom = (ets_post_function_t)0x40000e24;
|
||||
|
||||
/*
|
||||
* Overwritten version of ROM function *ets_post*.
|
||||
*
|
||||
* ETS doesn't process interrupts directly in interrupt service routines.
|
||||
* Instead, they use the *ets_post* ROM function to send an event to one of the
|
||||
* ETS tasks, which then processes the interrupts asynchronously. Context
|
||||
* switches are not possible in interrupt service routines.
|
||||
*
|
||||
* Please note: *ets_post* is executed in interrupt context
|
||||
*/
|
||||
uint32_t IRAM ets_post (uint32_t prio, ETSSignal sig, ETSParam par)
|
||||
{
|
||||
/* This function is executed in interrupt context */
|
||||
uint32_t ret;
|
||||
|
||||
critical_enter();
|
||||
|
||||
/* test whether we are in hardware timer interrupt handling routine */
|
||||
if (prio == TIMER_TASK_PRIORITY) {
|
||||
/* first call ETS system post function */
|
||||
ret = ets_post_rom (prio, sig, par);
|
||||
|
||||
/* handle only pending timer events */
|
||||
if (irom_cache_enabled()) {
|
||||
ets_timer_handler_isr();
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* simply call ROM ets_post function */
|
||||
ret = ets_post_rom (prio, sig, par);
|
||||
}
|
||||
/* since only timer events are handled we have to reset watch dog timer */
|
||||
if (irom_cache_enabled()) {
|
||||
system_soft_wdt_feed();
|
||||
}
|
||||
|
||||
if (ets_thread && irom_cache_enabled()) {
|
||||
thread_flags_set((thread_t*)ets_thread, THREAD_FLAG_ETS_THREAD);
|
||||
}
|
||||
|
||||
critical_exit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ets_tasks_init(void)
|
||||
{
|
||||
/* there is nothing to be done here at the moment */
|
||||
}
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef ETS_TASK_H
|
||||
#define ETS_TASK_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_ESP_SDK
|
||||
|
||||
#include "ets_sys.h"
|
||||
|
||||
extern uint8_t ets_task_min_prio;
|
||||
|
||||
/* Task control block definition as used for ETS task functions */
|
||||
|
||||
typedef struct {
|
||||
ETSTask task; /* +0 task function */
|
||||
ETSEvent* queue; /* +4 event queue (ring buffer) */
|
||||
uint8_t qlength; /* +8 event queue length */
|
||||
uint8_t qposw; /* +9 event queue position for write */
|
||||
uint8_t qposr; /* +10 event queue position for read */
|
||||
uint8_t qpending; /* +11 pending events */
|
||||
uint32_t maskbit; /* +12 task mask bit */
|
||||
} ets_task_tcb_t;
|
||||
|
||||
/* ROM variables, defined in esp8266.riot-os.app.ld */
|
||||
/* source: disassembly of boot rom at https://github.com/trebisky/esp8266 */
|
||||
|
||||
extern uint8_t ets_task_min_prio; /* 0x3fffc6fc */
|
||||
extern void* ets_idle_cb; /* 0x3fffdab0 */
|
||||
extern void* ets_idle_arg; /* 0x3fffdab4 */
|
||||
extern uint32_t ets_task_exec_mask; /* 0x3fffdab8 */
|
||||
extern ets_task_tcb_t ets_task_tab[32]; /* 0x3fffdac0 */
|
||||
|
||||
extern uint32_t ets_post (uint32_t prio, ETSSignal sig, ETSParam par);
|
||||
|
||||
void ets_tasks_run (void);
|
||||
void ets_tasks_init (void);
|
||||
|
||||
#else /* MODULE_ESP_SDK */
|
||||
|
||||
#define ets_tasks_run()
|
||||
#define ets_tasks_init()
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* ETS_TASK_H */
|
||||
@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief lwIP functions required as symbols by the SDK
|
||||
*
|
||||
* This file defines a number of lwIP functions that are required as symbols by
|
||||
* Espressif's SDK libraries. Since RIOT doesn't need lwIP, these functions are
|
||||
* only dummies without real functionality. Using these functions instead of
|
||||
* the lwIP functions as provided with the SDK saves arround 4 kBytes of RAM.
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef MODULE_ESP_SDK
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
#include "netif/etharp.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
#include "log.h"
|
||||
|
||||
#ifndef ERR_OK
|
||||
#define ERR_OK 0
|
||||
#endif
|
||||
|
||||
const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
||||
|
||||
err_t ethernet_input(struct pbuf *pb, struct netif* netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)pb;
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
(void)q;
|
||||
(void)ipaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
(void)ipaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void etharp_tmr(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
void etharp_cleanup_netif(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
}
|
||||
|
||||
void dhcp_cleanup(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
}
|
||||
|
||||
err_t dhcp_start(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t dhcp_renew(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t dhcp_release(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void dhcp_stop(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
}
|
||||
|
||||
void dhcp_network_changed(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
}
|
||||
|
||||
void dhcp_coarse_tmr(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
void dhcp_fine_tmr(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
void dhcps_start(struct ip_info *info)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)info;
|
||||
}
|
||||
|
||||
void dhcps_stop(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
void dhcps_coarse_tmr(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
union tcp_listen_pcbs_t tcp_listen_pcbs;
|
||||
struct tcp_pcb *tcp_active_pcbs;
|
||||
struct tcp_pcb *tcp_tw_pcbs;
|
||||
|
||||
void tcp_seg_free(struct tcp_seg *seg)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)seg;
|
||||
}
|
||||
|
||||
void tcp_abort (struct tcp_pcb *pcb)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)pcb;
|
||||
}
|
||||
|
||||
void tcp_tmr(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
void igmp_init(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
err_t igmp_start(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t igmp_stop(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void igmp_report_groups(struct netif *netif)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)netif;
|
||||
}
|
||||
|
||||
void igmp_tmr(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
void dns_init(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
void dns_tmr(void)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
}
|
||||
|
||||
uint32_t espconn_init(uint32 arg)
|
||||
{
|
||||
DEBUG("%s\n", __func__);
|
||||
(void)arg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern struct netif * eagle_lwip_getif(uint8_t index);
|
||||
|
||||
void esp_lwip_init(void)
|
||||
{
|
||||
netif_set_default((struct netif *)eagle_lwip_getif(0));
|
||||
}
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
@ -1,202 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 SDK libmain function
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "cpu_conf.h"
|
||||
#include "irq.h"
|
||||
#include "irq_arch.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "esp/rtcmem_regs.h"
|
||||
#include "spi_flash.h"
|
||||
#include "sdk/ets.h"
|
||||
#include "sdk/main.h"
|
||||
#include "sdk/rom.h"
|
||||
|
||||
static char _printf_buf[PRINTF_BUFSIZ];
|
||||
|
||||
int IRAM os_printf_plus (const char* format, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
va_start(arglist, format);
|
||||
|
||||
int ret = vsnprintf(_printf_buf, PRINTF_BUFSIZ, format, arglist);
|
||||
|
||||
if (ret > 0) {
|
||||
ets_printf (_printf_buf);
|
||||
}
|
||||
|
||||
va_end(arglist);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SpiFlashOpResult IRAM spi_flash_read (uint32_t faddr, uint32_t *dst, size_t size)
|
||||
{
|
||||
/*
|
||||
* For simplicity, we use the ROM function. Since we need to disable the
|
||||
* IROM cache function for that purpose, we have to be IRAM.
|
||||
* Please note, faddr, src and size have to be aligned to 4 byte.
|
||||
*/
|
||||
|
||||
SpiFlashOpResult ret;
|
||||
|
||||
CHECK_PARAM_RET (dst != NULL, SPI_FLASH_RESULT_ERR);
|
||||
CHECK_PARAM_RET (faddr + size <= flashchip->chip_size, SPI_FLASH_RESULT_ERR);
|
||||
|
||||
critical_enter ();
|
||||
Cache_Read_Disable ();
|
||||
|
||||
ret = SPIRead (faddr, dst, size);
|
||||
|
||||
Cache_Read_Enable(0, 0, 1);
|
||||
critical_exit ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SpiFlashOpResult IRAM spi_flash_write (uint32_t faddr, uint32_t *src, size_t size)
|
||||
{
|
||||
/*
|
||||
* For simplicity, we use the ROM function. Since we need to disable the
|
||||
* IROM cache function for that purpose, we have to be in IRAM.
|
||||
* Please note, faddr, src and size have to be aligned to 4 byte
|
||||
*/
|
||||
|
||||
SpiFlashOpResult ret;
|
||||
|
||||
CHECK_PARAM_RET (src != NULL, SPI_FLASH_RESULT_ERR);
|
||||
CHECK_PARAM_RET (faddr + size <= flashchip->chip_size, SPI_FLASH_RESULT_ERR);
|
||||
|
||||
critical_enter ();
|
||||
Cache_Read_Disable ();
|
||||
|
||||
ret = SPIWrite (faddr, src, size);
|
||||
|
||||
Cache_Read_Enable(0, 0, 1);
|
||||
critical_exit ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SpiFlashOpResult IRAM spi_flash_erase_sector(uint16_t sec)
|
||||
{
|
||||
CHECK_PARAM_RET (sec < flashchip->chip_size / flashchip->sector_size, SPI_FLASH_RESULT_ERR);
|
||||
|
||||
critical_enter ();
|
||||
Cache_Read_Disable();
|
||||
|
||||
SpiFlashOpResult ret = SPIEraseSector (sec);
|
||||
|
||||
Cache_Read_Enable(0, 0, 1);
|
||||
critical_exit ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void system_deep_sleep(uint32_t time_in_us)
|
||||
{
|
||||
/* TODO implement */
|
||||
(void)time_in_us;
|
||||
NOT_YET_IMPLEMENTED();
|
||||
}
|
||||
|
||||
void system_restart(void)
|
||||
{
|
||||
/* TODO it's just a hard reset at the moment */
|
||||
__asm__ volatile (" call0 0x40000080 ");
|
||||
}
|
||||
|
||||
extern bool system_update_cpu_freq(uint8 freq)
|
||||
{
|
||||
if (freq == 160) {
|
||||
DPORT.CPU_CLOCK |= DPORT_CPU_CLOCK_X2;
|
||||
ets_update_cpu_frequency(160);
|
||||
}
|
||||
else {
|
||||
DPORT.CPU_CLOCK &= ~DPORT_CPU_CLOCK_X2;
|
||||
ets_update_cpu_frequency(80);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Following code is completly or at least partially from
|
||||
* https://github.com/pvvx/esp8266web
|
||||
* (c) PV` 2015
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
uint8_t ICACHE_FLASH_ATTR system_get_checksum(uint8_t *ptr, uint32_t len)
|
||||
{
|
||||
uint8_t checksum = 0xEF;
|
||||
while (len--) {
|
||||
checksum ^= *ptr++;
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
|
||||
#define RTCMEM_SIZE 0x300 /* user RTC RAM 768 bytes, 192 dword registers */
|
||||
|
||||
static bool IRAM _system_rtc_mem_access (uint32_t src, void *dst, uint32_t size, bool write)
|
||||
{
|
||||
/* src hast to be smaller than 192 */
|
||||
CHECK_PARAM_RET (src <= (RTCMEM_SIZE >> 2), false);
|
||||
/* src times 4 plus size must less than RTCMEM_SIZE */
|
||||
CHECK_PARAM_RET (((src << 2) + size) < RTCMEM_SIZE, false);
|
||||
/* des_addr has to be a multiple of 4 */
|
||||
CHECK_PARAM_RET (((uint32_t)dst & 0x3) == 0, false);
|
||||
|
||||
/* align size to next higher multiple of 4 */
|
||||
if (size & 0x3) {
|
||||
size = (size + 4) & ~0x3;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < (size >> 2); i++) {
|
||||
if (write) {
|
||||
RTCMEM_SYSTEM[src + i] = ((uint32_t*)dst)[i];
|
||||
}
|
||||
else {
|
||||
((uint32_t*)dst)[i] = RTCMEM_SYSTEM[src + i];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IRAM system_rtc_mem_read (uint32_t src_addr, void *des_addr, uint32_t save_size)
|
||||
{
|
||||
return _system_rtc_mem_access (src_addr, des_addr, save_size, false);
|
||||
}
|
||||
|
||||
bool IRAM system_rtc_mem_write (uint32_t src_addr, void *des_addr, uint32_t save_size)
|
||||
{
|
||||
return _system_rtc_mem_access (src_addr, des_addr, save_size, true);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 SDK libmain function prototypes
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
#include "esp/dport_regs.h"
|
||||
|
||||
/*
|
||||
* The following functions are mappings or dummies for source code
|
||||
* compatibility of SDK and NON-SDK version
|
||||
*/
|
||||
|
||||
#define system_get_time phy_get_mactime
|
||||
#define system_get_chip_id() (((DPORT.OTP_MAC1 & 0xffff) << 8) + ((DPORT.OTP_MAC0 >> 24) & 0xff))
|
||||
#define system_get_cpu_freq ets_get_cpu_frequency
|
||||
|
||||
extern int os_printf_plus (const char* format, ...);
|
||||
|
||||
extern void system_deep_sleep (uint32_t time_in_us);
|
||||
extern uint8_t system_get_checksum(uint8_t *ptr, uint32_t len);
|
||||
extern void system_restart (void);
|
||||
extern bool system_update_cpu_freq(uint8 freq);
|
||||
|
||||
extern bool system_rtc_mem_read(uint32_t src_addr, void *des_addr, uint32_t save_size);
|
||||
extern bool system_rtc_mem_write(uint32_t src_addr, void *des_addr, uint32_t save_size);
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
|
||||
extern void NmiTimSetFunc(void (*func)(void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* MAIN_H */
|
||||
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 SDK libphy functions
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
|
||||
#include "sdk/phy.h"
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -25,29 +25,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
/*
|
||||
* The following functions are mappings or dummies for source code
|
||||
* compatibility of SDK and NON-SDK version
|
||||
*/
|
||||
|
||||
#include "esp/dport_regs.h"
|
||||
|
||||
extern void phy_afterwake_set_rfoption(int op);
|
||||
extern int phy_check_data_table(void * gdctbl, int x, int flg);
|
||||
extern int register_chipv6_phy(uint8_t * esp_init_data);
|
||||
extern void sleep_reset_analog_rtcreg_8266(void);
|
||||
extern uint32_t test_tout(bool);
|
||||
extern void write_data_to_rtc(uint8_t *);
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
|
||||
extern uint32_t phy_get_mactime(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 other ROM functions
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
|
||||
#include "sdk/pp.h"
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 SDK libpp function prototypes
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef PP_H
|
||||
#define PP_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
/*
|
||||
* The following functions are mappings or dummies for source code
|
||||
* compatibility of SDK and NON-SDK version
|
||||
*/
|
||||
|
||||
#define system_soft_wdt_feed()
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* PP_H */
|
||||
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 other ROM functions
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
|
||||
#include "sdk/rom.h"
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 other ROM function prototypes
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef ROM_H
|
||||
#define ROM_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "c_types.h"
|
||||
#include "spi_flash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MODULE_ESP_SDK
|
||||
/*
|
||||
* The following functions are mappings or dummies for source code
|
||||
* compatibility of SDK and NON-SDK version
|
||||
*/
|
||||
|
||||
extern uint8_t rom_i2c_readReg(uint32_t block, uint32_t host_id, uint32_t reg_add);
|
||||
extern uint8_t rom_i2c_readReg_Mask(uint32_t block, uint32_t host_id,
|
||||
uint32_t reg_add,uint32_t Msb, uint32_t Lsb);
|
||||
extern void rom_i2c_writeReg (uint32_t block, uint32_t host_id,
|
||||
uint32_t reg_add, uint32_t data);
|
||||
extern void rom_i2c_writeReg_Mask(uint32_t block, uint32_t host_id,
|
||||
uint32_t reg_add, uint32_t Msb, uint32_t Lsb,
|
||||
uint32_t indata);
|
||||
|
||||
extern uint32_t rtc_get_reset_reason(void);
|
||||
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
|
||||
/* pointer to flash chip data structure */
|
||||
extern SpiFlashChip* flashchip;
|
||||
|
||||
extern SpiFlashOpResult spi_flash_attach(void);
|
||||
|
||||
void Cache_Read_Disable(void);
|
||||
void Cache_Read_Enable (uint32_t odd_even, uint32_t mb_count, uint32_t no_idea);
|
||||
|
||||
SpiFlashOpResult Wait_SPI_Idle(SpiFlashChip *chip);
|
||||
SpiFlashOpResult SPI_write_enable(SpiFlashChip *chip);
|
||||
|
||||
SpiFlashOpResult SPIEraseArea (uint32_t off, size_t len);
|
||||
SpiFlashOpResult SPIEraseBlock (uint32_t num);
|
||||
SpiFlashOpResult SPIEraseSector(uint32_t num);
|
||||
SpiFlashOpResult SPIEraseChip (void);
|
||||
|
||||
SpiFlashOpResult SPILock (void);
|
||||
SpiFlashOpResult SPIUnlock(void);
|
||||
|
||||
SpiFlashOpResult SPIRead (uint32_t off, uint32_t *dst, size_t size);
|
||||
SpiFlashOpResult SPIWrite (uint32_t off, const uint32_t *src, size_t size);
|
||||
|
||||
int SPIReadModeCnfig (uint32_t);
|
||||
|
||||
/* set elements of flashchip, see struct SpiFlashChip; */
|
||||
SpiFlashOpResult SPIParamCfg (uint32_t deviceId,
|
||||
uint32_t chip_size,
|
||||
uint32_t block_size,
|
||||
uint32_t sector_size,
|
||||
uint32_t page_size,
|
||||
uint32_t status_mask);
|
||||
|
||||
extern void uartAttach (void);
|
||||
extern void uart_div_modify(uint8 uart_no, uint32_t DivLatchValue);
|
||||
extern void Uart_Init (uint8 uart_no);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* ROM_H */
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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
|
||||
@ -20,25 +20,16 @@
|
||||
#ifndef SDK_H
|
||||
#define SDK_H
|
||||
|
||||
#include "c_types.h"
|
||||
#include "ets_sys.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sdk/ets.h"
|
||||
#include "sdk/main.h"
|
||||
#include "sdk/phy.h"
|
||||
#include "sdk/pp.h"
|
||||
#include "sdk/rom.h"
|
||||
#include "sdk/user.h"
|
||||
#include "sdk/system.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_ESP_SDK
|
||||
#include "espressif/osapi.h"
|
||||
#include "espressif/user_interface.h"
|
||||
#endif /* MODULE_ESP_SDK */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
56
cpu/esp8266/sdk/system.c
Normal file
56
cpu/esp8266/sdk/system.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 user defined SDK functions
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "sdk/sdk.h"
|
||||
|
||||
#include "esp/dport_regs.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
uint32_t system_get_chip_id(void)
|
||||
{
|
||||
/* Chip ID as determined by NONOS SDK */
|
||||
return (((DPORT.OTP_MAC1 << 8) & 0xffffff00) + ((DPORT.OTP_MAC0 >> 24) & 0xff));
|
||||
}
|
||||
|
||||
const char* system_get_sdk_version(void)
|
||||
{
|
||||
return esp_get_idf_version();
|
||||
}
|
||||
|
||||
void system_deep_sleep(uint32_t time_in_us)
|
||||
{
|
||||
/* TODO test */
|
||||
esp_deep_sleep(time_in_us);
|
||||
}
|
||||
|
||||
void system_restart(void)
|
||||
{
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
void system_update_cpu_freq(uint8_t freq)
|
||||
{
|
||||
if (freq == 160) {
|
||||
rtc_clk_cpu_freq_set(RTC_CPU_FREQ_160M);
|
||||
}
|
||||
else {
|
||||
rtc_clk_cpu_freq_set(RTC_CPU_FREQ_80M);
|
||||
}
|
||||
}
|
||||
60
cpu/esp8266/sdk/system.h
Normal file
60
cpu/esp8266/sdk/system.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* 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 cpu_esp8266_sdk
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ESP8266 user defined SDK function prototypes
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_H
|
||||
#define SYSTEM_H
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "esp_task_wdt.h"
|
||||
#include "sdk/ets.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Functions for NONOS SDK compatibility
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
extern uint8_t system_get_cpu_freq(void);
|
||||
extern void system_update_cpu_freq(uint8_t);
|
||||
extern uint32_t system_get_chip_id(void);
|
||||
extern const char* system_get_sdk_version(void);
|
||||
|
||||
extern void system_deep_sleep(uint32_t time_in_us);
|
||||
extern void system_restart(void);
|
||||
|
||||
#define system_wdt_init esp_task_wdt_init
|
||||
#define system_wdt_feed esp_task_wdt_reset
|
||||
#define system_wdt_start pp_soft_wdt_stop
|
||||
#define system_wdt_stop pp_soft_wdt_restart
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DOXYGEN */
|
||||
#endif /* SYSTEM_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user