Add ESP32C3 support/coexistence.

The uzlib and parts of Lua had to be switched over to use the
C standard int types, as their custom typedefs conflicted with
RISC-V toolchain provided typedefs.

UART console driver updated to do less direct register meddling
and use the IDF uart driver interface for setup. Still using our
own ISR rather than the default driver ISR. Down the line we
might want to investigate whether the IDF ISR would be a better
fit.

Lua C modules have been split into common and ESP32/ESP32-S
specific ones. In the future there might also be ESP32-C3
specific modules, which would go into components/modules-esp32c3
at that point.

Our old automatic fixup of flash size has been discarded as it
interferes with the checksumming done by the ROM loader and
results in unbootable systems. The IDF has already taken on
this work via the ESPTOOL_FLASHSIZE_DETECT option, which handles
this situation properly.
This commit is contained in:
Johny Mattsson 2021-08-11 17:11:11 +10:00
parent 9647cc2185
commit f123d46209
40 changed files with 443 additions and 327 deletions

View File

@ -8,10 +8,8 @@ jobs:
strategy:
matrix:
lua_ver: ['5.1']
numbers: ['float']
include:
- lua_ver: '5.1'
numbers: 'integral'
numbers: ['float','integral']
target: ['esp32','esp32c3']
runs-on: ubuntu-latest
@ -34,18 +32,18 @@ jobs:
if: ${{ matrix.lua_ver == '5.1' && matrix.numbers == 'float' }}
run: |
cp sdkconfig.defaults sdkconfig
make SHELL=/bin/bash
make IDF_TARGET=${{ matrix.target }}
shell: bash
- name: Build firmware (Lua 5.1, integer-only)
if: ${{ matrix.lua_ver == '5.1' && matrix.numbers == 'integral' }}
run: |
cp sdkconfig.defaults sdkconfig
echo CONFIG_LUA_NUMBER_INTEGRAL=y >> sdkconfig
make SHELL=/bin/bash
make IDF_TARGET=${{ matrix.target }}
shell: bash
- name: Upload luac.cross
uses: actions/upload-artifact@v2
if: ${{ success() }}
with:
name: luac.cross-${{ matrix.lua_ver }}-${{ matrix.numbers }}
name: luac.cross-${{ matrix.lua_ver }}-${{ matrix.numbers }}-${{ matrix.target }}
path: build/luac_cross/luac.cross

View File

@ -1,3 +1,5 @@
SHELL:=/bin/bash
ifeq ($(IDF_PATH),)
THIS_MK_FILE:=$(notdir $(lastword $(MAKEFILE_LIST)))

View File

@ -264,7 +264,7 @@ static int uart_wakeup (lua_State *L)
uint32_t id = luaL_checkinteger(L, 1);
MOD_CHECK_ID(uart, id);
int threshold = luaL_checkinteger(L, 2);
esp_err_t err = uart_set_wakeup_threshold(id, threshold);
int err = platform_uart_set_wakeup_threshold(id, threshold);
if (err) {
return luaL_error(L, "Error %d from uart_set_wakeup_threshold()", err);
}
@ -275,7 +275,7 @@ static int luart_tx_flush (lua_State *L)
{
uint32_t id = luaL_checkinteger(L, 1);
MOD_CHECK_ID(uart, id);
uart_tx_flush(id);
platform_uart_flush(id);
return 0;
}

View File

@ -124,18 +124,6 @@ void nodemcu_init(void)
return;
}
if (flash_safe_get_size_byte() != flash_rom_get_size_byte()) {
NODE_ERR("Incorrect flash size reported, adjusting...\n");
// Fit hardware real flash size.
flash_rom_set_size_byte(flash_safe_get_size_byte());
// Reboot to get SDK to use (or write) init data at new location
esp_restart ();
// Don't post the start_lua task, we're about to reboot...
return;
}
#if defined ( CONFIG_NODEMCU_BUILD_SPIFFS )
// This can take a while, so be nice and provide some feedback while waiting
printf ("Mounting flash filesystem...\n");

View File

@ -1,4 +1,8 @@
if(NOT "${IDF_TARGET}" STREQUAL "esp32c3")
idf_component_register(
SRCS "CAN.c"
INCLUDE_DIRS "include"
)
endif()

View File

@ -32,16 +32,17 @@
*/
#include "driver/console.h"
#include "driver/uart.h"
#include "esp_intr_alloc.h"
#include "soc/soc.h"
#include "soc/uart_reg.h"
#include "soc/dport_reg.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include <unistd.h>
#include "esp32/rom/libc_stubs.h"
#include "sys/reent.h"
#include <unistd.h>
#include "rom/libc_stubs.h"
#include "rom/uart.h"
#define UART_INPUT_QUEUE_SZ 0x100
@ -49,23 +50,17 @@
#define UART_GET_RXFIFO_RD_BYTE(i) GET_PERI_REG_BITS2(UART_FIFO_REG(i) , UART_RXFIFO_RD_BYTE_V, UART_RXFIFO_RD_BYTE_S)
#define UART_GET_RXFIFO_CNT(i) GET_PERI_REG_BITS2(UART_STATUS_REG(i) , UART_RXFIFO_CNT_V, UART_RXFIFO_CNT_S)
#define UART_SET_AUTOBAUD_EN(i,val) SET_PERI_REG_BITS(UART_AUTOBAUD_REG(i) ,UART_AUTOBAUD_EN_V,(val),UART_AUTOBAUD_EN_S)
# define UART_SET_PARITY_EN(i,val) SET_PERI_REG_BITS(UART_CONF0_REG(i) ,UART_PARITY_EN_V,(val),UART_PARITY_EN_S)
#define UART_SET_RX_TOUT_EN(i,val) SET_PERI_REG_BITS(UART_CONF1_REG(i) ,UART_RX_TOUT_EN_V,(val),UART_RX_TOUT_EN_S)
#define UART_SET_RX_TOUT_THRHD(i,val) SET_PERI_REG_BITS(UART_CONF1_REG(i) ,UART_RX_TOUT_THRHD_V,(val),UART_RX_TOUT_THRHD_S)
#define UART_SET_RXFIFO_FULL_THRHD(i,val) SET_PERI_REG_BITS(UART_CONF1_REG(i) ,UART_RXFIFO_FULL_THRHD_V,(val),UART_RXFIFO_FULL_THRHD_S)
#define UART_SET_STOP_BIT_NUM(i,val) SET_PERI_REG_BITS(UART_CONF0_REG(i) ,UART_STOP_BIT_NUM_V,(val),UART_STOP_BIT_NUM_S)
#define UART_SET_BIT_NUM(i,val) SET_PERI_REG_BITS(UART_CONF0_REG(i) ,UART_BIT_NUM_V,(val),UART_BIT_NUM_S)
#define UART_SET_PARITY_EN(i,val) SET_PERI_REG_BITS(UART_CONF0_REG(i) ,UART_PARITY_EN_V,(val),UART_PARITY_EN_S)
#define UART_SET_PARITY(i,val) SET_PERI_REG_BITS(UART_CONF0_REG(i) ,UART_PARITY_V,(val),UART_PARITY_S)
typedef int (*_read_r_fn) (struct _reent *r, int fd, void *buf, int size);
static _read_r_fn _read_r_pro, _read_r_app;
static _read_r_fn _read_r_app;
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
static _read_r_fn _read_r_pro;
#endif
static xQueueHandle uart0Q;
static task_handle_t input_task = 0;
static intr_handle_t intr_handle;
// --- Syscall support for reading from STDIN_FILENO ---------------
@ -91,10 +86,12 @@ static int console_read_r (struct _reent *r, int fd, void *buf, int size, _read_
return -1;
}
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
static int console_read_r_pro (struct _reent *r, int fd, void *buf, int size)
{
return console_read_r (r, fd, buf, size, _read_r_pro);
}
#endif
static int console_read_r_app (struct _reent *r, int fd, void *buf, int size)
{
return console_read_r (r, fd, buf, size, _read_r_app);
@ -137,16 +134,31 @@ static void uart0_rx_intr_handler (void *arg)
void console_setup (const ConsoleSetup_t *cfg)
{
uart_tx_wait_idle (CONSOLE_UART);
esp_rom_uart_tx_wait_idle (CONSOLE_UART);
uart_div_modify (CONSOLE_UART, (UART_CLK_FREQ << 4) / cfg->bit_rate);
UART_SET_BIT_NUM(CONSOLE_UART, cfg->data_bits);
UART_SET_PARITY_EN(CONSOLE_UART, cfg->parity != CONSOLE_PARITY_NONE);
UART_SET_PARITY(CONSOLE_UART, cfg->parity & 0x1);
UART_SET_STOP_BIT_NUM(CONSOLE_UART, cfg->stop_bits);
uart_config_t uart_conf = {
.baud_rate = cfg->bit_rate,
.data_bits =
cfg->data_bits == CONSOLE_NUM_BITS_5 ? UART_DATA_5_BITS :
cfg->data_bits == CONSOLE_NUM_BITS_6 ? UART_DATA_6_BITS :
cfg->data_bits == CONSOLE_NUM_BITS_7 ? UART_DATA_7_BITS :
UART_DATA_8_BITS,
.stop_bits =
cfg->stop_bits == CONSOLE_STOP_BITS_1 ? UART_STOP_BITS_1 :
cfg->stop_bits == CONSOLE_STOP_BITS_2 ? UART_STOP_BITS_2 :
UART_STOP_BITS_1_5,
.parity =
cfg->parity == CONSOLE_PARITY_NONE ? UART_PARITY_DISABLE :
cfg->parity == CONSOLE_PARITY_EVEN ? UART_PARITY_EVEN :
UART_PARITY_ODD,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};
uart_param_config(CONSOLE_UART, &uart_conf);
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
// TODO: Make this actually work
UART_SET_AUTOBAUD_EN(CONSOLE_UART, cfg->auto_baud);
#endif
}
@ -158,26 +170,24 @@ void console_init (const ConsoleSetup_t *cfg, task_handle_t tsk)
console_setup (cfg);
esp_intr_alloc (ETS_UART0_INTR_SOURCE + CONSOLE_UART,
ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_INTRDISABLED,
uart0_rx_intr_handler, NULL, &intr_handle);
UART_SET_RX_TOUT_EN(CONSOLE_UART, true);
UART_SET_RX_TOUT_THRHD(CONSOLE_UART, 2);
UART_SET_RXFIFO_FULL_THRHD(CONSOLE_UART, 10);
WRITE_PERI_REG(UART_INT_ENA_REG(CONSOLE_UART),
UART_RXFIFO_TOUT_INT_ENA |
UART_RXFIFO_FULL_INT_ENA |
UART_FRM_ERR_INT_ENA);
esp_intr_enable (intr_handle);
uart_isr_register(CONSOLE_UART, uart0_rx_intr_handler, NULL, 0, NULL);
uart_set_rx_timeout(CONSOLE_UART, 2);
uart_set_rx_full_threshold(CONSOLE_UART, 10);
uart_enable_intr_mask(CONSOLE_UART,
UART_RXFIFO_TOUT_INT_ENA_M |
UART_RXFIFO_FULL_INT_ENA_M |
UART_FRM_ERR_INT_ENA_M);
// Register our console_read_r_xxx functions to support stdin input
_read_r_pro = syscall_table_ptr_pro->_read_r;
#if defined(CONFIG_IDF_TARGET_ESP32C3)
_read_r_app = syscall_table_ptr->_read_r;
syscall_table_ptr->_read_r = console_read_r_app;
#else
_read_r_app = syscall_table_ptr_app->_read_r;
syscall_table_ptr_pro->_read_r = console_read_r_pro;
_read_r_pro = syscall_table_ptr_pro->_read_r;
syscall_table_ptr_app->_read_r = console_read_r_app;
syscall_table_ptr_pro->_read_r = console_read_r_pro;
#endif
}
@ -185,4 +195,3 @@ bool console_getc (char *c)
{
return (uart0Q && (xQueueReceive (uart0Q, c, 0) == pdTRUE));
}

View File

@ -31,7 +31,7 @@
* @author Johny Mattsson <jmattsson@dius.com.au>
*/
#include "esp32/rom/uart.h"
#include "esp_rom_uart.h"
#include "task/task.h"
#include <stdint.h>
#include <stdbool.h>

View File

@ -1,7 +1,7 @@
#ifndef __I2C_SW_MASTER_H__
#define __I2C_SW_MASTER_H__
#include "esp32/rom/ets_sys.h"
#include "rom/ets_sys.h"
#define I2C_NUM_MAX 1

View File

@ -12,6 +12,13 @@ extern char _irom0_text_end;
#define RODATA_START_ADDRESS (&_irom0_text_start)
#define RODATA_END_ADDRESS (&_irom0_text_end)
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
extern char _rodata_start;
extern char _rodata_end;
#define RODATA_START_ADDRESS (&_rodata_start)
#define RODATA_END_ADDRESS (&_rodata_end)
#elif defined(__ESP32__) || defined(CONFIG_IDF_TARGET_ESP32)
#define RODATA_START_ADDRESS ((char*)0x3F400000)

View File

@ -444,5 +444,6 @@ LROT_PUBLIC_BEGIN(dblib)
LROT_END(dblib, NULL, 0)
LUALIB_API int luaopen_debug (lua_State *L) {
(void)L;
return 0;
}

View File

@ -422,13 +422,13 @@ static void put_byte (uint8_t value) {
}
static uint8_t recall_byte (uint offset) {
static uint8_t recall_byte (uint32_t offset) {
if(offset > DICTIONARY_WINDOW || offset >= out->ndx)
flash_error("invalid dictionary offset on inflate");
/* ndx starts at 1. Need relative to 0 */
uint n = out->ndx - offset;
uint pos = n % WRITE_BLOCKSIZE;
uint blockNo = out->ndx / WRITE_BLOCKSIZE - n / WRITE_BLOCKSIZE;
uint32_t n = out->ndx - offset;
uint32_t pos = n % WRITE_BLOCKSIZE;
uint32_t blockNo = out->ndx / WRITE_BLOCKSIZE - n / WRITE_BLOCKSIZE;
return out->block[blockNo]->byte[pos];
}
@ -462,7 +462,7 @@ int procFirstPass (void) {
fh->flash_size > flashSize ||
out->flagsLen != 1 + (out->flashLen/WORDSIZE - 1) / BITS_PER_WORD)
flash_error("LFS length mismatch");
out->flags = luaM_newvector(out->L, out->flagsLen, uint);
out->flags = luaM_newvector(out->L, out->flagsLen, uint32_t);
}
/* update running CRC */

View File

@ -54,26 +54,7 @@ int luaO_fb2int (int x) {
int luaO_log2 (unsigned int x) {
#ifdef LUA_CROSS_COMPILER
static const lu_byte log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
int l = -1;
while (x >= 256) { l += 8; x >>= 8; }
return l + log_2[x];
#else
/* Use Normalization Shift Amount Unsigned: 0x1=>31 up to 0xffffffff =>0
* See Xtensa Instruction Set Architecture (ISA) Refman P 462 */
asm volatile ("nsau %0, %1;" :"=r"(x) : "r"(x));
return 31 - x;
#endif
return 31 - __builtin_clz(x);
}

View File

@ -333,6 +333,7 @@ static Node *find_prev_node(Node *mp, Node *next) {
** (colliding node is in its main position), moving node goes to an empty position.
*/
static int move_node (lua_State *L, Table *t, Node *node) {
(void)L;
Node *mp = mainposition(t, key2tval(node));
/* if node is in it's main position, don't need to move node. */
if (mp == node) return 1;
@ -371,6 +372,7 @@ static int move_node (lua_State *L, Table *t, Node *node) {
static int move_number (lua_State *L, Table *t, Node *node) {
(void)L; (void)t;
int key;
lua_Number n = nvalue(key2tval(node));
lua_number2int(key, n);
@ -580,6 +582,7 @@ const TValue *luaH_getnum (Table *t, int key) {
/* same thing for rotables */
const TValue *luaH_getnum_ro (void *t, int key) {
(void)t; (void)key;
const TValue *res = NULL; // integer values not supported: luaR_findentryN(t, key, NULL);
return res ? res : luaO_nilobject;
}
@ -741,6 +744,7 @@ int luaH_getn (Table *t) {
/* same thing for rotables */
int luaH_getn_ro (void *t) {
(void)t;
return 0; // Integer Keys are not currently supported for ROTables
}

View File

@ -279,5 +279,6 @@ LROT_PUBLIC_BEGIN(tab_funcs)
LROT_END(tab_funcs, NULL, 0)
LUALIB_API int luaopen_table (lua_State *L) {
(void)L;
return 1;
}

View File

@ -266,6 +266,7 @@ static int runargs (lua_State *L, char **argv, int n) {
#endif
static int handle_luainit (lua_State *L) {
(void)dolfsfile; // silence warning about potentially unused function
const char *init = LUA_INIT_STRING;
if (init[0] == '@') {
#if CONFIG_NODEMCU_EMBEDDED_LFS_SIZE > 0

View File

@ -0,0 +1,49 @@
if(NOT "${IDF_TARGET}" STREQUAL "esp32c3")
# Globbing isn't recommended, but I dislike it less than having to edit
# this file whenever a new module source file springs into existence.
# Just remember to "idf.py reconfigure" (or do a clean build) to get
# cmake to pick up on the new (or removed) files.
file(
GLOB module_srcs
LIST_DIRECTORIES false
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
*.c
)
idf_component_register(
SRCS ${module_srcs}
PRIV_INCLUDE_DIRS "." "${CMAKE_CURRENT_BINARY_DIR}"
PRIV_REQUIRES
"base_nodemcu"
"driver"
"driver_can"
"sdmmc"
"esp_eth"
"lua"
"modules"
"platform"
"soc"
)
# Match up all the module source files with their corresponding Kconfig
# option in the form NODEMCU_CMODULE_<modname> and if enabled, add a
# "-u <modname>_module_selected1" option to force the linker to include
# the module. See components/core/include/module.h for further details on
# how this works.
set(modules_enabled)
foreach(module_src ${module_srcs})
string(REPLACE ".c" "" module_name ${module_src})
string(TOUPPER ${module_name} module_ucase)
set(mod_opt "CONFIG_NODEMCU_CMODULE_${module_ucase}")
if (${${mod_opt}})
list(APPEND modules_enabled ${module_ucase})
endif()
endforeach()
message("Including the following modules: ${modules_enabled}")
foreach(mod ${modules_enabled})
target_link_libraries(${COMPONENT_LIB} "-u ${mod}_module_selected1")
endforeach()
endif()

View File

@ -0,0 +1,49 @@
menu "NodeMCU modules (ESP32/ESP32-S specific)"
depends on IDF_TARGET != "ESP32C3"
config NODEMCU_CMODULE_CAN
bool "CAN module"
default "n"
help
Includes the can module.
config NODEMCU_CMODULE_DAC
bool "DAC module"
default "n"
help
Includes the dac module.
config NODEMCU_CMODULE_ETH
select ETH_USE_ESP32_EMAC
bool "Ethernet module"
default "n"
help
Includes the ethernet module.
config NODEMCU_CMODULE_I2S
bool "I2S module"
default "n"
help
Includes the I2S module.
config NODEMCU_CMODULE_PULSECNT
bool "Pulse counter module"
default "n"
help
Includes the pulse counter module to use ESP32's built-in pulse
counting hardware.
config NODEMCU_CMODULE_SDMMC
bool "SD-MMC module"
default "n"
help
Includes the sdmmc module.
config NODEMCU_CMODULE_TOUCH
bool "Touch module"
default "n"
help
Includes the touch module to use ESP32's built-in touch sensor
hardware.
endmenu

View File

@ -11,7 +11,7 @@ file(
idf_component_register(
SRCS ${module_srcs}
PRIV_INCLUDE_DIRS "." "${CMAKE_CURRENT_BINARY_DIR}"
INCLUDE_DIRS "." "${CMAKE_CURRENT_BINARY_DIR}"
PRIV_REQUIRES
"app_update"
"base_nodemcu"
@ -41,7 +41,6 @@ foreach(module_src ${module_srcs})
string(REPLACE ".c" "" module_name ${module_src})
string(TOUPPER ${module_name} module_ucase)
set(mod_opt "CONFIG_NODEMCU_CMODULE_${module_ucase}")
#message("checking ${mod_opt}")
if (${${mod_opt}})
list(APPEND modules_enabled ${module_ucase})
endif()

View File

@ -21,24 +21,12 @@ menu "NodeMCU modules"
help
Includes the simple BlueTooth HCI module.
config NODEMCU_CMODULE_CAN
bool "CAN module"
default "n"
help
Includes the can module.
config NODEMCU_CMODULE_CRYPTO
bool "Crypto module"
default "n"
help
Includes the crypto module.
config NODEMCU_CMODULE_DAC
bool "DAC module"
default "n"
help
Includes the dac module.
config NODEMCU_CMODULE_DHT
bool "DHT11/21/22/AM2301/AM2302 module"
default "n"
@ -52,12 +40,6 @@ menu "NodeMCU modules"
Includes the encoder module. This provides hex and base64 encoding
and decoding functionality.
config NODEMCU_CMODULE_ETH
bool "Ethernet module"
default "n"
help
Includes the ethernet module.
config NODEMCU_CMODULE_FILE
bool "File module"
default "y"
@ -82,12 +64,6 @@ menu "NodeMCU modules"
help
Includes the I2C module (recommended).
config NODEMCU_CMODULE_I2S
bool "I2S module"
default "n"
help
Includes the I2S module.
config NODEMCU_CMODULE_LEDC
bool "LEDC module"
default "n"
@ -126,13 +102,6 @@ menu "NodeMCU modules"
requires a partition table with at least two OTA partitions, plus
the OTA data partition. See the IDF documentation for details.
config NODEMCU_CMODULE_PULSECNT
bool "Pulse counter module"
default "n"
help
Includes the pulse counter module to use ESP32's built-in pulse
counting hardware.
config NODEMCU_CMODULE_QRCODEGEN
bool "QR Code Generator module"
default "n"
@ -140,12 +109,6 @@ menu "NodeMCU modules"
Includes the QR Code Generator from
https://www.nayuki.io/page/qr-code-generator-library
config NODEMCU_CMODULE_SDMMC
bool "SD-MMC module"
default "n"
help
Includes the sdmmc module.
config NODEMCU_CMODULE_SIGMA_DELTA
bool "Sigma-Delta module"
default "n"
@ -184,13 +147,6 @@ menu "NodeMCU modules"
help
Includes the timer module (recommended).
config NODEMCU_CMODULE_TOUCH
bool "Touch module"
default "n"
help
Includes the touch module to use ESP32's built-in touch sensor
hardware.
config NODEMCU_CMODULE_U8G2
bool "U8G2 module"
default "n"

View File

@ -252,7 +252,9 @@ LROT_END(ledc_channel, NULL, 0)
LROT_BEGIN(ledc)
LROT_FUNCENTRY( newChannel, lledc_new_channel )
#if SOC_LEDC_SUPPORT_HS_MODE
LROT_NUMENTRY ( HIGH_SPEED, LEDC_HIGH_SPEED_MODE )
#endif
LROT_NUMENTRY ( LOW_SPEED, LEDC_LOW_SPEED_MODE )
LROT_NUMENTRY ( TIMER_0, LEDC_TIMER_0 )
@ -263,7 +265,14 @@ LROT_BEGIN(ledc)
LROT_NUMENTRY ( TIMER_12_BIT, LEDC_TIMER_12_BIT )
LROT_NUMENTRY ( TIMER_13_BIT, LEDC_TIMER_13_BIT )
LROT_NUMENTRY ( TIMER_14_BIT, LEDC_TIMER_14_BIT )
#if SOC_LEDC_TIMER_BIT_WIDE_NUM > 14
LROT_NUMENTRY ( TIMER_15_BIT, LEDC_TIMER_15_BIT )
LROT_NUMENTRY ( TIMER_16_BIT, LEDC_TIMER_16_BIT )
LROT_NUMENTRY ( TIMER_17_BIT, LEDC_TIMER_17_BIT )
LROT_NUMENTRY ( TIMER_18_BIT, LEDC_TIMER_18_BIT )
LROT_NUMENTRY ( TIMER_19_BIT, LEDC_TIMER_19_BIT )
LROT_NUMENTRY ( TIMER_20_BIT, LEDC_TIMER_20_BIT )
#endif
LROT_NUMENTRY ( CHANNEL_0, LEDC_CHANNEL_0 )
LROT_NUMENTRY ( CHANNEL_1, LEDC_CHANNEL_1 )
@ -271,8 +280,10 @@ LROT_BEGIN(ledc)
LROT_NUMENTRY ( CHANNEL_3, LEDC_CHANNEL_3 )
LROT_NUMENTRY ( CHANNEL_4, LEDC_CHANNEL_4 )
LROT_NUMENTRY ( CHANNEL_5, LEDC_CHANNEL_5 )
#if SOC_LED_CHANNEL_NUM > 6
LROT_NUMENTRY ( CHANNEL_6, LEDC_CHANNEL_6 )
LROT_NUMENTRY ( CHANNEL_7, LEDC_CHANNEL_7 )
#endif
LROT_NUMENTRY ( IDLE_LOW, 0 )
LROT_NUMENTRY ( IDLE_HIGH, 1 )

View File

@ -20,71 +20,87 @@
// Lua: node.bootreason()
static int node_bootreason( lua_State *L)
{
int panicval = panic_get_nvval();
RESET_REASON rr0 = rtc_get_reset_reason(0);
unsigned rawinfo = 3;
// rawinfo can take these values as defined in docs/modules/node.md
//
// 1, power-on
// 2, reset (software?)
// 3, hardware reset via reset pin or unknown reason
// 4, WDT reset (watchdog timeout)
//
// extendedinfo can take these values as definded in docs/modules/node.md
//
// 0, power-on
// 1, hardware watchdog reset
// 2, exception reset
// 3, software watchdog reset
// 4, software restart
// 5, wake from deep sleep
// 6, external reset
// added values from rom/rtc.h with offset 7
// 7: NO_MEAN = 0,
// 8: POWERON_RESET = 1, /**<1, Vbat power on reset*/
// 9:
// 10: SW_RESET = 3, /**<3, Software reset digital core*/
// 11: OWDT_RESET = 4, /**<4, Legacy watch dog reset digital core*/
// 12: DEEPSLEEP_RESET = 5, /**<3, Deep Sleep reset digital core*/
// 13: SDIO_RESET = 6, /**<6, Reset by SLC module, reset digital core*/
// 14: TG0WDT_SYS_RESET = 7, /**<7, Timer Group0 Watch dog reset digital core*/
// 15: TG1WDT_SYS_RESET = 8, /**<8, Timer Group1 Watch dog reset digital core*/
// 16: RTCWDT_SYS_RESET = 9, /**<9, RTC Watch dog Reset digital core*/
// 17: INTRUSION_RESET = 10, /**<10, Instrusion tested to reset CPU*/
// 18: TGWDT_CPU_RESET = 11, /**<11, Time Group reset CPU*/
// 19: SW_CPU_RESET = 12, /**<12, Software reset CPU*/
// 20: RTCWDT_CPU_RESET = 13, /**<13, RTC Watch dog Reset CPU*/
// 21: EXT_CPU_RESET = 14, /**<14, for APP CPU, reseted by PRO CPU*/
// 22: RTCWDT_BROWN_OUT_RESET = 15, /**<15, Reset when the vdd voltage is not stable*/
// 23: RTCWDT_RTC_RESET = 16 /**<16, RTC Watch dog reset digital core and rtc module*/`
switch (rr0) {
case NO_MEAN: rawinfo = 3; break;
case POWERON_RESET: rawinfo = 1; break;
case SW_RESET: rawinfo = 2; break;
case OWDT_RESET: rawinfo = 4; break;
case DEEPSLEEP_RESET:
case SDIO_RESET:
case TG0WDT_SYS_RESET:
case TG1WDT_SYS_RESET:
rawinfo = 3; break;
case RTCWDT_SYS_RESET: rawinfo = 4; break;
case INTRUSION_RESET: rawinfo = 3; break;
case TGWDT_CPU_RESET: rawinfo = 4; break;
case SW_CPU_RESET: rawinfo = 2; break;
case RTCWDT_CPU_RESET: rawinfo = 4; break;
case EXT_CPU_RESET:
case RTCWDT_BROWN_OUT_RESET: rawinfo = 3; break;
case RTCWDT_RTC_RESET: rawinfo = 3; break;
}
lua_pushinteger(L, (lua_Integer)rawinfo);
lua_pushinteger(L, (lua_Integer)rr0+7);
if (rr0 == SW_CPU_RESET) {
lua_pushinteger(L, (lua_Integer)panicval);
return 3;
}
return 2;
int panicval = panic_get_nvval();
RESET_REASON rr0 = rtc_get_reset_reason(0);
unsigned rawinfo = 3;
// rawinfo can take these values as defined in docs/modules/node.md
//
// 1, power-on
// 2, reset (software?)
// 3, hardware reset via reset pin or unknown reason
// 4, WDT reset (watchdog timeout)
//
// extendedinfo can take these values as definded in docs/modules/node.md
//
// 0, power-on
// 1, hardware watchdog reset
// 2, exception reset
// 3, software watchdog reset
// 4, software restart
// 5, wake from deep sleep
// 6, external reset
// added values from rom/rtc.h with offset 7
// 7: NO_MEAN = 0,
// 8: POWERON_RESET = 1, /**<1, Vbat power on reset*/
// 9:
// 10: SW_RESET = 3, /**<3, Software reset digital core*/
// 11: OWDT_RESET = 4, /**<4, Legacy watch dog reset digital core*/
// 12: DEEPSLEEP_RESET = 5, /**<3, Deep Sleep reset digital core*/
// 13: SDIO_RESET = 6, /**<6, Reset by SLC module, reset digital core*/
// 14: TG0WDT_SYS_RESET = 7, /**<7, Timer Group0 Watch dog reset digital core*/
// 15: TG1WDT_SYS_RESET = 8, /**<8, Timer Group1 Watch dog reset digital core*/
// 16: RTCWDT_SYS_RESET = 9, /**<9, RTC Watch dog Reset digital core*/
// 17: INTRUSION_RESET = 10, /**<10, Instrusion tested to reset CPU*/
// 18: TGWDT_CPU_RESET = 11, /**<11, Time Group reset CPU*/
// 19: SW_CPU_RESET = 12, /**<12, Software reset CPU*/
// 20: RTCWDT_CPU_RESET = 13, /**<13, RTC Watch dog Reset CPU*/
// 21: EXT_CPU_RESET = 14, /**<14, for APP CPU, reseted by PRO CPU*/
// 22: RTCWDT_BROWN_OUT_RESET = 15, /**<15, Reset when the vdd voltage is not stable*/
// 23: RTCWDT_RTC_RESET = 16 /**<16, RTC Watch dog reset digital core and rtc module*/`
#if defined(CONFIG_IDF_TARGET_ESP32C3)
# define SW_CPU_RESET RTC_SW_CPU_RESET
# define SW_RESET RTC_SW_SYS_RESET
#endif
switch (rr0) {
case POWERON_RESET:
rawinfo = 1; break;
case SW_CPU_RESET:
case SW_RESET:
rawinfo = 2; break;
case NO_MEAN:
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
case EXT_CPU_RESET:
#endif
case DEEPSLEEP_RESET:
case SDIO_RESET:
case TG0WDT_SYS_RESET:
case TG1WDT_SYS_RESET:
case INTRUSION_RESET:
case RTCWDT_BROWN_OUT_RESET:
case RTCWDT_RTC_RESET:
rawinfo = 3; break;
#if defined(CONFIG_IDF_TARGET_ESP32C3)
case TG0WDT_CPU_RESET:
case TG1WDT_CPU_RESET:
case SUPER_WDT_RESET:
#else
case OWDT_RESET:
case TGWDT_CPU_RESET:
#endif
case RTCWDT_CPU_RESET:
case RTCWDT_SYS_RESET:
rawinfo = 4; break;
}
lua_pushinteger(L, (lua_Integer)rawinfo);
lua_pushinteger(L, (lua_Integer)rr0+7);
if (rr0 == SW_CPU_RESET) {
lua_pushinteger(L, (lua_Integer)panicval);
return 3;
}
return 2;
}
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
// Lua: node.chipid()
static int node_chipid( lua_State *L )
{
@ -101,7 +117,7 @@ static int node_chipid( lua_State *L )
lua_pushstring(L, chipid);
return 1;
}
#endif
// Lua: node.heap()
static int node_heap( lua_State* L )
@ -200,6 +216,7 @@ static int node_sleep (lua_State *L)
esp_sleep_enable_timer_wakeup(usecs);
}
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
// touch option: boolean
if (opt_checkbool(L, "touch", false)) {
int err = esp_sleep_enable_touchpad_wakeup();
@ -215,6 +232,7 @@ static int node_sleep (lua_State *L)
return luaL_error(L, "Error %d returned from esp_sleep_enable_ulp_wakeup()", err);
}
}
#endif
int err = esp_light_sleep_start();
if (err == ESP_ERR_INVALID_STATE) {
@ -271,10 +289,8 @@ static int node_dsleep (lua_State *L)
}
}
int level = opt_checkint_range(L, "level", 1, 0, 1);
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
bool pull = opt_checkbool(L, "pull", false);
bool touch = opt_checkbool(L, "touch", false);
if (opt_get(L, "isolate", LUA_TTABLE)) {
for (int i = 1; ; i++) {
lua_rawgeti(L, -1, i);
@ -297,6 +313,7 @@ static int node_dsleep (lua_State *L)
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
}
int level = opt_checkint_range(L, "level", 1, 0, 1);
if (pin_mask) {
esp_sleep_ext1_wakeup_mode_t mode = (level == 1) ?
ESP_EXT1_WAKEUP_ANY_HIGH : ESP_EXT1_WAKEUP_ALL_LOW;
@ -306,9 +323,11 @@ static int node_dsleep (lua_State *L)
}
}
bool touch = opt_checkbool(L, "touch", false);
if (touch) {
esp_sleep_enable_touchpad_wakeup();
}
#endif
} else {
luaL_argerror(L, 1, "Expected integer or table");
@ -708,7 +727,9 @@ LROT_END(node_wakeup, NULL, 0)
LROT_BEGIN(node)
LROT_FUNCENTRY( bootreason, node_bootreason )
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
LROT_FUNCENTRY( chipid, node_chipid )
#endif
LROT_FUNCENTRY( compile, node_compile )
LROT_FUNCENTRY( dsleep, node_dsleep )
LROT_TABENTRY ( egc, node_egc )

View File

@ -10,9 +10,14 @@
LROT_BEGIN(lspi)
LROT_FUNCENTRY( master, lspi_master )
// LROT_FUNCENTRY( slave, lspi_slave )
#if defined(CONFIG_IDF_TARGET_ESP32)
LROT_NUMENTRY( SPI, SPI_HOST )
LROT_NUMENTRY( HSPI, HSPI_HOST )
LROT_NUMENTRY( VSPI, VSPI_HOST )
#endif
LROT_NUMENTRY( SPI1, SPI1_HOST )
LROT_NUMENTRY( SPI2, SPI2_HOST )
LROT_NUMENTRY( SPI3, SPI3_HOST )
LROT_END(lspi, NULL, 0)
int luaopen_spi( lua_State *L ) {

View File

@ -219,7 +219,7 @@ int lspi_master( lua_State *L )
int host = luaL_checkint( L, ++stack );
luaL_argcheck( L,
host == SPI_HOST || host == HSPI_HOST || host == VSPI_HOST,
host == SPI1_HOST || host == SPI2_HOST || host == SPI2_HOST,
stack,
"invalid host" );

View File

@ -7,10 +7,8 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "esp32/rom/spi_flash.h"
#include "rom/spi_flash.h"
#include "platform_wdt.h"
#include "esp_image_format.h"
#include "esp_flash_partitions.h"

View File

@ -123,6 +123,7 @@ void platform_uart_flush( unsigned id );
int platform_uart_start( unsigned id );
void platform_uart_stop( unsigned id );
int platform_uart_get_config(unsigned id, uint32_t *baudp, uint32_t *databitsp, uint32_t *parityp, uint32_t *stopbitsp);
int platform_uart_set_wakeup_threshold(unsigned id, unsigned threshold);
// *****************************************************************************

View File

@ -193,12 +193,16 @@ static int onewire_rmt_attach_pin( uint8_t gpio_num )
return PLATFORM_ERR;
if (gpio_num != ow_rmt.gpio) {
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
// attach GPIO to previous pin
if (gpio_num < 32) {
GPIO.enable_w1ts = (0x1 << gpio_num);
} else {
GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32));
}
#else
GPIO.enable_w1ts.val = (0x1 << gpio_num);
#endif
if (ow_rmt.gpio >= 0) {
gpio_matrix_out( ow_rmt.gpio, SIG_GPIO_OUT_IDX, 0, 0 );
}

View File

@ -3,11 +3,12 @@
#include "driver/sigmadelta.h"
#include "driver/adc.h"
#include "driver/uart.h"
#include "soc/uart_reg.h"
#include <stdio.h>
#include <string.h>
#include <freertos/semphr.h>
#include "lua.h"
#include "rom/uart.h"
#include "esp_log.h"
int platform_init (void)
@ -72,7 +73,7 @@ void uart_event_task( task_param_t param, task_prio_t prio ) {
}
free(post->data);
} else {
char *err;
const char *err;
switch(post->type) {
case PLATFORM_UART_EVENT_OOM:
err = "out_of_memory";
@ -305,6 +306,8 @@ void platform_uart_flush( unsigned id )
{
if (id == CONSOLE_UART)
fflush (stdout);
else
uart_tx_flush(id);
}
@ -360,7 +363,7 @@ int platform_uart_get_config(unsigned id, uint32_t *baudp, uint32_t *databitsp,
if (err != ESP_OK) return -1;
*baudp &= 0xFFFFFFFE; // round down
uint32_t databits;
uart_word_length_t databits;
err = uart_get_word_length(id, &databits);
if (err != ESP_OK) return -1;
@ -381,15 +384,34 @@ int platform_uart_get_config(unsigned id, uint32_t *baudp, uint32_t *databitsp,
return -1;
}
err = uart_get_parity(id, parityp);
uart_parity_t parity;
err = uart_get_parity(id, &parity);
if (err != ESP_OK) return -1;
switch(parity) {
case UART_PARITY_DISABLE: *parityp = PLATFORM_UART_PARITY_NONE; break;
case UART_PARITY_EVEN: *parityp = PLATFORM_UART_PARITY_EVEN; break;
case UART_PARITY_ODD: *parityp = PLATFORM_UART_PARITY_ODD; break;
}
err = uart_get_stop_bits(id, stopbitsp);
uart_stop_bits_t stopbits;
err = uart_get_stop_bits(id, &stopbits);
if (err != ESP_OK) return -1;
switch(stopbits) {
case UART_STOP_BITS_1: *stopbitsp = PLATFORM_UART_STOPBITS_1; break;
case UART_STOP_BITS_1_5: *stopbitsp = PLATFORM_UART_STOPBITS_1_5; break;
case UART_STOP_BITS_2: *stopbitsp = PLATFORM_UART_STOPBITS_2; break;
case UART_STOP_BITS_MAX: break;
}
return 0;
}
int platform_uart_set_wakeup_threshold(unsigned id, unsigned threshold)
{
esp_err_t err = uart_set_wakeup_threshold(id, threshold);
return (err == ESP_OK) ? 0 : -1;
}
// *****************************************************************************
// Sigma-Delta platform interface
@ -478,9 +500,16 @@ int platform_adc_channel_exists( uint8_t adc, uint8_t channel ) {
}
uint8_t platform_adc_set_width( uint8_t adc, int bits ) {
(void)adc;
#if defined(CONFIG_IDF_TARGET_ESP32C3)
if (bits != SOC_ADC_MAX_BITWIDTH)
return 0;
bits = SOC_ADC_MAX_BITWIDTH;
#else
bits = bits - 9;
if (bits < ADC_WIDTH_9Bit || bits > ADC_WIDTH_12Bit)
return 0;
#endif
if (ESP_OK != adc1_config_width( bits ))
return 0;
@ -501,8 +530,12 @@ int platform_adc_read( uint8_t adc, uint8_t channel ) {
}
int platform_adc_read_hall_sensor( ) {
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
int value = hall_sensor_read( );
return value;
#else
return -1;
#endif
}
// *****************************************************************************
// I2C platform interface

View File

@ -1,16 +1,11 @@
#include <string.h>
#include "esp32/rom/ets_sys.h"
#include "u8x8_nodemcu_hal.h"
#include "platform.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "driver/spi_master.h"
#include "platform.h"
#include "u8x8_nodemcu_hal.h"
#include "rom/ets_sys.h"
#include "esp_heap_caps.h"
#include <string.h>
uint8_t u8x8_gpio_and_delay_nodemcu(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)

View File

@ -29,7 +29,7 @@
#include "driver/rmt.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "soc/periph_defs.h"
#undef WS2812_DEBUG
@ -104,7 +104,11 @@ static void ws2812_isr(void *arg)
RMT.int_clr.val = BIT(channel+24);
ws2812_chain_t *chain = &(ws2812_chains[channel]);
#if defined(CONFIG_IDF_TARGET_ESP32C3)
uint32_t data_sub_len = RMT.tx_lim[channel].limit/8;
#else
uint32_t data_sub_len = RMT.tx_lim_ch[channel].limit/8;
#endif
if (chain->len >= data_sub_len) {
ws2812_fill_memory_encoded( channel, chain->data, data_sub_len, chain->tx_offset );

View File

@ -81,7 +81,8 @@ bool IRAM_ATTR task_post_isr(task_prio_t priority, task_handle_t handle, task_pa
BaseType_t woken = pdFALSE;
xSemaphoreGiveFromISR (pending, &woken);
portYIELD_FROM_ISR(woken);
if (woken == pdTRUE)
portYIELD_FROM_ISR();
return res;
}

View File

@ -18,7 +18,7 @@
#define uz_malloc malloc
#define uz_free free
#if defined(__XTENSA__)
#if defined(__XTENSA__) || defined(CONFIG_IDF_TARGET_ESP32C3)
#define UZLIB_THROW(v) longjmp(unwindAddr, (v))
#define UZLIB_SETJMP setjmp

View File

@ -22,6 +22,8 @@
*
* - I have replaced the various mix of char, unsigned char and uchar
* by the single uchar type; ditto for ushort and uint.
* [Addendum: this was later switch to standard uintX_t types in order
* to not conflict with RISCV system headers, which also defined uint]
*
* - All internal (non-exported) functions and data are static
*
@ -109,16 +111,12 @@ jmp_buf unwindAddr;
#define SIZE(a) (sizeof(a)/sizeof(*a)) /* no of elements in array */
#ifdef __XTENSA__
#define RAM_COPY_BYTE_ARRAY(c,s,sl) uchar *c = alloca(sl); memcpy(c,s,(sl))
#define RAM_COPY_BYTE_ARRAY(c,s,sl) uint8_t *c = alloca(sl); memcpy(c,s,(sl))
#else
#define RAM_COPY_BYTE_ARRAY(c,s,sl) uchar *c = s;
#define RAM_COPY_BYTE_ARRAY(c,s,sl) uint8_t *c = s;
#endif
#define FREE(v) if (v) uz_free(v)
typedef uint8_t uchar;
typedef uint16_t ushort;
typedef uint32_t uint;
#ifdef DEBUG_COUNTS
#define DBG_PRINT(...) printf(__VA_ARGS__)
#define DBG_COUNT(n) (debugCounts[n]++)
@ -133,27 +131,27 @@ int debugCounts[20];
int dbg_break(void) {return 1;}
typedef struct {
ushort code, extraBits, min, max;
uint16_t code, extraBits, min, max;
} codeRecord;
struct dynTables {
ushort *hashChain;
ushort *hashTable;
ushort hashMask;
ushort hashSlots;
ushort hashBits;
ushort dictLen;
const uchar bitrevNibble[16];
uint16_t *hashChain;
uint16_t *hashTable;
uint16_t hashMask;
uint16_t hashSlots;
uint16_t hashBits;
uint16_t dictLen;
const uint8_t bitrevNibble[16];
const codeRecord lenCodes[285-257+1];
const codeRecord distCodes[29-0+1];
} *dynamicTables;
struct outputBuf {
uchar *buffer;
uint len, size;
uint inLen, inNdx;
uint bits, nBits;
uint compDisabled;
uint8_t *buffer;
uint32_t len, size;
uint32_t inLen, inNdx;
uint32_t bits, nBits;
uint32_t compDisabled;
} *oBuf;
@ -190,12 +188,12 @@ struct outputBuf {
#define distCodes_LEN 30
#define BITREV16 "\x0\x8\x4\xc\x2\xa\x6\xe\x1\x9\x5\xd\x3\xb\x7\xf"
static void genCodeRecs (const codeRecord *rec, ushort len,
char *init, int initLen,
ushort start, ushort m0) {
static void genCodeRecs (const codeRecord *rec, uint16_t len,
const char *init, int initLen,
uint16_t start, uint16_t m0) {
DBG_COUNT(0);
int i, b=0, m=0, last=m0;
RAM_COPY_BYTE_ARRAY(c, (uchar *)init,initLen);
RAM_COPY_BYTE_ARRAY(c, (uint8_t *)init,initLen);
codeRecord *p = (codeRecord *) rec;
for (i = start; i < start+len; i++, c++) {
@ -206,12 +204,12 @@ static void genCodeRecs (const codeRecord *rec, ushort len,
}
}
static void initTables (uint chainLen, uint hashSlots) {
static void initTables (uint32_t chainLen, uint32_t hashSlots) {
DBG_COUNT(1);
uint dynamicSize = sizeof(struct dynTables) +
uint32_t dynamicSize = sizeof(struct dynTables) +
sizeof(struct outputBuf) +
chainLen * sizeof(ushort) +
hashSlots * sizeof(ushort);
chainLen * sizeof(uint16_t) +
hashSlots * sizeof(uint16_t);
struct dynTables *dt = uz_malloc(dynamicSize);
memset(dt, 0, dynamicSize);
dynamicTables = dt;
@ -220,17 +218,17 @@ static void initTables (uint chainLen, uint hashSlots) {
if(!dt )
UZLIB_THROW(UZLIB_MEMORY_ERROR);
memcpy((uchar*)dt->bitrevNibble, BITREV16, 16);
memcpy((uint8_t*)dt->bitrevNibble, BITREV16, 16);
oBuf = (struct outputBuf *)(dt+1);
dt->hashTable = (ushort *)(oBuf+1);
dt->hashTable = (uint16_t *)(oBuf+1);
dt->hashChain = dt->hashTable + hashSlots;
dt->hashSlots = hashSlots;
dt->hashMask = hashSlots - 1;
/* As these are offset rather than pointer, 0 is a valid offset */
/* (unlike NULL), so 0xFFFF is used to denote an unset value */
memset(dt->hashTable, -1, sizeof(ushort)*hashSlots);
memset(dt->hashChain, -1, sizeof(ushort)*chainLen);
memset(dt->hashTable, -1, sizeof(uint16_t)*hashSlots);
memset(dt->hashChain, -1, sizeof(uint16_t)*chainLen);
/* Generate the code recors for the lenth and distance code tables */
genCodeRecs(dt->lenCodes, SIZE(dt->lenCodes),
@ -247,7 +245,7 @@ static void initTables (uint chainLen, uint hashSlots) {
* Routines to output bit streams and byte streams to the output buffer
*/
void resizeBuffer(void) {
uchar *nb;
uint8_t *nb;
DBG_COUNT(2);
/* The outbuf is given an initial size estimate but if we are running */
/* out of space then extropolate size using current compression */
@ -258,7 +256,7 @@ void resizeBuffer(void) {
oBuf->buffer = nb;
}
void outBits(ushort bits, int nBits) {
void outBits(uint16_t bits, int nBits) {
DBG_COUNT(3);
oBuf->bits |= bits << oBuf->nBits;
oBuf->nBits += nBits;
@ -274,10 +272,10 @@ void outBits(ushort bits, int nBits) {
}
}
void outBitsRev(uchar bits, int nBits) {
void outBitsRev(uint8_t bits, int nBits) {
DBG_COUNT(4);
/* Note that bit reversal only operates on an 8-bit bits field */
uchar bitsRev = (dynamicTables->bitrevNibble[bits & 0x0f]<<4) |
uint8_t bitsRev = (dynamicTables->bitrevNibble[bits & 0x0f]<<4) |
dynamicTables->bitrevNibble[bits>>4];
outBits(bitsRev, nBits);
}
@ -292,15 +290,15 @@ void outBytes(void *bytes, int nBytes) {
/* flush this first, if necessary */
oBuf->nBits = oBuf->bits = 0;
for (i = 0; i < nBytes; i++) {
DBG_PRINT("%02x-", *((uchar*)bytes+i));
oBuf->buffer[oBuf->len++] = *((uchar*)bytes+i);
DBG_PRINT("%02x-", *((uint8_t*)bytes+i));
oBuf->buffer[oBuf->len++] = *((uint8_t*)bytes+i);
}
}
/*
* Output an literal byte as an 8 or 9 bit code
*/
void literal (uchar c) {
void literal (uint8_t c) {
DBG_COUNT(6);
DBG_PRINT("sym: %02x %c\n", c, c);
if (oBuf->compDisabled) {
@ -414,19 +412,19 @@ void copy (int distance, int len) {
* constraints of the ESP8266), the chainList is 16K slots long, and the
* hashTable is 4K slots long, so a typical chain will have 4 links.
*
* These two tables use 16-bit ushort offsets rather than pointers to
* These two tables use 16-bit uint16_t offsets rather than pointers to
* save memory (essential on the ESP8266).
*
* As per RFC 1951 sec 4, we also implement a "lazy match" procedure
*/
void uzlibCompressBlock(const uchar *src, uint srcLen) {
void uzlibCompressBlock(const uint8_t *src, uint32_t srcLen) {
int i, j, k, l;
uint hashMask = dynamicTables->hashMask;
ushort *hashChain = dynamicTables->hashChain;
ushort *hashTable = dynamicTables->hashTable;
uint hashShift = 24 - dynamicTables->hashBits;
uint lastOffset = 0, lastLen = 0;
uint32_t hashMask = dynamicTables->hashMask;
uint16_t *hashChain = dynamicTables->hashChain;
uint16_t *hashTable = dynamicTables->hashTable;
uint32_t hashShift = 24 - dynamicTables->hashBits;
uint32_t lastOffset = 0, lastLen = 0;
oBuf->inLen = srcLen; /* used for output buffer resizing */
DBG_COUNT(9);
@ -438,22 +436,22 @@ void uzlibCompressBlock(const uchar *src, uint srcLen) {
*
* Note that using 16-bit offsets requires a little manipulation to
* handle wrap-around and recover the correct offset, but all other
* working uses uint offsets simply because the compiler generates
* working uses uint32_t offsets simply because the compiler generates
* faster (and smaller in the case of the ESP8266) code.
*
* Also note that this code also works for any tail 2 literals; the
* hash will access beyond the array and will be incorrect, but
* these can't match and will flush the last cache.
*/
const uchar *this = src + i, *comp;
uint base = i & ~OFFSET16_MASK;
uint iOffset = i - base;
uint maxLen = srcLen - i;
uint matchLen = MIN_MATCH - 1;
uint matchOffset = 0;
uint v = (this[0] << 16) | (this[1] << 8) | this[2];
uint hash = ((v >> hashShift) - v) & hashMask;
uint nextOffset = hashTable[hash];
const uint8_t *this = src + i, *comp;
uint32_t base = i & ~OFFSET16_MASK;
uint32_t iOffset = i - base;
uint32_t maxLen = srcLen - i;
uint32_t matchLen = MIN_MATCH - 1;
uint32_t matchOffset = 0;
uint32_t v = (this[0] << 16) | (this[1] << 8) | this[2];
uint32_t hash = ((v >> hashShift) - v) & hashMask;
uint32_t nextOffset = hashTable[hash];
oBuf->inNdx = i; /* used for output buffer resizing */
DBG_COUNT(10);
@ -525,14 +523,14 @@ void uzlibCompressBlock(const uchar *src, uint srcLen) {
* This compress wrapper treats the input stream as a single block for
* compression using the default Static huffman block encoding
*/
int uzlib_compress (uchar **dest, uint *destLen, const uchar *src, uint srcLen) {
uint crc = ~uzlib_crc32(src, srcLen, ~0);
uint chainLen = srcLen < MAX_OFFSET ? srcLen : MAX_OFFSET;
uint hashSlots, i, j;
int uzlib_compress (uint8_t **dest, uint32_t *destLen, const uint8_t *src, uint32_t srcLen) {
uint32_t crc = ~uzlib_crc32(src, srcLen, ~0);
uint32_t chainLen = srcLen < MAX_OFFSET ? srcLen : MAX_OFFSET;
uint32_t hashSlots, i, j;
int status;
uint FLG_MTIME[] = {0x00088b1f, 0};
ushort XFL_OS = 0x0304;
uint32_t FLG_MTIME[] = {0x00088b1f, 0};
uint16_t XFL_OS = 0x0304;
/* The hash table has 4K slots for a 16K chain and scaling down */
/* accordingly, for an average chain length of 4 links or thereabouts */
@ -571,7 +569,7 @@ int uzlib_compress (uchar **dest, uint *destLen, const uchar *src, uint srcLen)
for (i=0; i<20;i++) DBG_PRINT("count %u = %u\n",i,debugCounts[i]);
if (status == UZLIB_OK) {
uchar *trimBuf = realloc(oBuf->buffer, oBuf->len);
uint8_t *trimBuf = realloc(oBuf->buffer, oBuf->len);
*dest = trimBuf ? trimBuf : oBuf->buffer;
*destLen = oBuf->len;
} else {

View File

@ -61,29 +61,25 @@ int debugCounts[20];
jmp_buf unwindAddr;
int dbg_break(void) {return 1;}
typedef uint8_t uchar;
typedef uint16_t ushort;
typedef uint32_t uint;
/* data structures */
typedef struct {
ushort table[16]; /* table of code length counts */
ushort trans[288]; /* code -> symbol translation table */
uint16_t table[16]; /* table of code length counts */
uint16_t trans[288]; /* code -> symbol translation table */
} UZLIB_TREE;
struct uzlib_data {
/*
* extra bits and base tables for length and distance codes
*/
uchar lengthBits[30];
ushort lengthBase[30];
uchar distBits[30];
ushort distBase[30];
uint8_t lengthBits[30];
uint16_t lengthBase[30];
uint8_t distBits[30];
uint16_t distBase[30];
/*
* special ordering of code length codes
*/
uchar clcidx[19];
uint8_t clcidx[19];
/*
* dynamic length/symbol and distance trees
*/
@ -92,20 +88,20 @@ struct uzlib_data {
/*
* methods encapsulate handling of the input and output streams
*/
uchar (*get_byte)(void);
void (*put_byte)(uchar b);
uchar (*recall_byte)(uint offset);
uint8_t (*get_byte)(void);
void (*put_byte)(uint8_t b);
uint8_t (*recall_byte)(uint32_t offset);
/*
* Other state values
*/
uint destSize;
uint tag;
uint bitcount;
uint lzOffs;
uint32_t destSize;
uint32_t tag;
uint32_t bitcount;
uint32_t lzOffs;
int bType;
int bFinal;
uint curLen;
uint checksum;
uint32_t curLen;
uint32_t checksum;
};
/*
@ -134,14 +130,14 @@ static uint16_t get_uint16(UZLIB_DATA *d) {
return v | (d->get_byte() << 8);
}
static uint get_le_uint32 (UZLIB_DATA *d) {
uint v = get_uint16(d);
return v | ((uint) get_uint16(d) << 16);
static uint32_t get_le_uint32 (UZLIB_DATA *d) {
uint32_t v = get_uint16(d);
return v | ((uint32_t) get_uint16(d) << 16);
}
/* get one bit from source stream */
static int getbit (UZLIB_DATA *d) {
uint bit;
uint32_t bit;
/* check if tag is empty */
if (!d->bitcount--) {
@ -158,14 +154,14 @@ static int getbit (UZLIB_DATA *d) {
}
/* read a num bit value from a stream and add base */
static uint read_bits (UZLIB_DATA *d, int num, int base) {
static uint32_t read_bits (UZLIB_DATA *d, int num, int base) {
/* This is an optimised version which doesn't call getbit num times */
if (!num)
return base;
uint i, n = (((uint)-1)<<num);
uint32_t i, n = (((uint32_t)-1)<<num);
for (i = d->bitcount; i < num; i +=8)
d->tag |= ((uint)d->get_byte()) << i;
d->tag |= ((uint32_t)d->get_byte()) << i;
n = d->tag & ~n;
d->tag >>= num;
@ -198,7 +194,7 @@ static uint read_bits (UZLIB_DATA *d, int num, int base) {
* ----------------------- */
/* build extra bits and base tables */
static void build_bits_base (uchar *bits, ushort *base,
static void build_bits_base (uint8_t *bits, uint16_t *base,
int delta, int first) {
int i, sum;
@ -237,9 +233,9 @@ static void build_fixed_trees (UZLIB_TREE *lt, UZLIB_TREE *dt) {
}
/* given an array of code lengths, build a tree */
static void build_tree (UZLIB_TREE *t, const uchar *lengths, uint num) {
ushort offs[16];
uint i, sum;
static void build_tree (UZLIB_TREE *t, const uint8_t *lengths, uint32_t num) {
uint16_t offs[16];
uint32_t i, sum;
/* clear code length count table */
for (i = 0; i < 16; ++i)
@ -292,9 +288,9 @@ static int decode_symbol (UZLIB_DATA *d, UZLIB_TREE *t) {
/* given a data stream, decode dynamic trees from it */
static int decode_trees (UZLIB_DATA *d, UZLIB_TREE *lt, UZLIB_TREE *dt) {
uchar lengths[288+32];
uint hlit, hdist, hclen, hlimit;
uint i, num, length;
uint8_t lengths[288+32];
uint32_t hlit, hdist, hclen, hlimit;
uint32_t i, num, length;
/* get 5 bits HLIT (257-286) */
hlit = read_bits(d, 5, 257);
@ -310,7 +306,7 @@ static int decode_trees (UZLIB_DATA *d, UZLIB_TREE *lt, UZLIB_TREE *dt) {
/* read code lengths for code length alphabet */
for (i = 0; i < hclen; ++i) {
/* get 3 bits code length (0-7) */
uint clen = read_bits(d, 3, 0);
uint32_t clen = read_bits(d, 3, 0);
lengths[d->clcidx[i]] = clen;
}
@ -321,7 +317,7 @@ static int decode_trees (UZLIB_DATA *d, UZLIB_TREE *lt, UZLIB_TREE *dt) {
hlimit = hlit + hdist;
for (num = 0; num < hlimit; ) {
int sym = decode_symbol(d, lt);
uchar fill_value = 0;
uint8_t fill_value = 0;
int lbits, lbase = 3;
/* error decoding */
@ -398,7 +394,7 @@ static int inflate_block_data (UZLIB_DATA *d, UZLIB_TREE *lt, UZLIB_TREE *dt) {
}
/* copy next byte from dict substring */
uchar b = d->recall_byte(d->lzOffs);
uint8_t b = d->recall_byte(d->lzOffs);
DBG_PRINT("huff dict byte(%u): -%u - %02x %c\n\n",
d->curLen, d->lzOffs, b, b);
d->put_byte(b);
@ -409,8 +405,8 @@ static int inflate_block_data (UZLIB_DATA *d, UZLIB_TREE *lt, UZLIB_TREE *dt) {
/* inflate an uncompressed block of data */
static int inflate_uncompressed_block (UZLIB_DATA *d) {
if (d->curLen == 0) {
uint length = get_uint16(d);
uint invlength = get_uint16(d);
uint32_t length = get_uint16(d);
uint32_t invlength = get_uint16(d);
/* check length */
if (length != (~invlength & 0x0000ffff))
@ -445,7 +441,7 @@ static int parse_gzip_header(UZLIB_DATA *d) {
if (d->get_byte() != 8) /* check method is deflate */
return UZLIB_DATA_ERROR;
uchar flg = d->get_byte();/* get flag byte */
uint8_t flg = d->get_byte();/* get flag byte */
if (flg & 0xe0)/* check that reserved bits are zero */
return UZLIB_DATA_ERROR;
@ -537,18 +533,18 @@ static int uncompress_stream (UZLIB_DATA *d) {
* three support routines to handle the streaming:
*
* void get_byte(void)
* void put_byte(uchar b)
* uchar recall_byte(uint offset)
* void put_byte(uint8_t b)
* uint8_t recall_byte(uint32_t offset)
*
* This last must be able to recall an output byte with an offet up to
* the maximum dictionary size.
*/
int uzlib_inflate (
uchar (*get_byte)(void),
void (*put_byte)(uchar v),
uchar (*recall_byte)(uint offset),
uint len, uint *crc, void **state) {
uint8_t (*get_byte)(void),
void (*put_byte)(uint8_t v),
uint8_t (*recall_byte)(uint32_t offset),
uint32_t len, uint32_t *crc, void **state) {
int res;
/* initialize decompression structure */