Merge remote-tracking branch 'upstream/master'

Conflicts:
	core/newlib_syscalls.c
This commit is contained in:
Johan Kanflo 2015-10-26 11:39:11 +01:00
commit 8f6c297849
35 changed files with 452 additions and 307 deletions

View file

@ -6,4 +6,20 @@
(c-file-style . "bsd")
(c-basic-offset . 4)
)
(asm-mode
(indent-tabs-mode . nil)
; this is basically a hack so asm-mode indents with spaces not tabs
; taken from http://stackoverflow.com/questions/2668563/emacs-indentation-in-asm-mode
; (moving to gas-mode may be a better choice)
(tab-stop-list (quote (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120)))
(asm-comment-char . "#")
)
)
; IMPORTANT: If you want to write assembly and have indenting to not be infuriating,
; you probably also want this in your .emacs file:
;
; (add-hook 'asm-mode-hook '(lambda () (setq indent-line-function 'indent-relative)))
;
; This is not safe to set as a local variable.

View file

@ -198,6 +198,8 @@ portBASE_TYPE xPortStartScheduler( void )
}
/* Initialize system tick timer interrupt and schedule the first tick. */
_xt_isr_attach(INUM_TICK, sdk__xt_timer_int);
_xt_isr_unmask(BIT(INUM_TICK));
sdk__xt_tick_timer_init();
vTaskSwitchContext();
@ -265,60 +267,3 @@ void IRAM vPortExitCritical( void )
portENABLE_INTERRUPTS();
}
/*-----------------------------------------------------------*/
/* Main ISR handler for FreeRTOS side of the ESP libs?
As far as I can tell, the "real" Xtensa ISRs ("Exceptions") are
handled in libmain.a (xtensa_vectors.o) which then can call into here
passing an interrupt mask.
*/
_xt_isr isr[16];
void IRAM _xt_isr_attach(uint8_t i, _xt_isr func)
{
isr[i] = func;
}
uint16_t IRAM _xt_isr_handler(uint16_t i)
{
uint8_t index;
/* I think this is implementing some kind of interrupt priority or
short-circuiting an expensive ffs for most common interrupts - ie
WDT And GPIO are common or high priority, then remaining flags.
*/
if (i & (1 << INUM_WDT)) {
index = INUM_WDT;
}
else if (i & (1 << INUM_GPIO)) {
index = INUM_GPIO;
}else {
index = __builtin_ffs(i) - 1;
if (index == INUM_MAX) {
/* I don't understand what happens here. INUM_MAX is not
the highest interrupt number listed (and the isr array
has 16 entries).
Clearing that flag and then setting index to
__builtin_ffs(i)-1 may result in index == 255 if no
higher flags are set, unless this is guarded against
somehow by the caller?
I also don't understand why the code is written like
this in esp_iot_rtos_sdk instead of just putting the i
&= line near the top... Probably no good reason?
*/
i &= ~(1 << INUM_MAX);
index = __builtin_ffs(i) - 1;
}
}
_xt_clear_ints(1<<index);
isr[index]();
return i & ~(1 << index);
}

View file

@ -73,8 +73,8 @@ extern "C" {
#include "esp8266.h"
#include "espressif/esp8266/ets_sys.h"
#include <stdint.h>
#include "xtensa_rtos.h"
#include "xtensa_interrupts.h"
#include "xtensa_rtos.h"
#include <esp/interrupts.h>
/*-----------------------------------------------------------
* Port specific definitions for ESP8266

View file

@ -134,7 +134,17 @@ The best way to write suitable code is to first add documentation somewhere like
## Coding Style
For new contributions, please use BSD style and indent using 4 spaces. If you're an emacs user then there is a .dir-locals.el file in the root which configures cc-mode.
For new contributions in C, please use BSD style and indent using 4 spaces.
For assembly, please use the following:
* Instructions indented using 8 spaces.
* Inline comments use `#` as a comment delimiter.
* Comments on their own line(s) use `/*`..`*/`.
* First operand of each instruction should be vertically aligned where possible.
* For xtensa special registers, prefer `wsr aX, SR` over `wsr.SR aX`
If you're an emacs user then there is a .dir-locals.el file in the root which configures cc-mode and asm-mode (you will need to approve some variable values as safe). See also
the additional comments in .dir-locals.el, if you're editing assembly code.
Upstream code is left with the indentation and style of the upstream project.

View file

@ -16,8 +16,8 @@
#include "common_macros.h"
#include "xtensa_ops.h"
#include "esp/rom.h"
#include "esp/uart.h"
#include "esp/iomux_regs.h"
#include "esp/uart_regs.h"
#include "esp/spi_regs.h"
#include "esp/dport_regs.h"
#include "esp/wdev_regs.h"
@ -30,7 +30,6 @@
void user_init(void);
#define UART_DIVISOR 1068 // 74906 bps (yeah, I don't understand it either)
#define BOOT_INFO_SIZE 28
//TODO: phy_info should probably be a struct (no idea about its organization, though)
#define PHY_INFO_SIZE 128
@ -82,8 +81,6 @@ xTaskHandle sdk_xWatchDogTaskHandle;
static void IRAM get_otp_mac_address(uint8_t *buf);
static void IRAM set_spi0_divisor(uint32_t divisor);
static int IRAM default_putc(char c);
static void IRAM default_putc1(char c);
static void zero_bss(void);
static void init_networking(uint8_t *phy_info, uint8_t *mac_addr);
static void init_g_ic(void);
@ -160,27 +157,15 @@ void IRAM sdk_user_fatal_exception_handler(void) {
Cache_Read_Disable();
Cache_Read_Enable(0, 0, 1);
dump_excinfo();
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS)) {}
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(1).STATUS)) {}
uart_flush_txfifo(0);
uart_flush_txfifo(1);
sdk_system_restart_in_nmi();
halt();
}
// .Lfunc003 -- .text+0x1d0
static int IRAM default_putc(char c) {
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 125) {}
UART(0).FIFO = c;
return 0;
}
// .Lfunc004 -- .text+0x1f4
static void IRAM default_putc1(char c) {
if (c == '\n') {
default_putc('\r');
} else if (c == '\r') {
return;
}
default_putc(c);
static void IRAM default_putc(char c) {
uart_putc(0, c);
}
// .text+0x258
@ -247,7 +232,7 @@ void IRAM sdk_user_start(void) {
sdk_SPIRead(ic_flash_addr, buf32, sizeof(struct sdk_g_ic_saved_st));
Cache_Read_Enable(0, 0, 1);
zero_bss();
sdk_os_install_putc1(default_putc1);
sdk_os_install_putc1(default_putc);
if (cksum_magic == 0xffffffff) {
// No checksum required
} else if ((cksum_magic == 0x55aa55aa) &&
@ -293,8 +278,8 @@ static void init_networking(uint8_t *phy_info, uint8_t *mac_addr) {
printf("FATAL: sdk_register_chipv6_phy failed");
halt();
}
sdk_uart_div_modify(0, UART_DIVISOR);
sdk_uart_div_modify(1, UART_DIVISOR);
uart_set_baud(0, 74906);
uart_set_baud(1, 74906);
sdk_phy_disable_agc();
sdk_ieee80211_phy_init(sdk_g_ic.s.phy_mode);
sdk_lmacInit();
@ -378,15 +363,6 @@ static void dump_excinfo(void) {
sdk_system_rtc_mem_write(0, excinfo, 32);
}
// .irom0.text+0x368
int sdk_uart_rx_one_char(char *buf) {
if (FIELD2VAL(UART_STATUS_RXFIFO_COUNT, UART(0).STATUS)) {
*buf = UART(0).FIFO;
return 0;
}
return 1;
}
// .irom0.text+0x398
void sdk_wdt_init(void) {
WDT.CTRL &= ~WDT_CTRL_ENABLE;
@ -455,9 +431,11 @@ static void user_start_phase2(void) {
phy_info = malloc(PHY_INFO_SIZE);
sdk_spi_flash_read(sdk_flashchip.chip_size - sdk_flashchip.sector_size * 4, (uint32_t *)phy_info, PHY_INFO_SIZE);
// Disable default buffering on stdout
setbuf(stdout, NULL);
// Wait for UARTs to finish sending anything in their queues.
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 0) {}
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(1).STATUS) > 0) {}
uart_flush_txfifo(0);
uart_flush_txfifo(1);
if (phy_info[0] != 5) {
// Bad version byte. Discard what we read and use default values

39
core/esp_interrupts.c Normal file
View file

@ -0,0 +1,39 @@
/* ESP8266 Xtensa interrupt management functions
*
*
* Part of esp-open-rtos
* Copyright (C) 2015 Angus Gratton
* BSD Licensed as described in the file LICENSE
*/
#include <esp/interrupts.h>
_xt_isr isr[16];
void IRAM _xt_isr_attach(uint8_t i, _xt_isr func)
{
isr[i] = func;
}
/* Generic ISR handler.
Handles all flags set for interrupts in 'intset'.
*/
uint16_t IRAM _xt_isr_handler(uint16_t intset)
{
/* WDT has highest priority (occasional WDT resets otherwise) */
if(intset & BIT(INUM_WDT)) {
_xt_clear_ints(BIT(INUM_WDT));
isr[INUM_WDT]();
intset -= BIT(INUM_WDT);
}
while(intset) {
uint8_t index = __builtin_ffs(intset) - 1;
uint16_t mask = BIT(index);
_xt_clear_ints(mask);
isr[index]();
intset -= mask;
}
return 0;
}

View file

@ -25,12 +25,19 @@
.section .bss
NMIHandlerStack: # stack space for NMI handler
.skip 4*0x100
.LNMIHandlerStackTop:
NMIRegisterSaved: # register space for saving NMI registers
.skip 4*(16 + 6)
/* Stack space for NMI handler
NMI handler stack high water mark measured at 0x134 bytes. Any use
of the NMI timer callback will add stack overhead as well.
The NMI handler does a basic check for stack overflow
*/
.balign 16
NMIHandlerStack:
.skip 0x200
.NMIHandlerStackTop:
.balign 16
LoadStoreErrorHandlerStack:
.word 0 # a0
.word 0 # (unused)
@ -67,10 +74,7 @@ DebugExceptionVector:
.org VecBase + 0x20
NMIExceptionVector:
.type NMIExceptionVector, @function
wsr a0, excsave3
call0 CallNMIExceptionHandler
rfi 3 # Should never be reached
j NMIExceptionHandler
.org VecBase + 0x30
KernelExceptionVector:
@ -371,96 +375,103 @@ call_user_start:
/*************************** NMI Exception Handler ***************************/
#define NMI_STACK_CANARY 0xABBABABA
.section .vecbase.text, "x"
/* Save register relative to a0 */
.macro SAVE_REG register, regnum
s32i \register, a0, (4 * (\regnum + 6))
.endm
/* Load register relative to sp */
.macro LOAD_REG register, regnum
l32i \register, sp, (4 * (\regnum + 6))
.endm
.literal_position
.balign 16
CallNMIExceptionHandler:
.type CallNMIExceptionHandler, @function
NMIExceptionHandler:
.type NMIExceptionHandler, @function
movi a0, NMIRegisterSaved
SAVE_REG a2, 2
SAVE_REG sp, 1
SAVE_REG a3, 3
rsr a2, excsave3 # a2 is now former a0
SAVE_REG a4, 4
SAVE_REG a2, 0
rsr a3, epc1
rsr a4, exccause
SAVE_REG a3, -5
SAVE_REG a4, -4
rsr a3, excvaddr
SAVE_REG a3, -3
rsr a3, excsave1
SAVE_REG a3, -2
SAVE_REG a5, 5
SAVE_REG a6, 6
SAVE_REG a7, 7
SAVE_REG a8, 8
SAVE_REG a9, 9
SAVE_REG a10, 10
SAVE_REG a11, 11
SAVE_REG a12, 12
SAVE_REG a13, 13
SAVE_REG a14, 14
SAVE_REG a15, 15
movi sp, .LNMIHandlerStackTop
movi a0, 0
movi a2, 0x23 # argument for handler
wsr a2, ps
wsr sp, excsave3 # excsave3 holds user stack
movi sp, .NMIHandlerStackTop - 0x40
s32i a0, sp, 0x00
s32i a2, sp, 0x04
s32i a3, sp, 0x08
s32i a4, sp, 0x0c
s32i a5, sp, 0x10
s32i a6, sp, 0x14
s32i a7, sp, 0x18
s32i a8, sp, 0x1c
s32i a9, sp, 0x20
s32i a10, sp, 0x24
s32i a11, sp, 0x28
rsr a0, epc1
s32i a0, sp, 0x2c
rsr a0, exccause
s32i a0, sp, 0x30
rsr a0, excsave1
s32i a0, sp, 0x34
rsr a0, excvaddr
s32i a0, sp, 0x38
rsr a0, sar
s32i a0, sp, 0x3c
movi a0, 0x23 # Override PS for NMI handler
wsr a0, ps
rsync
rsr a14, sar
s32i a14, sp, 0 # this is also NMIRegisterSaved+0
/* mark the stack overflow point before we call the actual NMI handler */
movi a0, NMIHandlerStack
movi a2, NMI_STACK_CANARY
s32i a2, a0, 0x00
call0 sdk_wDev_ProcessFiq
l32i a15, sp, 0
wsr a15, sar
movi a2, 0x33
wsr a2, ps
/* verify we didn't overflow */
movi a0, NMIHandlerStack
l32i a3, a0, 0
movi a2, NMI_STACK_CANARY
bne a3, a2, .NMIFatalStackOverflow
l32i a0, sp, 0x3c
wsr a0, sar
l32i a0, sp, 0x38
wsr a0, excvaddr
l32i a0, sp, 0x34
wsr a0, excsave1
l32i a0, sp, 0x30
wsr a0, exccause
l32i a0, sp, 0x2c
wsr a0, epc1
l32i a11, sp, 0x28
l32i a10, sp, 0x24
l32i a9, sp, 0x20
l32i a8, sp, 0x1c
l32i a7, sp, 0x18
l32i a6, sp, 0x14
l32i a5, sp, 0x10
l32i a4, sp, 0x0c
l32i a3, sp, 0x08
movi a0, 0x33 # Reset PS
wsr a0, ps
rsync
LOAD_REG a4, 4
LOAD_REG a5, 5
LOAD_REG a6, 6
LOAD_REG a7, 7
LOAD_REG a8, 8
LOAD_REG a9, 9
LOAD_REG a10, 10
LOAD_REG a11, 11
LOAD_REG a12, 12
LOAD_REG a13, 13
LOAD_REG a14, 14
LOAD_REG a15, 15
LOAD_REG a2, -5
LOAD_REG a3, -4
wsr a2, epc1
wsr a3, exccause
LOAD_REG a2, -3
LOAD_REG a3, -2
wsr a2, excvaddr
wsr a3, excsave1
LOAD_REG a0, 0
/* set dport nmi status bit 0 (wDev_ProcessFiq clears & verifies this
* bit stays cleared, see
/* set dport nmi status to 1 (wDev_ProcessFiq clears bit 0 and verifies it
* stays cleared, see
* http://esp8266-re.foogod.com/wiki/WDev_ProcessFiq_%28IoT_RTOS_SDK_0.9.9%29)
*/
movi a2, 0x3ff00000
movi a3, 0x1
s32i a3, a2, 0
LOAD_REG a2, 2
LOAD_REG a3, 3
LOAD_REG a1, 1
movi a0, 0x3ff00000
movi a2, 0x1
s32i a2, a0, 0
l32i a2, sp, 0x04
l32i a0, sp, 0x00
movi a1, 0x0
xsr a1, excsave3 # Load stack back from excsave3, clear excsave3
rfi 3
.section .rodata
.NMIStackOverflowErrorMsg:
.string "\nFATAL: NMI Stack Overflow\n"
.section .vecbase.text, "x"
.NMIFatalStackOverflow:
movi a2, .NMIStackOverflowErrorMsg
call0 printf
.NMIInfiniteLoop:
j .NMIInfiniteLoop /* TODO: replace with call to abort() */
/*********************** General UserException Handler ***********************/
.section .vecbase.text, "x"
@ -469,7 +480,6 @@ CallNMIExceptionHandler:
* LoadStoreCause. */
.literal_position
.balign 4
UserExceptionHandler:
.type UserExceptionHandler, @function
@ -490,46 +500,28 @@ UserExceptionHandler:
wsr a0, ps
rsync
rsr a2, exccause
beqi a2, CAUSE_LVL1INT, UserHandleInterrupt
/* Any UserException cause other than level 1 interrupt should panic */
UserFailOtherExceptionCause:
break 1, 1
call0 sdk_user_fatal_exception_handler
UserHandleInterrupt:
/* Any UserException cause other than a level 1 interrupt is fatal */
bnei a2, CAUSE_LVL1INT, .LUserFailOtherExceptionCause
.LUserHandleInterrupt:
rsil a0, 1
rsr a2, intenable
rsr a3, interrupt
movi a4, 0x3fff
and a2, a2, a3
and a2, a2, a4 # a2 = 0x3FFF & INTENABLE & INTERRUPT
UserHandleTimer:
movi a3, 0xffbf
and a3, a2, a3 # a3 = a2 with bit 6 cleared
bnez a3, UserTimerDone # If any non-timer interrupt bits set
movi a3, 0x40
sub a12, a2, a3 # a12 = a2 - 0x40 -- Will be zero if bit 6 set
call0 sdk__xt_timer_int # tick timer interrupt
mov a2, a12 # restore a2 from a12, ie zero
beqz a2, UserIntDone
UserTimerDone:
and a2, a2, a4 # a2 = 0x3FFF & INTENABLE & INTERRUPT
call0 _xt_isr_handler
bnez a2, UserHandleTimer
UserIntDone:
beqz a2, UserIntExit
/* FIXME: this code will never be reached */
call0 sdk__xt_int_exit # once finished, jumps to _xt_user_exit via stack
.literal_position
.LUserFailOtherExceptionCause:
break 1, 1
call0 sdk_user_fatal_exception_handler
UserIntExit:
call0 sdk__xt_int_exit # jumps to _xt_user_exit. Never returns here
.section .text
/* _xt_user_exit is used to exit interrupt context. */
/* TODO: Find a better place for this to live. */
/* _xt_user_exit is pushed onto the stack as part of the user exception handler,
restores same set registers which were saved there and returns from exception */
_xt_user_exit:
.global _xt_user_exit
.type _xt_user_exit, @function
l32i a0, sp, 0x8
wsr a0, ps
l32i a0, sp, 0x4
@ -538,4 +530,3 @@ _xt_user_exit:
l32i sp, sp, 0x10
rsync
rfe

View file

@ -1,33 +0,0 @@
/* esp/cpu.h
*
* Details relating to the ESP8266 Xtensa core.
*
*/
#ifndef _ESP_CPU_H
#define _ESP_CPU_H
#include <stdbool.h>
/* Interrupt numbers for level 1 exception handler.
*
* Currently the UserExceptionVector calls down to _xt_isr_handler,
* defined in port.c, for at least some of these interrupts. Some are handled
* on the SDK side, though.
*/
typedef enum {
INUM_SPI = 2,
INUM_GPIO = 4,
INUM_UART = 5,
INUM_MAX = 6, /* in some places this is documented as timer0 CCOMPARE0 interrupt */
INUM_SOFT = 7,
INUM_WDT = 8,
INUM_TIMER_FRC1 = 9,
/* FRC2 default handler. Configured by sdk_ets_timer_init, which
runs as part of default libmain.a startup code, assigns
interrupt handler to sdk_vApplicationTickHook+0x68
*/
INUM_TIMER_FRC2 = 10,
} xt_isr_num_t;
#endif

View file

@ -11,8 +11,7 @@
#include <stdbool.h>
#include "esp/gpio_regs.h"
#include "esp/iomux.h"
#include "esp/cpu.h"
#include "xtensa_interrupts.h"
#include "esp/interrupts.h"
typedef enum {
GPIO_INPUT,

View file

@ -1,4 +1,4 @@
/* Xtensa interrupt management functions
/* ESP8266 Xtensa interrupt management functions
*
* Some (w/ sdk_ prefix) are implemented in binary libs, rest are
* inlines replacing functions in the binary libraries.
@ -15,9 +15,27 @@
#include <xtensa/hal.h>
#include <common_macros.h>
/* Interrupt numbers for level 1 exception handler. */
typedef enum {
INUM_SPI = 2,
INUM_GPIO = 4,
INUM_UART = 5,
INUM_TICK = 6, /* RTOS timer tick, possibly xtensa CPU CCOMPARE0(?) */
INUM_SOFT = 7,
INUM_WDT = 8,
INUM_TIMER_FRC1 = 9,
/* FRC2 default handler. Configured by sdk_ets_timer_init, which
runs as part of default libmain.a startup code, assigns
interrupt handler to sdk_vApplicationTickHook+0x68
*/
INUM_TIMER_FRC2 = 10,
} xt_isr_num_t;
void sdk__xt_int_exit (void);
void _xt_user_exit (void);
void sdk__xt_tick_timer_init (void);
void sdk__xt_timer_int(void);
void sdk__xt_timer_int1(void);
INLINED uint32_t _xt_get_intlevel(void)

View file

@ -10,9 +10,8 @@
#define _ESP_TIMER_H
#include <stdbool.h>
#include <xtensa_interrupts.h>
#include "esp/timer_regs.h"
#include "esp/cpu.h"
#include "esp/interrupts.h"
#ifdef __cplusplus
extern "C" {

127
core/include/esp/uart.h Normal file
View file

@ -0,0 +1,127 @@
/** esp/uart.h
*
* Utility routines for working with UARTs
*
* Part of esp-open-rtos
* Copyright (C) 2015 Superhouse Automation Pty Ltd
* BSD Licensed as described in the file LICENSE
*/
#ifndef _ESP_UART_H
#define _ESP_UART_H
#include "esp/types.h"
#include "esp/uart_regs.h"
#include "esp/clocks.h"
#define UART_FIFO_MAX 127
/* Wait for at least `min_count` bytes of data to be available in the UART's
* receive FIFO
*
* Returns the number of bytes actually available for reading.
*/
static inline int uart_rxfifo_wait(int uart_num, int min_count) {
int count;
do {
count = FIELD2VAL(UART_STATUS_RXFIFO_COUNT, UART(uart_num).STATUS);
} while (count < min_count);
return count;
}
/* Wait for at least `min_count` bytes of space to be available in the UART's
* transmit FIFO
*
* Returns the number of bytes actually available in the write buffer.
*/
static inline int uart_txfifo_wait(int uart_num, int min_count) {
int count;
do {
count = UART_FIFO_MAX - FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(uart_num).STATUS);
} while (count < min_count);
return count;
}
/* Read a character from the UART. Block until a character is available for
* reading.
*
* Returns the character read.
*/
static inline int uart_getc(int uart_num) {
uart_rxfifo_wait(uart_num, 1);
return UART(uart_num).FIFO;
}
/* Read a character from the UART. Does not block.
*
* Returns the read character on success. If the RX FIFO is currently empty
* (nothing to read), returns -1.
*/
static inline int uart_getc_nowait(int uart_num) {
if (FIELD2VAL(UART_STATUS_RXFIFO_COUNT, UART(uart_num).STATUS)) {
return UART(uart_num).FIFO;
}
return -1;
}
/* Write a character to the UART. Blocks if necessary until there is space in
* the TX FIFO.
*/
static inline void uart_putc(int uart_num, char c) {
uart_txfifo_wait(uart_num, 1);
UART(uart_num).FIFO = c;
}
/* Write a character to the UART. Does not block.
*
* Returns 0 on success. If there is no space currently in the TX FIFO,
* returns -1.
*/
static inline int uart_putc_nowait(int uart_num, char c) {
if (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(uart_num).STATUS) < UART_FIFO_MAX) {
UART(uart_num).FIFO = c;
return 0;
}
return -1;
}
/* Clear (discard) all pending write data in the TX FIFO */
static inline void uart_clear_txfifo(int uart_num) {
uint32_t conf = UART(uart_num).CONF0;
UART(uart_num).CONF0 = conf | UART_CONF0_TXFIFO_RESET;
UART(uart_num).CONF0 = conf & ~UART_CONF0_TXFIFO_RESET;
}
/* Clear (discard) all pending read data in the RX FIFO */
static inline void uart_clear_rxfifo(int uart_num) {
uint32_t conf = UART(uart_num).CONF0;
UART(uart_num).CONF0 = conf | UART_CONF0_RXFIFO_RESET;
UART(uart_num).CONF0 = conf & ~UART_CONF0_RXFIFO_RESET;
}
/* Wait until all pending output in the UART's TX FIFO has been sent out the
* serial port. */
static inline void uart_flush_txfifo(int uart_num) {
while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(uart_num).STATUS) != 0) {}
}
/* Flush all pending input in the UART's RX FIFO
* (this is just another name for uart_clear_rxfifo)
*/
static inline void uart_flush_rxfifo(int uart_num) {
uart_clear_rxfifo(uart_num);
}
/* Set uart baud rate to the desired value */
static inline void uart_set_baud(int uart_num, int bps)
{
uint32_t divider = APB_CLK_FREQ / bps;
UART(uart_num).CLOCK_DIVIDER = divider;
}
/* Returns the current baud rate for the UART */
static inline int uart_get_baud(int uart_num)
{
return APB_CLK_FREQ / FIELD2VAL(UART_CLOCK_DIVIDER_VALUE, UART(uart_num).CLOCK_DIVIDER);
}
#endif /* _ESP_UART_H */

View file

@ -13,7 +13,7 @@
#include "common_macros.h"
#include "esp/registers.h"
#include "esp/cpu.h"
#include "esp/interrupts.h"
#include "esp/iomux.h"
#include "esp/gpio.h"
#include "esp/timer.h"

View file

@ -9,6 +9,7 @@
#include <sys/errno.h>
#include <espressif/sdk_private.h>
#include <common_macros.h>
#include <esp/uart.h>
#include <stdlib.h>
IRAM caddr_t _sbrk_r (struct _reent *r, int incr)
@ -32,38 +33,40 @@ IRAM caddr_t _sbrk_r (struct _reent *r, int incr)
return (caddr_t) prev_heap_end;
}
/* syscall implementation for stdio write to UART
at the moment UART functionality is all still in the binary SDK
*/
/* syscall implementation for stdio write to UART */
long _write_r(struct _reent *r, int fd, const char *ptr, int len )
{
if(fd != r->_stdout->_file) {
r->_errno = EBADF;
return -1;
}
for(int i = 0; i < len; i++)
sdk_os_putc(ptr[i]);
for(int i = 0; i < len; i++) {
/* Auto convert CR to CRLF, ignore other LFs (compatible with Espressif SDK behaviour) */
if(ptr[i] == '\r')
continue;
if(ptr[i] == '\n')
uart_putc(0, '\r');
uart_putc(0, ptr[i]);
}
return len;
}
/* syscall implementation for stdio read from UART
at the moment UART functionality is all still in the binary SDK
but there is support for IRQ driven UART0 RX in extras/serial-driver
*/
long __attribute__((weak)) _read_r( struct _reent *r, int fd, char *ptr, int len )
/* syscall implementation for stdio read from UART */
long _read_r( struct _reent *r, int fd, char *ptr, int len )
{
int ch, i;
if(fd != r->_stdin->_file) {
r->_errno = EBADF;
return -1;
}
for(int i = 0; i < len; i++) {
char ch;
while (sdk_uart_rx_one_char(&ch)) ;
uart_rxfifo_wait(0, 1);
for(i = 0; i < len; i++) {
ch = uart_getc_nowait(0);
if (ch < 0) break;
ptr[i] = ch;
}
return len;
return i;
}
/* Stub syscall implementations follow, to allow compiling newlib functions that

View file

@ -1,5 +1,5 @@
/*
* Wrappers for functions called by binary espressif libraries
* Compatibility routines for the Espressif SDK and its API
*
* Part of esp-open-rtos
* Copyright (C) 2015 Superhouse Automation Pty Ltd
@ -10,6 +10,8 @@
#include <stdio.h>
#include <common_macros.h>
#include <esp/uart.h>
void IRAM *zalloc(size_t nbytes)
{
return calloc(1, nbytes);
@ -18,9 +20,8 @@ void IRAM *zalloc(size_t nbytes)
extern void (*__init_array_start)(void);
extern void (*__init_array_end)(void);
/* Do things which should be done as part of the startup code, but aren't.
Can be replaced with _start() once we have open source startup code.
/* Do things which should be done as part of the SDK startup code, but aren't.
TODO: Move into app_main.c
*/
void sdk_compat_initialise()
{
@ -29,3 +30,15 @@ void sdk_compat_initialise()
for ( p = &__init_array_start; p != &__init_array_end; ++p)
(*p)();
}
/* UART RX function from Espressif SDK internals.
*
* Not part of published API.
*/
int sdk_uart_rx_one_char(char *buf) {
int c = uart_getc_nowait(0);
if(c < 0)
return 1;
*buf = (char)c;
return 0;
}

View file

@ -3,7 +3,7 @@
* This sample code is in the public domain.
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"
@ -53,7 +53,7 @@ void blinkenRegisterTask(void *pvParameters)
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
xTaskCreate(blinkenTask, (signed char *)"blinkenTask", 256, NULL, 2, NULL);
//xTaskCreate(blinkenRegisterTask, (signed char *)"blinkenRegisterTask", 256, NULL, 2, NULL);
}

View file

@ -3,7 +3,7 @@
* This sample code is in the public domain.
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"
@ -33,7 +33,7 @@ void frc2_interrupt_handler(void)
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
/* configure GPIOs */
gpio_enable(gpio_frc1, GPIO_OUTPUT);

View file

@ -3,7 +3,7 @@
* This sample code is in the public domain.
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
@ -87,7 +87,7 @@ void bmp180_task(void *pvParameters)
void user_setup(void)
{
// Set UART Parameter
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
// Give the UART some time to settle
sdk_os_delay_us(500);

View file

@ -6,7 +6,7 @@
* This sample code is in the public domain.
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
@ -75,7 +75,7 @@ void GPIO_HANDLER(void)
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
gpio_enable(gpio, GPIO_INPUT);
tsqueue = xQueueCreate(2, sizeof(uint32_t));

View file

@ -31,6 +31,8 @@
#include "espressif/esp_common.h"
#include "esp/uart.h"
/******************************************************************************************************************
* task_1_t
*
@ -94,8 +96,8 @@ esp_open_rtos::thread::queue_t<uint32_t> MyQueue;
*/
extern "C" void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
MyQueue.queue_create(10);
task_1.queue = MyQueue;

View file

@ -7,7 +7,7 @@
* This experimental reverse engineering code is in the public domain.
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"
@ -118,7 +118,7 @@ void frc2_handler(void)
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
xTaskCreate(timerRegTask, (signed char *)"timerRegTask", 1024, NULL, 2, NULL);
TIMER(0).CTRL = VAL2FIELD(TIMER_CTRL_CLKDIV, TIMER_CLKDIV_256) | TIMER_CTRL_RELOAD;

View file

@ -3,7 +3,7 @@
#include "esp/rom.h"
#include "esp/timer.h"
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
@ -214,7 +214,7 @@ void sanity_tests(void);
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
gpio_enable(2, GPIO_OUTPUT); /* used for LED debug */
gpio_write(2, 1); /* active low */

View file

@ -5,7 +5,7 @@
* This sample code is in the public domain.,
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include <string.h>
@ -114,7 +114,7 @@ void http_get_task(void *pvParameters)
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version());
struct sdk_station_config config = {

View file

@ -10,7 +10,7 @@
* Additions Copyright (C) 2015 Angus Gratton, Apache 2.0 License.
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include <string.h>
@ -80,7 +80,6 @@ static void my_debug(void *ctx, int level,
file = file_sep+1;
printf("%s:%04d: %s", file, line, str);
fflush(stdout);
}
#endif
@ -107,7 +106,6 @@ void http_get_task(void *pvParameters)
mbedtls_x509_crt_init(&cacert);
mbedtls_ctr_drbg_init(&ctr_drbg);
printf("\n . Seeding the random number generator...");
fflush(stdout);
mbedtls_ssl_config_init(&conf);
@ -126,7 +124,6 @@ void http_get_task(void *pvParameters)
* 0. Initialize certificates
*/
printf(" . Loading the CA root certificate ...");
fflush(stdout);
ret = mbedtls_x509_crt_parse(&cacert, (uint8_t*)server_root_cert, strlen(server_root_cert)+1);
if(ret < 0)
@ -148,7 +145,6 @@ void http_get_task(void *pvParameters)
* 2. Setup stuff
*/
printf(" . Setting up the SSL/TLS structure...");
fflush(stdout);
if((ret = mbedtls_ssl_config_defaults(&conf,
MBEDTLS_SSL_IS_CLIENT,
@ -182,7 +178,6 @@ void http_get_task(void *pvParameters)
our network is probably working...
*/
printf("Waiting for server DNS to resolve... ");
fflush(stdout);
err_t dns_err;
ip_addr_t host_ip;
do {
@ -198,7 +193,6 @@ void http_get_task(void *pvParameters)
* 1. Start the connection
*/
printf(" . Connecting to %s:%s...", WEB_SERVER, WEB_PORT);
fflush(stdout);
if((ret = mbedtls_net_connect(&server_fd, WEB_SERVER,
WEB_PORT, MBEDTLS_NET_PROTO_TCP)) != 0)
@ -215,7 +209,6 @@ void http_get_task(void *pvParameters)
* 4. Handshake
*/
printf(" . Performing the SSL/TLS handshake...");
fflush(stdout);
while((ret = mbedtls_ssl_handshake(&ssl)) != 0)
{
@ -251,7 +244,6 @@ void http_get_task(void *pvParameters)
* 3. Write the GET request
*/
printf(" > Write to server:");
fflush(stdout);
int len = sprintf((char *) buf, GET_REQUEST);
@ -271,7 +263,6 @@ void http_get_task(void *pvParameters)
* 7. Read the HTTP response
*/
printf(" < Read from server:");
fflush(stdout);
do
{
@ -322,7 +313,6 @@ void http_get_task(void *pvParameters)
printf("\n\nsuccesses = %d failures = %d\n", successes, failures);
for(int countdown = successes ? 10 : 5; countdown >= 0; countdown--) {
printf("%d... ", countdown);
fflush(stdout);
vTaskDelay(1000 / portTICK_RATE_MS);
}
printf("\nStarting again!\n");
@ -331,7 +321,7 @@ void http_get_task(void *pvParameters)
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version());
struct sdk_station_config config = {

View file

@ -7,7 +7,7 @@
* NOT SUITABLE TO PUT ON THE INTERNET OR INTO A PRODUCTION ENVIRONMENT!!!!
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"
@ -18,7 +18,7 @@
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
rboot_config_t conf = rboot_get_config();
printf("\r\n\r\nOTA Basic demo.\r\nCurrently running on flash slot %d / %d.\r\n\r\n",

View file

@ -0,0 +1,3 @@
# Simple makefile for serial_echo example
PROGRAM=serial_echo
include ../../common.mk

View file

@ -0,0 +1,42 @@
/* Extremely simple example that just reads from stdin and echoes back on stdout
*
* Has an easter egg, which is if you type "QUACK" it'll quack 3 times back at you.
*
* This example code is in the public domain
*/
#include "espressif/esp_common.h"
#include <esp/uart.h>
#include <string.h>
void user_init(void)
{
uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version());
printf("Going into echo mode...\n");
/* By default stdout is line-buffered, so you only see output
after a newline is sent. This is helpful in a multithreaded
environment so output doesn't get chopped up within a line.
Here we want to see the echo immediately, so disable buffering.
*/
setbuf(stdout, NULL);
while(1) {
int c = getchar();
if(c != EOF)
putchar(c);
/* Easter egg: check for a quack! */
static int quack;
if(c == "QUACK"[quack]) {
quack++;
if(quack == strlen("QUACK")) {
printf("\nQUACK\nQUACK\n");
quack = 0;
}
} else {
quack = 0;
}
}
}

View file

@ -1,7 +1,7 @@
/* Very basic example that just demonstrates we can run at all!
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
@ -36,7 +36,7 @@ static xQueueHandle mainqueue;
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version());
mainqueue = xQueueCreate(10, sizeof(uint32_t));
xTaskCreate(task1, (signed char *)"tsk1", 256, &mainqueue, 2, NULL);

View file

@ -3,11 +3,12 @@
This sample code is in the public domain.
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include <esp/uart.h>
class Counter
{
private:
@ -58,7 +59,7 @@ void task1(void *pvParameters)
extern "C" void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version());
xTaskCreate(task1, (signed char *)"tsk1", 256, NULL, 2, NULL);
}

View file

@ -8,7 +8,7 @@
* This sample code is in the public domain.,
*/
#include "espressif/esp_common.h"
#include "espressif/sdk_private.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "mbedtls/md.h"
@ -130,7 +130,7 @@ static void test_md5(void)
void user_init(void)
{
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
uart_set_baud(0, 115200);
test_md5();

View file

@ -31,7 +31,7 @@
/* Optional reentrant struct support. Used mostly on platforms with
very restricted storage. */
/* #undef _WANT_REENT_SMALL */
#define _WANT_REENT_SMALL 1
/* Multibyte supported */
/* #undef _MB_CAPABLE */

View file

@ -188,6 +188,8 @@
#ifdef __XTENSA__
#include <xtensa/config/core-isa.h>
#define MALLOC_ALIGNMENT ((XCHAL_DATA_WIDTH) < 16 ? 16 : (XCHAL_DATA_WIDTH))
/* esp8266-specific: shrink the default fd buffer size */
#define __BUFSIZ__ 128
#endif
/* This block should be kept in sync with GCC's limits.h. The point

Binary file not shown.

Binary file not shown.

Binary file not shown.