├── .gitignore ├── License ├── Makefile ├── README.md ├── driver └── uart.c ├── include └── driver │ ├── uart.h │ └── uart_register.h └── user ├── user_config.h └── user_main.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x6e/ESP8266-RTC-Example/5812f6b4a6dd3ce89a291993b39a2cfca7a0da06/License -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for ESP8266 projects 2 | # 3 | # Thanks to: 4 | # - zarya 5 | # - Jeroen Domburg (Sprite_tm) 6 | # - Christian Klippel (mamalala) 7 | # - Tommie Gannert (tommie) 8 | # 9 | # Changelog: 10 | # - 2014-10-06: Changed the variables to include the header file directory 11 | # - 2014-10-06: Added global var for the Xtensa tool root 12 | # - 2014-11-23: Updated for SDK 0.9.3 13 | # - 2014-12-25: Replaced esptool by esptool.py 14 | 15 | # Output directors to store intermediate compiled files 16 | # relative to the project directory 17 | BUILD_BASE = build 18 | FW_BASE = firmware 19 | 20 | # base directory for the compiler 21 | XTENSA_TOOLS_ROOT ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin 22 | 23 | # base directory of the ESP8266 SDK package, absolute 24 | SDK_BASE ?= /opt/Espressif/ESP8266_SDK 25 | 26 | # esptool.py path and port 27 | ESPTOOL ?= esptool.py 28 | ESPPORT ?= /dev/ttyUSB0 29 | 30 | # name for the target project 31 | TARGET = app 32 | 33 | # which modules (subdirectories) of the project to include in compiling 34 | MODULES = user driver 35 | EXTRA_INCDIR = include 36 | 37 | # libraries used in this project, mainly provided by the SDK 38 | LIBS = c gcc hal pp phy net80211 lwip wpa main 39 | 40 | # compiler flags using during compilation of source files 41 | CFLAGS = -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH 42 | 43 | # linker flags used to generate the main object file 44 | LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static 45 | 46 | # linker script used for the above linkier step 47 | LD_SCRIPT = eagle.app.v6.ld 48 | 49 | # various paths from the SDK used in this project 50 | SDK_LIBDIR = lib 51 | SDK_LDDIR = ld 52 | SDK_INCDIR = include 53 | 54 | # we create two different files for uploading into the flash 55 | # these are the names and options to generate them 56 | FW_FILE_1_ADDR = 0x00000 57 | FW_FILE_2_ADDR = 0x40000 58 | 59 | # select which tools to use as compiler, librarian and linker 60 | CC := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc 61 | AR := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar 62 | LD := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc 63 | 64 | 65 | 66 | #### 67 | #### no user configurable options below here 68 | #### 69 | SRC_DIR := $(MODULES) 70 | BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(MODULES)) 71 | 72 | SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR)) 73 | SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR)) 74 | 75 | SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) 76 | OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC)) 77 | LIBS := $(addprefix -l,$(LIBS)) 78 | APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a) 79 | TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out) 80 | 81 | LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT)) 82 | 83 | INCDIR := $(addprefix -I,$(SRC_DIR)) 84 | EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR)) 85 | MODULE_INCDIR := $(addsuffix /include,$(INCDIR)) 86 | 87 | FW_FILE_1 := $(addprefix $(FW_BASE)/,$(FW_FILE_1_ADDR).bin) 88 | FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_FILE_2_ADDR).bin) 89 | 90 | V ?= $(VERBOSE) 91 | ifeq ("$(V)","1") 92 | Q := 93 | vecho := @true 94 | else 95 | Q := @ 96 | vecho := @echo 97 | endif 98 | 99 | vpath %.c $(SRC_DIR) 100 | 101 | define compile-objects 102 | $1/%.o: %.c 103 | $(vecho) "CC $$<" 104 | $(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@ 105 | endef 106 | 107 | .PHONY: all checkdirs flash clean 108 | 109 | all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2) 110 | 111 | $(FW_BASE)/%.bin: $(TARGET_OUT) | $(FW_BASE) 112 | $(vecho) "FW $(FW_BASE)/" 113 | $(Q) $(ESPTOOL) elf2image -o $(FW_BASE)/ $(TARGET_OUT) 114 | 115 | $(TARGET_OUT): $(APP_AR) 116 | $(vecho) "LD $@" 117 | $(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ 118 | 119 | $(APP_AR): $(OBJ) 120 | $(vecho) "AR $@" 121 | $(Q) $(AR) cru $@ $^ 122 | 123 | checkdirs: $(BUILD_DIR) $(FW_BASE) 124 | 125 | $(BUILD_DIR): 126 | $(Q) mkdir -p $@ 127 | 128 | $(FW_BASE): 129 | $(Q) mkdir -p $@ 130 | 131 | flash: $(FW_FILE_1) $(FW_FILE_2) 132 | $(ESPTOOL) --port $(ESPPORT) write_flash $(FW_FILE_1_ADDR) $(FW_FILE_1) $(FW_FILE_2_ADDR) $(FW_FILE_2) 133 | 134 | clean: 135 | $(Q) rm -rf $(FW_BASE) $(BUILD_BASE) 136 | 137 | $(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir)))) 138 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP8266 RTC Example 2 | 3 | An ESP8266 Real Time Clock (RTC) from the Appendix (8.2) of the ESP8266 SDK Programming Guide EN v1.1.0 4 | 5 | ## Instructions: 6 | 1. Build and setup the [toolchain](https://github.com/esp8266/esp8266-wiki/wiki/Toolchain) if required. I used [pfalcon's repository](https://github.com/pfalcon/esp-open-sdk) as recommended; and did a seperated build. 7 | 2. `make` 8 | 3. `make flash` 9 | 4. Observe the serial output using a baud rate of 115200. 10 | 11 | The SDK Programming Guide can be found in `/sdk/document` 12 | -------------------------------------------------------------------------------- /driver/uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File : uart.c 3 | * Copyright (C) 2013 - 2016, Espressif Systems 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of version 3 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program. If not, see . 16 | */ 17 | #include "ets_sys.h" 18 | #include "osapi.h" 19 | #include "driver/uart.h" 20 | #include "osapi.h" 21 | #include "driver/uart_register.h" 22 | #include "mem.h" 23 | #include "os_type.h" 24 | 25 | // UartDev is defined and initialized in rom code. 26 | extern UartDevice UartDev; 27 | 28 | LOCAL struct UartBuffer* pTxBuffer = NULL; 29 | LOCAL struct UartBuffer* pRxBuffer = NULL; 30 | 31 | /*uart demo with a system task, to output what uart receives*/ 32 | /*this is a example to process uart data from task,please change the priority to fit your application task if exists*/ 33 | /*it might conflict with your task, if so,please arrange the priority of different task, or combine it to a different event in the same task. */ 34 | #define uart_recvTaskPrio 0 35 | #define uart_recvTaskQueueLen 10 36 | os_event_t uart_recvTaskQueue[uart_recvTaskQueueLen]; 37 | 38 | #define DBG 39 | #define DBG1 uart1_sendStr_no_wait 40 | #define DBG2 os_printf 41 | 42 | 43 | LOCAL void uart0_rx_intr_handler(void *para); 44 | 45 | /****************************************************************************** 46 | * FunctionName : uart_config 47 | * Description : Internal used function 48 | * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled 49 | * UART1 just used for debug output 50 | * Parameters : uart_no, use UART0 or UART1 defined ahead 51 | * Returns : NONE 52 | *******************************************************************************/ 53 | LOCAL void ICACHE_FLASH_ATTR 54 | uart_config(uint8 uart_no) 55 | { 56 | if (uart_no == UART1){ 57 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); 58 | }else{ 59 | /* rcv_buff size if 0x100 */ 60 | ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff)); 61 | PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); 62 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); 63 | #if UART_HW_RTS 64 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); //HW FLOW CONTROL RTS PIN 65 | #endif 66 | #if UART_HW_CTS 67 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); //HW FLOW CONTROL CTS PIN 68 | #endif 69 | } 70 | uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));//SET BAUDRATE 71 | 72 | WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M) << UART_PARITY_EN_S) //SET BIT AND PARITY MODE 73 | | ((UartDev.parity & UART_PARITY_M) <> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { 117 | break; 118 | } 119 | } 120 | WRITE_PERI_REG(UART_FIFO(uart) , TxChar); 121 | return OK; 122 | } 123 | 124 | /****************************************************************************** 125 | * FunctionName : uart1_write_char 126 | * Description : Internal used function 127 | * Do some special deal while tx char is '\r' or '\n' 128 | * Parameters : char c - character to tx 129 | * Returns : NONE 130 | *******************************************************************************/ 131 | LOCAL void ICACHE_FLASH_ATTR 132 | uart1_write_char(char c) 133 | { 134 | if (c == '\n'){ 135 | uart_tx_one_char(UART1, '\r'); 136 | uart_tx_one_char(UART1, '\n'); 137 | }else if (c == '\r'){ 138 | 139 | }else{ 140 | uart_tx_one_char(UART1, c); 141 | } 142 | } 143 | 144 | //os_printf output to fifo or to the tx buffer 145 | LOCAL void ICACHE_FLASH_ATTR 146 | uart0_write_char_no_wait(char c) 147 | { 148 | #if UART_BUFF_EN //send to uart0 fifo but do not wait 149 | uint8 chr; 150 | if (c == '\n'){ 151 | chr = '\r'; 152 | tx_buff_enq(&chr, 1); 153 | chr = '\n'; 154 | tx_buff_enq(&chr, 1); 155 | }else if (c == '\r'){ 156 | 157 | }else{ 158 | tx_buff_enq(&c,1); 159 | } 160 | #else //send to uart tx buffer 161 | if (c == '\n'){ 162 | uart_tx_one_char_no_wait(UART0, '\r'); 163 | uart_tx_one_char_no_wait(UART0, '\n'); 164 | }else if (c == '\r'){ 165 | 166 | } 167 | else{ 168 | uart_tx_one_char_no_wait(UART0, c); 169 | } 170 | #endif 171 | } 172 | 173 | /****************************************************************************** 174 | * FunctionName : uart0_tx_buffer 175 | * Description : use uart0 to transfer buffer 176 | * Parameters : uint8 *buf - point to send buffer 177 | * uint16 len - buffer len 178 | * Returns : 179 | *******************************************************************************/ 180 | void ICACHE_FLASH_ATTR 181 | uart0_tx_buffer(uint8 *buf, uint16 len) 182 | { 183 | uint16 i; 184 | for (i = 0; i < len; i++) 185 | { 186 | uart_tx_one_char(UART0, buf[i]); 187 | } 188 | } 189 | 190 | /****************************************************************************** 191 | * FunctionName : uart0_sendStr 192 | * Description : use uart0 to transfer buffer 193 | * Parameters : uint8 *buf - point to send buffer 194 | * uint16 len - buffer len 195 | * Returns : 196 | *******************************************************************************/ 197 | void ICACHE_FLASH_ATTR 198 | uart0_sendStr(const char *str) 199 | { 200 | while(*str){ 201 | uart_tx_one_char(UART0, *str++); 202 | } 203 | } 204 | void at_port_print(const char *str) __attribute__((alias("uart0_sendStr"))); 205 | /****************************************************************************** 206 | * FunctionName : uart0_rx_intr_handler 207 | * Description : Internal used function 208 | * UART0 interrupt handler, add self handle code inside 209 | * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg 210 | * Returns : NONE 211 | *******************************************************************************/ 212 | LOCAL void 213 | uart0_rx_intr_handler(void *para) 214 | { 215 | /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents 216 | * uart1 and uart0 respectively 217 | */ 218 | uint8 RcvChar; 219 | uint8 uart_no = UART0;//UartDev.buff_uart_no; 220 | uint8 fifo_len = 0; 221 | uint8 buf_idx = 0; 222 | uint8 temp,cnt; 223 | //RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para; 224 | 225 | /*ATTENTION:*/ 226 | /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/ 227 | /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */ 228 | /*IF NOT , POST AN EVENT AND PROCESS IN SYSTEM TASK */ 229 | if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)){ 230 | DBG1("FRM_ERR\r\n"); 231 | WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); 232 | }else if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)){ 233 | DBG("f"); 234 | uart_rx_intr_disable(UART0); 235 | WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); 236 | system_os_post(uart_recvTaskPrio, 0, 0); 237 | }else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)){ 238 | DBG("t"); 239 | uart_rx_intr_disable(UART0); 240 | WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); 241 | system_os_post(uart_recvTaskPrio, 0, 0); 242 | }else if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)){ 243 | DBG("e"); 244 | /* to output uart data from uart buffer directly in empty interrupt handler*/ 245 | /*instead of processing in system event, in order not to wait for current task/function to quit */ 246 | /*ATTENTION:*/ 247 | /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/ 248 | /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */ 249 | CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); 250 | #if UART_BUFF_EN 251 | tx_start_uart_buffer(UART0); 252 | #endif 253 | //system_os_post(uart_recvTaskPrio, 1, 0); 254 | WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR); 255 | 256 | }else if(UART_RXFIFO_OVF_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)){ 257 | WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR); 258 | DBG1("RX OVF!!\r\n"); 259 | } 260 | 261 | } 262 | 263 | /****************************************************************************** 264 | * FunctionName : uart_init 265 | * Description : user interface for init uart 266 | * Parameters : UartBautRate uart0_br - uart0 bautrate 267 | * UartBautRate uart1_br - uart1 bautrate 268 | * Returns : NONE 269 | *******************************************************************************/ 270 | #if UART_SELFTEST&UART_BUFF_EN 271 | os_timer_t buff_timer_t; 272 | void ICACHE_FLASH_ATTR 273 | uart_test_rx() 274 | { 275 | uint8 uart_buf[128]={0}; 276 | uint16 len = 0; 277 | len = rx_buff_deq(uart_buf, 128 ); 278 | tx_buff_enq(uart_buf,len); 279 | } 280 | #endif 281 | 282 | LOCAL void ICACHE_FLASH_ATTR /////// 283 | uart_recvTask(os_event_t *events) 284 | { 285 | if(events->sig == 0){ 286 | #if UART_BUFF_EN 287 | Uart_rx_buff_enq(); 288 | #else 289 | uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; 290 | uint8 d_tmp = 0; 291 | uint8 idx=0; 292 | for(idx=0;idxsig == 1){ 300 | #if UART_BUFF_EN 301 | //already move uart buffer output to uart empty interrupt 302 | //tx_start_uart_buffer(UART0); 303 | #else 304 | 305 | #endif 306 | } 307 | } 308 | 309 | void ICACHE_FLASH_ATTR 310 | uart_init(UartBautRate uart0_br, UartBautRate uart1_br) 311 | { 312 | /*this is a example to process uart data from task,please change the priority to fit your application task if exists*/ 313 | system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen); //demo with a task to process the uart data 314 | 315 | UartDev.baut_rate = uart0_br; 316 | uart_config(UART0); 317 | UartDev.baut_rate = uart1_br; 318 | uart_config(UART1); 319 | ETS_UART_INTR_ENABLE(); 320 | 321 | #if UART_BUFF_EN 322 | pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE); 323 | pRxBuffer = Uart_Buf_Init(UART_RX_BUFFER_SIZE); 324 | #endif 325 | 326 | 327 | /*option 1: use default print, output from uart0 , will wait some time if fifo is full */ 328 | //do nothing... 329 | 330 | /*option 2: output from uart1,uart1 output will not wait , just for output debug info */ 331 | /*os_printf output uart data via uart1(GPIO2)*/ 332 | //os_install_putc1((void *)uart1_write_char); //use this one to output debug information via uart1 // 333 | 334 | /*option 3: output from uart0 will skip current byte if fifo is full now... */ 335 | /*see uart0_write_char_no_wait:you can output via a buffer or output directly */ 336 | /*os_printf output uart data via uart0 or uart buffer*/ 337 | //os_install_putc1((void *)uart0_write_char_no_wait); //use this to print via uart0 338 | 339 | #if UART_SELFTEST&UART_BUFF_EN 340 | os_timer_disarm(&buff_timer_t); 341 | os_timer_setfn(&buff_timer_t, uart_test_rx , NULL); //a demo to process the data in uart rx buffer 342 | os_timer_arm(&buff_timer_t,10,1); 343 | #endif 344 | } 345 | 346 | void ICACHE_FLASH_ATTR 347 | uart_reattach() 348 | { 349 | uart_init(BIT_RATE_115200, BIT_RATE_115200); 350 | } 351 | 352 | /****************************************************************************** 353 | * FunctionName : uart_tx_one_char_no_wait 354 | * Description : uart tx a single char without waiting for fifo 355 | * Parameters : uint8 uart - uart port 356 | * uint8 TxChar - char to tx 357 | * Returns : STATUS 358 | *******************************************************************************/ 359 | STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar) 360 | { 361 | uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(uart))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT); 362 | if (fifo_cnt < 126) { 363 | WRITE_PERI_REG(UART_FIFO(uart) , TxChar); 364 | } 365 | return OK; 366 | } 367 | 368 | STATUS uart0_tx_one_char_no_wait(uint8 TxChar) 369 | { 370 | uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT); 371 | if (fifo_cnt < 126) { 372 | WRITE_PERI_REG(UART_FIFO(UART0) , TxChar); 373 | } 374 | return OK; 375 | } 376 | 377 | 378 | /****************************************************************************** 379 | * FunctionName : uart1_sendStr_no_wait 380 | * Description : uart tx a string without waiting for every char, used for print debug info which can be lost 381 | * Parameters : const char *str - string to be sent 382 | * Returns : NONE 383 | *******************************************************************************/ 384 | void uart1_sendStr_no_wait(const char *str) 385 | { 386 | while(*str){ 387 | uart_tx_one_char_no_wait(UART1, *str++); 388 | } 389 | } 390 | 391 | 392 | #if UART_BUFF_EN 393 | /****************************************************************************** 394 | * FunctionName : Uart_Buf_Init 395 | * Description : tx buffer enqueue: fill a first linked buffer 396 | * Parameters : char *pdata - data point to be enqueue 397 | * Returns : NONE 398 | *******************************************************************************/ 399 | struct UartBuffer* ICACHE_FLASH_ATTR 400 | Uart_Buf_Init(uint32 buf_size) 401 | { 402 | uint32 heap_size = system_get_free_heap_size(); 403 | if(heap_size <=buf_size){ 404 | DBG1("no buf for uart\n\r"); 405 | return NULL; 406 | }else{ 407 | DBG("test heap size: %d\n\r",heap_size); 408 | struct UartBuffer* pBuff = (struct UartBuffer* )os_malloc(sizeof(struct UartBuffer)); 409 | pBuff->UartBuffSize = buf_size; 410 | pBuff->pUartBuff = (uint8*)os_malloc(pBuff->UartBuffSize); 411 | pBuff->pInPos = pBuff->pUartBuff; 412 | pBuff->pOutPos = pBuff->pUartBuff; 413 | pBuff->Space = pBuff->UartBuffSize; 414 | pBuff->BuffState = OK; 415 | pBuff->nextBuff = NULL; 416 | pBuff->TcpControl = RUN; 417 | return pBuff; 418 | } 419 | } 420 | 421 | 422 | //copy uart buffer 423 | LOCAL void Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len) 424 | { 425 | if(data_len == 0) return ; 426 | 427 | uint16 tail_len = pCur->pUartBuff + pCur->UartBuffSize - pCur->pInPos ; 428 | if(tail_len >= data_len){ //do not need to loop back the queue 429 | os_memcpy(pCur->pInPos , pdata , data_len ); 430 | pCur->pInPos += ( data_len ); 431 | pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize ); 432 | pCur->Space -=data_len; 433 | }else{ 434 | os_memcpy(pCur->pInPos, pdata, tail_len); 435 | pCur->pInPos += ( tail_len ); 436 | pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize ); 437 | pCur->Space -=tail_len; 438 | os_memcpy(pCur->pInPos, pdata+tail_len , data_len-tail_len); 439 | pCur->pInPos += ( data_len-tail_len ); 440 | pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize ); 441 | pCur->Space -=( data_len-tail_len); 442 | } 443 | 444 | } 445 | 446 | /****************************************************************************** 447 | * FunctionName : uart_buf_free 448 | * Description : deinit of the tx buffer 449 | * Parameters : struct UartBuffer* pTxBuff - tx buffer struct pointer 450 | * Returns : NONE 451 | *******************************************************************************/ 452 | void ICACHE_FLASH_ATTR 453 | uart_buf_free(struct UartBuffer* pBuff) 454 | { 455 | os_free(pBuff->pUartBuff); 456 | os_free(pBuff); 457 | } 458 | 459 | 460 | //rx buffer dequeue 461 | uint16 ICACHE_FLASH_ATTR 462 | rx_buff_deq(char* pdata, uint16 data_len ) 463 | { 464 | uint16 buf_len = (pRxBuffer->UartBuffSize- pRxBuffer->Space); 465 | uint16 tail_len = pRxBuffer->pUartBuff + pRxBuffer->UartBuffSize - pRxBuffer->pOutPos ; 466 | uint16 len_tmp = 0; 467 | len_tmp = ((data_len > buf_len)?buf_len:data_len); 468 | if(pRxBuffer->pOutPos <= pRxBuffer->pInPos){ 469 | os_memcpy(pdata, pRxBuffer->pOutPos,len_tmp); 470 | pRxBuffer->pOutPos+= len_tmp; 471 | pRxBuffer->Space += len_tmp; 472 | }else{ 473 | if(len_tmp>tail_len){ 474 | os_memcpy(pdata, pRxBuffer->pOutPos, tail_len); 475 | pRxBuffer->pOutPos += tail_len; 476 | pRxBuffer->pOutPos = (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize ); 477 | pRxBuffer->Space += tail_len; 478 | 479 | os_memcpy(pdata+tail_len , pRxBuffer->pOutPos, len_tmp-tail_len); 480 | pRxBuffer->pOutPos+= ( len_tmp-tail_len ); 481 | pRxBuffer->pOutPos= (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize ); 482 | pRxBuffer->Space +=( len_tmp-tail_len); 483 | }else{ 484 | //os_printf("case 3 in rx deq\n\r"); 485 | os_memcpy(pdata, pRxBuffer->pOutPos, len_tmp); 486 | pRxBuffer->pOutPos += len_tmp; 487 | pRxBuffer->pOutPos = (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize ); 488 | pRxBuffer->Space += len_tmp; 489 | } 490 | } 491 | if(pRxBuffer->Space >= UART_FIFO_LEN){ 492 | uart_rx_intr_enable(UART0); 493 | } 494 | return len_tmp; 495 | } 496 | 497 | 498 | //move data from uart fifo to rx buffer 499 | void Uart_rx_buff_enq() 500 | { 501 | uint8 fifo_len,buf_idx; 502 | uint8 fifo_data; 503 | #if 1 504 | fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; 505 | if(fifo_len >= pRxBuffer->Space){ 506 | os_printf("buf full!!!\n\r"); 507 | }else{ 508 | buf_idx=0; 509 | while(buf_idx < fifo_len){ 510 | buf_idx++; 511 | fifo_data = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF; 512 | *(pRxBuffer->pInPos++) = fifo_data; 513 | if(pRxBuffer->pInPos == (pRxBuffer->pUartBuff + pRxBuffer->UartBuffSize)){ 514 | pRxBuffer->pInPos = pRxBuffer->pUartBuff; 515 | } 516 | } 517 | pRxBuffer->Space -= fifo_len ; 518 | if(pRxBuffer->Space >= UART_FIFO_LEN){ 519 | //os_printf("after rx enq buf enough\n\r"); 520 | uart_rx_intr_enable(UART0); 521 | } 522 | } 523 | #endif 524 | } 525 | 526 | 527 | //fill the uart tx buffer 528 | void ICACHE_FLASH_ATTR 529 | tx_buff_enq(char* pdata, uint16 data_len ) 530 | { 531 | if(pTxBuffer == NULL){ 532 | DBG1("\n\rnull, create buffer struct\n\r"); 533 | pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE); 534 | if(pTxBuffer!= NULL){ 535 | Uart_Buf_Cpy(pTxBuffer , pdata, data_len ); 536 | }else{ 537 | DBG1("uart tx MALLOC no buf \n\r"); 538 | } 539 | }else{ 540 | if(data_len <= pTxBuffer->Space){ 541 | Uart_Buf_Cpy(pTxBuffer , pdata, data_len); 542 | }else{ 543 | DBG1("UART TX BUF FULL!!!!\n\r"); 544 | } 545 | } 546 | #if 0 547 | if(pTxBuffer->Space <= URAT_TX_LOWER_SIZE){ 548 | set_tcp_block(); 549 | } 550 | #endif 551 | SET_PERI_REG_MASK(UART_CONF1(UART0), (UART_TX_EMPTY_THRESH_VAL & UART_TXFIFO_EMPTY_THRHD)<pOutPos++)); 563 | if(pTxBuff->pOutPos == (pTxBuff->pUartBuff + pTxBuff->UartBuffSize)){ 564 | pTxBuff->pOutPos = pTxBuff->pUartBuff; 565 | } 566 | } 567 | pTxBuff->pOutPos = (pTxBuff->pUartBuff + (pTxBuff->pOutPos - pTxBuff->pUartBuff) % pTxBuff->UartBuffSize ); 568 | pTxBuff->Space += data_len; 569 | } 570 | 571 | 572 | /****************************************************************************** 573 | * FunctionName : tx_start_uart_buffer 574 | * Description : get data from the tx buffer and fill the uart tx fifo, co-work with the uart fifo empty interrupt 575 | * Parameters : uint8 uart_no - uart port num 576 | * Returns : NONE 577 | *******************************************************************************/ 578 | void tx_start_uart_buffer(uint8 uart_no) 579 | { 580 | uint8 tx_fifo_len = (READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT; 581 | uint8 fifo_remain = UART_FIFO_LEN - tx_fifo_len ; 582 | uint8 len_tmp; 583 | uint16 tail_ptx_len,head_ptx_len,data_len; 584 | //struct UartBuffer* pTxBuff = *get_buff_prt(); 585 | 586 | if(pTxBuffer){ 587 | data_len = (pTxBuffer->UartBuffSize - pTxBuffer->Space); 588 | if(data_len > fifo_remain){ 589 | len_tmp = fifo_remain; 590 | tx_fifo_insert( pTxBuffer,len_tmp,uart_no); 591 | SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); 592 | }else{ 593 | len_tmp = data_len; 594 | tx_fifo_insert( pTxBuffer,len_tmp,uart_no); 595 | } 596 | }else{ 597 | DBG1("pTxBuff null \n\r"); 598 | } 599 | } 600 | 601 | #endif 602 | 603 | 604 | void uart_rx_intr_disable(uint8 uart_no) 605 | { 606 | #if 1 607 | CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); 608 | #else 609 | ETS_UART_INTR_DISABLE(); 610 | #endif 611 | } 612 | 613 | void uart_rx_intr_enable(uint8 uart_no) 614 | { 615 | #if 1 616 | SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); 617 | #else 618 | ETS_UART_INTR_ENABLE(); 619 | #endif 620 | } 621 | 622 | 623 | //======================================================== 624 | LOCAL void 625 | uart0_write_char(char c) 626 | { 627 | if (c == '\n') { 628 | uart_tx_one_char(UART0, '\r'); 629 | uart_tx_one_char(UART0, '\n'); 630 | } else if (c == '\r') { 631 | } else { 632 | uart_tx_one_char(UART0, c); 633 | } 634 | } 635 | 636 | void ICACHE_FLASH_ATTR 637 | UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len) 638 | { 639 | SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_BIT_NUM,len,UART_BIT_NUM_S); 640 | } 641 | 642 | void ICACHE_FLASH_ATTR 643 | UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num) 644 | { 645 | SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_STOP_BIT_NUM,bit_num,UART_STOP_BIT_NUM_S); 646 | } 647 | 648 | void ICACHE_FLASH_ATTR 649 | UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask) 650 | { 651 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK); 652 | SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask); 653 | } 654 | 655 | void ICACHE_FLASH_ATTR 656 | UART_SetParity(uint8 uart_no, UartParityMode Parity_mode) 657 | { 658 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY |UART_PARITY_EN); 659 | if(Parity_mode==NONE_BITS){ 660 | }else{ 661 | SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode|UART_PARITY_EN); 662 | } 663 | } 664 | 665 | void ICACHE_FLASH_ATTR 666 | UART_SetBaudrate(uint8 uart_no,uint32 baud_rate) 667 | { 668 | uart_div_modify(uart_no, UART_CLK_FREQ /baud_rate); 669 | } 670 | 671 | void ICACHE_FLASH_ATTR 672 | UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh) 673 | { 674 | if(flow_ctrl&USART_HardwareFlowControl_RTS){ 675 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); 676 | SET_PERI_REG_BITS(UART_CONF1(uart_no),UART_RX_FLOW_THRHD,rx_thresh,UART_RX_FLOW_THRHD_S); 677 | SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); 678 | }else{ 679 | CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); 680 | } 681 | if(flow_ctrl&USART_HardwareFlowControl_CTS){ 682 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS); 683 | SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); 684 | }else{ 685 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); 686 | } 687 | } 688 | 689 | void ICACHE_FLASH_ATTR 690 | UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us) //do not use if tx flow control enabled 691 | { 692 | uint32 t_s = system_get_time(); 693 | while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)){ 694 | 695 | if(( system_get_time() - t_s )> time_out_us){ 696 | break; 697 | } 698 | WRITE_PERI_REG(0X60000914, 0X73);//WTD 699 | 700 | } 701 | } 702 | 703 | 704 | bool ICACHE_FLASH_ATTR 705 | UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us) 706 | { 707 | uint32 t_start = system_get_time(); 708 | uint8 tx_fifo_len; 709 | uint32 tx_buff_len; 710 | while(1){ 711 | tx_fifo_len =( (READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT); 712 | if(pTxBuffer){ 713 | tx_buff_len = ((pTxBuffer->UartBuffSize)-(pTxBuffer->Space)); 714 | }else{ 715 | tx_buff_len = 0; 716 | } 717 | 718 | if( tx_fifo_len==0 && tx_buff_len==0){ 719 | return TRUE; 720 | } 721 | if( system_get_time() - t_start > time_out_us){ 722 | return FALSE; 723 | } 724 | WRITE_PERI_REG(0X60000914, 0X73);//WTD 725 | } 726 | } 727 | 728 | 729 | void ICACHE_FLASH_ATTR 730 | UART_ResetFifo(uint8 uart_no) 731 | { 732 | SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); 733 | CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); 734 | } 735 | 736 | void ICACHE_FLASH_ATTR 737 | UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask) 738 | { 739 | WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask); 740 | } 741 | 742 | void ICACHE_FLASH_ATTR 743 | UART_SetIntrEna(uint8 uart_no,uint32 ena_mask) 744 | { 745 | SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask); 746 | } 747 | 748 | 749 | void ICACHE_FLASH_ATTR 750 | UART_SetPrintPort(uint8 uart_no) 751 | { 752 | if(uart_no==1){ 753 | os_install_putc1(uart1_write_char); 754 | }else{ 755 | /*option 1: do not wait if uart fifo is full,drop current character*/ 756 | os_install_putc1(uart0_write_char_no_wait); 757 | /*option 2: wait for a while if uart fifo is full*/ 758 | os_install_putc1(uart0_write_char); 759 | } 760 | } 761 | 762 | 763 | //======================================================== 764 | 765 | 766 | /*test code*/ 767 | void ICACHE_FLASH_ATTR 768 | uart_init_2(UartBautRate uart0_br, UartBautRate uart1_br) 769 | { 770 | // rom use 74880 baut_rate, here reinitialize 771 | UartDev.baut_rate = uart0_br; 772 | UartDev.exist_parity = STICK_PARITY_EN; 773 | UartDev.parity = EVEN_BITS; 774 | UartDev.stop_bits = ONE_STOP_BIT; 775 | UartDev.data_bits = EIGHT_BITS; 776 | 777 | uart_config(UART0); 778 | UartDev.baut_rate = uart1_br; 779 | uart_config(UART1); 780 | ETS_UART_INTR_ENABLE(); 781 | 782 | // install uart1 putc callback 783 | os_install_putc1((void *)uart1_write_char);//print output at UART1 784 | } 785 | 786 | 787 | -------------------------------------------------------------------------------- /include/driver/uart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File : uart.h 3 | * Copyright (C) 2013 - 2016, Espressif Systems 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of version 3 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program. If not, see . 16 | */ 17 | #ifndef UART_APP_H 18 | #define UART_APP_H 19 | 20 | #include "uart_register.h" 21 | #include "eagle_soc.h" 22 | #include "c_types.h" 23 | 24 | #define UART_TX_BUFFER_SIZE 256 //Ring buffer length of tx buffer 25 | #define UART_RX_BUFFER_SIZE 256 //Ring buffer length of rx buffer 26 | 27 | #define UART_BUFF_EN 0 //use uart buffer , FOR UART0 28 | #define UART_SELFTEST 0 //set 1:enable the loop test demo for uart buffer, FOR UART0 29 | 30 | #define UART_HW_RTS 0 //set 1: enable uart hw flow control RTS, PIN MTDO, FOR UART0 31 | #define UART_HW_CTS 0 //set1: enable uart hw flow contrl CTS , PIN MTCK, FOR UART0 32 | 33 | 34 | 35 | 36 | #define UART0 0 37 | #define UART1 1 38 | 39 | 40 | typedef enum { 41 | FIVE_BITS = 0x0, 42 | SIX_BITS = 0x1, 43 | SEVEN_BITS = 0x2, 44 | EIGHT_BITS = 0x3 45 | } UartBitsNum4Char; 46 | 47 | typedef enum { 48 | ONE_STOP_BIT = 0x1, 49 | ONE_HALF_STOP_BIT = 0x2, 50 | TWO_STOP_BIT = 0x3 51 | } UartStopBitsNum; 52 | 53 | typedef enum { 54 | NONE_BITS = 0x2, 55 | ODD_BITS = 1, 56 | EVEN_BITS = 0 57 | } UartParityMode; 58 | 59 | typedef enum { 60 | STICK_PARITY_DIS = 0, 61 | STICK_PARITY_EN = 1 62 | } UartExistParity; 63 | 64 | typedef enum { 65 | UART_None_Inverse = 0x0, 66 | UART_Rxd_Inverse = UART_RXD_INV, 67 | UART_CTS_Inverse = UART_CTS_INV, 68 | UART_Txd_Inverse = UART_TXD_INV, 69 | UART_RTS_Inverse = UART_RTS_INV, 70 | } UART_LineLevelInverse; 71 | 72 | 73 | typedef enum { 74 | BIT_RATE_300 = 300, 75 | BIT_RATE_600 = 600, 76 | BIT_RATE_1200 = 1200, 77 | BIT_RATE_2400 = 2400, 78 | BIT_RATE_4800 = 4800, 79 | BIT_RATE_9600 = 9600, 80 | BIT_RATE_19200 = 19200, 81 | BIT_RATE_38400 = 38400, 82 | BIT_RATE_57600 = 57600, 83 | BIT_RATE_74880 = 74880, 84 | BIT_RATE_115200 = 115200, 85 | BIT_RATE_230400 = 230400, 86 | BIT_RATE_460800 = 460800, 87 | BIT_RATE_921600 = 921600, 88 | BIT_RATE_1843200 = 1843200, 89 | BIT_RATE_3686400 = 3686400, 90 | } UartBautRate; 91 | 92 | typedef enum { 93 | NONE_CTRL, 94 | HARDWARE_CTRL, 95 | XON_XOFF_CTRL 96 | } UartFlowCtrl; 97 | 98 | typedef enum { 99 | USART_HardwareFlowControl_None = 0x0, 100 | USART_HardwareFlowControl_RTS = 0x1, 101 | USART_HardwareFlowControl_CTS = 0x2, 102 | USART_HardwareFlowControl_CTS_RTS = 0x3 103 | } UART_HwFlowCtrl; 104 | 105 | typedef enum { 106 | EMPTY, 107 | UNDER_WRITE, 108 | WRITE_OVER 109 | } RcvMsgBuffState; 110 | 111 | typedef struct { 112 | uint32 RcvBuffSize; 113 | uint8 *pRcvMsgBuff; 114 | uint8 *pWritePos; 115 | uint8 *pReadPos; 116 | uint8 TrigLvl; //JLU: may need to pad 117 | RcvMsgBuffState BuffState; 118 | } RcvMsgBuff; 119 | 120 | typedef struct { 121 | uint32 TrxBuffSize; 122 | uint8 *pTrxBuff; 123 | } TrxMsgBuff; 124 | 125 | typedef enum { 126 | BAUD_RATE_DET, 127 | WAIT_SYNC_FRM, 128 | SRCH_MSG_HEAD, 129 | RCV_MSG_BODY, 130 | RCV_ESC_CHAR, 131 | } RcvMsgState; 132 | 133 | typedef struct { 134 | UartBautRate baut_rate; 135 | UartBitsNum4Char data_bits; 136 | UartExistParity exist_parity; 137 | UartParityMode parity; 138 | UartStopBitsNum stop_bits; 139 | UartFlowCtrl flow_ctrl; 140 | RcvMsgBuff rcv_buff; 141 | TrxMsgBuff trx_buff; 142 | RcvMsgState rcv_state; 143 | int received; 144 | int buff_uart_no; //indicate which uart use tx/rx buffer 145 | } UartDevice; 146 | 147 | void uart_init(UartBautRate uart0_br, UartBautRate uart1_br); 148 | void uart0_sendStr(const char *str); 149 | 150 | 151 | /////////////////////////////////////// 152 | #define UART_FIFO_LEN 128 //define the tx fifo length 153 | #define UART_TX_EMPTY_THRESH_VAL 0x10 154 | 155 | 156 | struct UartBuffer{ 157 | uint32 UartBuffSize; 158 | uint8 *pUartBuff; 159 | uint8 *pInPos; 160 | uint8 *pOutPos; 161 | STATUS BuffState; 162 | uint16 Space; //remanent space of the buffer 163 | uint8 TcpControl; 164 | struct UartBuffer * nextBuff; 165 | }; 166 | 167 | struct UartRxBuff{ 168 | uint32 UartRxBuffSize; 169 | uint8 *pUartRxBuff; 170 | uint8 *pWritePos; 171 | uint8 *pReadPos; 172 | STATUS RxBuffState; 173 | uint32 Space; //remanent space of the buffer 174 | } ; 175 | 176 | typedef enum { 177 | RUN = 0, 178 | BLOCK = 1, 179 | } TCPState; 180 | 181 | //void ICACHE_FLASH_ATTR uart_test_rx(); 182 | STATUS uart_tx_one_char(uint8 uart, uint8 TxChar); 183 | STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar); 184 | void uart1_sendStr_no_wait(const char *str); 185 | struct UartBuffer* Uart_Buf_Init(); 186 | 187 | 188 | #if UART_BUFF_EN 189 | LOCAL void Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len); 190 | void uart_buf_free(struct UartBuffer* pBuff); 191 | void tx_buff_enq(char* pdata, uint16 data_len ); 192 | LOCAL void tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len, uint8 uart_no); 193 | void tx_start_uart_buffer(uint8 uart_no); 194 | uint16 rx_buff_deq(char* pdata, uint16 data_len ); 195 | void Uart_rx_buff_enq(); 196 | #endif 197 | void uart_rx_intr_enable(uint8 uart_no); 198 | void uart_rx_intr_disable(uint8 uart_no); 199 | void uart0_tx_buffer(uint8 *buf, uint16 len); 200 | 201 | //============================================== 202 | #define FUNC_UART0_CTS 4 203 | #define FUNC_U0CTS 4 204 | #define FUNC_U1TXD_BK 2 205 | #define UART_LINE_INV_MASK (0x3f<<19) 206 | void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len); 207 | void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num); 208 | void UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask); 209 | void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode); 210 | void UART_SetBaudrate(uint8 uart_no,uint32 baud_rate); 211 | void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh); 212 | void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us); //do not use if tx flow control enabled 213 | void UART_ResetFifo(uint8 uart_no); 214 | void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask); 215 | void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask); 216 | void UART_SetPrintPort(uint8 uart_no); 217 | bool UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us); 218 | //============================================== 219 | 220 | #endif 221 | 222 | -------------------------------------------------------------------------------- /include/driver/uart_register.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File : uart_register.h 3 | * Copyright (C) 2013 - 2016, Espressif Systems 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of version 3 of the GNU General Public License as 7 | * published by the Free Software Foundation. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program. If not, see . 16 | */ 17 | /* 18 | * Copyright (c) 2010 - 2011 Espressif System 19 | * 20 | */ 21 | 22 | #ifndef UART_REGISTER_H_ 23 | #define UART_REGISTER_H_ 24 | 25 | #define REG_UART_BASE(i) (0x60000000 + (i)*0xf00) 26 | //version value:32'h062000 27 | 28 | #define UART_FIFO(i) (REG_UART_BASE(i) + 0x0) 29 | #define UART_RXFIFO_RD_BYTE 0x000000FF 30 | #define UART_RXFIFO_RD_BYTE_S 0 31 | 32 | #define UART_INT_RAW(i) (REG_UART_BASE(i) + 0x4) 33 | #define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) 34 | #define UART_BRK_DET_INT_RAW (BIT(7)) 35 | #define UART_CTS_CHG_INT_RAW (BIT(6)) 36 | #define UART_DSR_CHG_INT_RAW (BIT(5)) 37 | #define UART_RXFIFO_OVF_INT_RAW (BIT(4)) 38 | #define UART_FRM_ERR_INT_RAW (BIT(3)) 39 | #define UART_PARITY_ERR_INT_RAW (BIT(2)) 40 | #define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) 41 | #define UART_RXFIFO_FULL_INT_RAW (BIT(0)) 42 | 43 | #define UART_INT_ST(i) (REG_UART_BASE(i) + 0x8) 44 | #define UART_RXFIFO_TOUT_INT_ST (BIT(8)) 45 | #define UART_BRK_DET_INT_ST (BIT(7)) 46 | #define UART_CTS_CHG_INT_ST (BIT(6)) 47 | #define UART_DSR_CHG_INT_ST (BIT(5)) 48 | #define UART_RXFIFO_OVF_INT_ST (BIT(4)) 49 | #define UART_FRM_ERR_INT_ST (BIT(3)) 50 | #define UART_PARITY_ERR_INT_ST (BIT(2)) 51 | #define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) 52 | #define UART_RXFIFO_FULL_INT_ST (BIT(0)) 53 | 54 | #define UART_INT_ENA(i) (REG_UART_BASE(i) + 0xC) 55 | #define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) 56 | #define UART_BRK_DET_INT_ENA (BIT(7)) 57 | #define UART_CTS_CHG_INT_ENA (BIT(6)) 58 | #define UART_DSR_CHG_INT_ENA (BIT(5)) 59 | #define UART_RXFIFO_OVF_INT_ENA (BIT(4)) 60 | #define UART_FRM_ERR_INT_ENA (BIT(3)) 61 | #define UART_PARITY_ERR_INT_ENA (BIT(2)) 62 | #define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) 63 | #define UART_RXFIFO_FULL_INT_ENA (BIT(0)) 64 | 65 | #define UART_INT_CLR(i) (REG_UART_BASE(i) + 0x10) 66 | #define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) 67 | #define UART_BRK_DET_INT_CLR (BIT(7)) 68 | #define UART_CTS_CHG_INT_CLR (BIT(6)) 69 | #define UART_DSR_CHG_INT_CLR (BIT(5)) 70 | #define UART_RXFIFO_OVF_INT_CLR (BIT(4)) 71 | #define UART_FRM_ERR_INT_CLR (BIT(3)) 72 | #define UART_PARITY_ERR_INT_CLR (BIT(2)) 73 | #define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) 74 | #define UART_RXFIFO_FULL_INT_CLR (BIT(0)) 75 | 76 | #define UART_CLKDIV(i) (REG_UART_BASE(i) + 0x14) 77 | #define UART_CLKDIV_CNT 0x000FFFFF 78 | #define UART_CLKDIV_S 0 79 | 80 | #define UART_AUTOBAUD(i) (REG_UART_BASE(i) + 0x18) 81 | #define UART_GLITCH_FILT 0x000000FF 82 | #define UART_GLITCH_FILT_S 8 83 | #define UART_AUTOBAUD_EN (BIT(0)) 84 | 85 | #define UART_STATUS(i) (REG_UART_BASE(i) + 0x1C) 86 | #define UART_TXD (BIT(31)) 87 | #define UART_RTSN (BIT(30)) 88 | #define UART_DTRN (BIT(29)) 89 | #define UART_TXFIFO_CNT 0x000000FF 90 | #define UART_TXFIFO_CNT_S 16 91 | #define UART_RXD (BIT(15)) 92 | #define UART_CTSN (BIT(14)) 93 | #define UART_DSRN (BIT(13)) 94 | #define UART_RXFIFO_CNT 0x000000FF 95 | #define UART_RXFIFO_CNT_S 0 96 | 97 | #define UART_CONF0(i) (REG_UART_BASE(i) + 0x20) 98 | #define UART_DTR_INV (BIT(24)) 99 | #define UART_RTS_INV (BIT(23)) 100 | #define UART_TXD_INV (BIT(22)) 101 | #define UART_DSR_INV (BIT(21)) 102 | #define UART_CTS_INV (BIT(20)) 103 | #define UART_RXD_INV (BIT(19)) 104 | #define UART_TXFIFO_RST (BIT(18)) 105 | #define UART_RXFIFO_RST (BIT(17)) 106 | #define UART_IRDA_EN (BIT(16)) 107 | #define UART_TX_FLOW_EN (BIT(15)) 108 | #define UART_LOOPBACK (BIT(14)) 109 | #define UART_IRDA_RX_INV (BIT(13)) 110 | #define UART_IRDA_TX_INV (BIT(12)) 111 | #define UART_IRDA_WCTL (BIT(11)) 112 | #define UART_IRDA_TX_EN (BIT(10)) 113 | #define UART_IRDA_DPLX (BIT(9)) 114 | #define UART_TXD_BRK (BIT(8)) 115 | #define UART_SW_DTR (BIT(7)) 116 | #define UART_SW_RTS (BIT(6)) 117 | #define UART_STOP_BIT_NUM 0x00000003 118 | #define UART_STOP_BIT_NUM_S 4 119 | #define UART_BIT_NUM 0x00000003 120 | #define UART_BIT_NUM_S 2 121 | #define UART_PARITY_EN (BIT(1)) 122 | #define UART_PARITY_EN_M 0x00000001 123 | #define UART_PARITY_EN_S 1 124 | #define UART_PARITY (BIT(0)) 125 | #define UART_PARITY_M 0x00000001 126 | #define UART_PARITY_S 0 127 | 128 | #define UART_CONF1(i) (REG_UART_BASE(i) + 0x24) 129 | #define UART_RX_TOUT_EN (BIT(31)) 130 | #define UART_RX_TOUT_THRHD 0x0000007F 131 | #define UART_RX_TOUT_THRHD_S 24 132 | #define UART_RX_FLOW_EN (BIT(23)) 133 | #define UART_RX_FLOW_THRHD 0x0000007F 134 | #define UART_RX_FLOW_THRHD_S 16 135 | #define UART_TXFIFO_EMPTY_THRHD 0x0000007F 136 | #define UART_TXFIFO_EMPTY_THRHD_S 8 137 | #define UART_RXFIFO_FULL_THRHD 0x0000007F 138 | #define UART_RXFIFO_FULL_THRHD_S 0 139 | 140 | #define UART_LOWPULSE(i) (REG_UART_BASE(i) + 0x28) 141 | #define UART_LOWPULSE_MIN_CNT 0x000FFFFF 142 | #define UART_LOWPULSE_MIN_CNT_S 0 143 | 144 | #define UART_HIGHPULSE(i) (REG_UART_BASE(i) + 0x2C) 145 | #define UART_HIGHPULSE_MIN_CNT 0x000FFFFF 146 | #define UART_HIGHPULSE_MIN_CNT_S 0 147 | 148 | #define UART_PULSE_NUM(i) (REG_UART_BASE(i) + 0x30) 149 | #define UART_PULSE_NUM_CNT 0x0003FF 150 | #define UART_PULSE_NUM_CNT_S 0 151 | 152 | #define UART_DATE(i) (REG_UART_BASE(i) + 0x78) 153 | #define UART_ID(i) (REG_UART_BASE(i) + 0x7C) 154 | 155 | #endif // UART_REGISTER_H_INCLUDED 156 | 157 | -------------------------------------------------------------------------------- /user/user_config.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x6e/ESP8266-RTC-Example/5812f6b4a6dd3ce89a291993b39a2cfca7a0da06/user/user_config.h -------------------------------------------------------------------------------- /user/user_main.c: -------------------------------------------------------------------------------- 1 | #include "ets_sys.h" 2 | #include "osapi.h" 3 | #include "user_interface.h" 4 | #include "driver/uart.h" 5 | 6 | os_timer_t rtc_test_t; 7 | #define RTC_MAGIC 0x55aaaa55 8 | 9 | typedef struct { 10 | uint64 timeAcc; 11 | uint32 magic; 12 | uint32 timeBase; 13 | } RTC_TIMER_DEMO; 14 | 15 | void rtcCount() 16 | { 17 | RTC_TIMER_DEMO rtcTime; 18 | static uint8 count = 0; 19 | system_rtc_mem_read(64, &rtcTime, sizeof(rtcTime)); 20 | 21 | // Initialise the time struct 22 | if (rtcTime.magic != RTC_MAGIC) 23 | { 24 | os_printf( "rtc time init...\r\n"); 25 | 26 | rtcTime.magic = RTC_MAGIC; 27 | rtcTime.timeAcc = 0; 28 | rtcTime.timeBase = system_get_rtc_time(); 29 | 30 | os_printf( "time base: %d \r\n", rtcTime.timeBase ); 31 | } 32 | 33 | os_printf("===================\r\n"); 34 | os_printf("RTC time test\r\n"); 35 | 36 | uint32 rtcT1, rtcT2; 37 | uint32 st1, st2; 38 | uint32 cal1, cal2; 39 | 40 | rtcT1 = system_get_rtc_time(); 41 | st1 = system_get_time(); 42 | 43 | cal1 = system_rtc_clock_cali_proc(); 44 | os_delay_us(300); 45 | 46 | st2 = system_get_time(); 47 | rtcT2 = system_get_rtc_time(); 48 | 49 | cal2 = system_rtc_clock_cali_proc(); 50 | 51 | os_printf(" RTC t2 - t1: %d \r\n", rtcT2 - rtcT1); 52 | os_printf(" SYS t2 - t1: %d \r\n", st2 - st1); 53 | os_printf("Cal 1: %d.%d \r\n", ((cal1 * 1000) >> 12) / 1000, ((cal1 * 1000) >> 12) % 1000 ); 54 | os_printf("Cal 2: %d.%d \r\n", ((cal2 * 1000) >> 12) / 1000, ((cal2 * 1000) >> 12) % 1000 ); 55 | 56 | os_printf("===================\r\n"); 57 | 58 | rtcTime.timeAcc += ( ((uint64) (rtcT2 - rtcTime.timeBase)) * ((uint64) ((cal2 * 1000) >> 12)) ); 59 | 60 | os_printf("RTC time accuracy: %lld \r\n", rtcTime.timeAcc); 61 | os_printf("Power on time: \r\n"); 62 | os_printf(" - %lld us\r\n", rtcTime.timeAcc / 1000); 63 | os_printf(" - %lld.%02lld S\r\n", (rtcTime.timeAcc / 10000000) / 100, (rtcTime.timeAcc / 10000000) % 100); 64 | 65 | rtcTime.timeBase = rtcT2; 66 | system_rtc_mem_write(64, &rtcTime, sizeof(rtcTime)); 67 | 68 | os_printf("-----------------------------\r\n"); 69 | 70 | if ( 5 == (count++) ) 71 | { 72 | os_printf("System restart\r\n"); 73 | system_restart(); 74 | } 75 | else 76 | { 77 | os_printf("Continue...\r\n\r\n"); 78 | } 79 | } 80 | 81 | 82 | void user_init(void) 83 | { 84 | uart_init(BIT_RATE_115200, BIT_RATE_115200); 85 | rtcCount(); 86 | 87 | os_printf("SDK version:%s\n", system_get_sdk_version()); 88 | 89 | os_timer_disarm(&rtc_test_t); 90 | os_timer_setfn(&rtc_test_t, rtcCount, NULL); 91 | os_timer_arm(&rtc_test_t, 10000, 1); 92 | } 93 | 94 | --------------------------------------------------------------------------------