Page 1 of 1

undefined reference to `uart0_tx_buffer'

Posted: Mon Jan 22, 2018 9:08 am
by AgentSmithers
Hi Everyone!
When I compile this sample code it's kicking off this error. Is there a Libary I am missing in my Makefile for UART to function?

Main.c

Code: Select all

#include "ets_sys.h"
#include "osapi.h"
#include "gpio.h"
#include "os_type.h"
#include "ip_addr.h"
#include "mem.h"
#include "user_interface.h"
#include "lwip/stats.h"
#include "espconn.h"

#include "c_types.h" ////ONE WIRE

#include "../library/uart.h" //Copy these from your Driver Lib to your local folder
#include "../library/gpio16.h" //Copy these from your Driver Lib to your local folder

#include "../library/common.h"

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

#define user_procTaskPrio        0
#define user_procTaskQueueLen    1
os_event_t user_procTaskQueue[user_procTaskQueueLen];

static const int LEDpin = 2; //LED
void uart0_tx_buffer(uint8 *buf, uint16 len);

LOCAL void uart0_rx_intr_handler(void *para)
{
   os_printf(para);
}

void ICACHE_FLASH_ATTR sdk_init_done_cb(void)
{
   os_printf("[%s] initializing ESP8266!\n", __func__);
   uart0_tx_buffer("test", 4);
   //uart1_sendStr_no_wait("test");
}

void ICACHE_FLASH_ATTR user_init()
{
   
   //void   uart0_tx_buffer(uint8   *buf,   uint16   len)
   uart_div_modify(0, UART_CLK_FREQ / 115200);
   wifi_set_opmode(0);
   wifi_set_sleep_type( NONE_SLEEP_T );

   ETS_GPIO_INTR_DISABLE();// Disable gpio interrupts
   gpio_init();   

   SetAllGPIOPinsAsOutput();

   /* Need to fix this to display value   */
   uint32 VDDADCByte[4] = {0};
   spi_flash_read(0x3fc06b, (uint32 *)&VDDADCByte, 1); //Read pads the other 3 bytes with FF

   os_printf("\r\n\r\nStarting ESP8266 OTA!\r\nSDK version:%s\r\nLoaded from: %02x\r\nVdd33_Const: %02x\r\n", system_get_sdk_version(), system_get_userbin_addr(), (VDDADCByte[0] & 0xff));
   //Turn off LED
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
   gpio_output_set((1 << 2), 0, 0, 0);

   //Start os task
   system_init_done_cb(sdk_init_done_cb);
   //system_os_task(loop, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen); //Task to Signal for later
}


Uart.h

Code: Select all

/*
 * ESPRSSIF MIT License
 *
 * Copyright (c) 2016 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
 *
 * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
 * it is free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#ifndef UART_APP_H
#define UART_APP_H

#include "uart_register.h"
#include "eagle_soc.h"
#include "c_types.h"

#define UART_TX_BUFFER_SIZE 256  //Ring buffer length of tx buffer
#define UART_RX_BUFFER_SIZE 256 //Ring buffer length of rx buffer

#define UART_BUFF_EN  0   //use uart buffer  , FOR UART0
#define UART_SELFTEST  0  //set 1:enable the loop test demo for uart buffer, FOR UART0

#define UART_HW_RTS   0   //set 1: enable uart hw flow control RTS, PIN MTDO, FOR UART0
#define UART_HW_CTS  0    //set1: enable uart hw flow contrl CTS , PIN MTCK, FOR UART0




#define UART0   0
#define UART1   1


typedef enum {
    FIVE_BITS = 0x0,
    SIX_BITS = 0x1,
    SEVEN_BITS = 0x2,
    EIGHT_BITS = 0x3
} UartBitsNum4Char;

typedef enum {
    ONE_STOP_BIT             = 0x1,
    ONE_HALF_STOP_BIT        = 0x2,
    TWO_STOP_BIT             = 0x3
} UartStopBitsNum;

typedef enum {
    NONE_BITS = 0x2,
    ODD_BITS   = 1,
    EVEN_BITS = 0
} UartParityMode;

typedef enum {
    STICK_PARITY_DIS   = 0,
    STICK_PARITY_EN    = 1
} UartExistParity;

typedef enum {
    UART_None_Inverse = 0x0,
    UART_Rxd_Inverse = UART_RXD_INV,
    UART_CTS_Inverse = UART_CTS_INV,
    UART_Txd_Inverse = UART_TXD_INV,
    UART_RTS_Inverse = UART_RTS_INV,
} UART_LineLevelInverse;


typedef enum {
    BIT_RATE_300 = 300,
    BIT_RATE_600 = 600,
    BIT_RATE_1200 = 1200,
    BIT_RATE_2400 = 2400,
    BIT_RATE_4800 = 4800,
    BIT_RATE_9600   = 9600,
    BIT_RATE_19200  = 19200,
    BIT_RATE_38400  = 38400,
    BIT_RATE_57600  = 57600,
    BIT_RATE_74880  = 74880,
    BIT_RATE_115200 = 115200,
    BIT_RATE_230400 = 230400,
    BIT_RATE_460800 = 460800,
    BIT_RATE_921600 = 921600,
    BIT_RATE_1843200 = 1843200,
    BIT_RATE_3686400 = 3686400,
} UartBautRate;

typedef enum {
    NONE_CTRL,
    HARDWARE_CTRL,
    XON_XOFF_CTRL
} UartFlowCtrl;

typedef enum {
    USART_HardwareFlowControl_None = 0x0,
    USART_HardwareFlowControl_RTS = 0x1,
    USART_HardwareFlowControl_CTS = 0x2,
    USART_HardwareFlowControl_CTS_RTS = 0x3
} UART_HwFlowCtrl;

typedef enum {
    EMPTY,
    UNDER_WRITE,
    WRITE_OVER
} RcvMsgBuffState;

typedef struct {
    uint32     RcvBuffSize;
    uint8     *pRcvMsgBuff;
    uint8     *pWritePos;
    uint8     *pReadPos;
    uint8      TrigLvl; //JLU: may need to pad
    RcvMsgBuffState  BuffState;
} RcvMsgBuff;

typedef struct {
    uint32   TrxBuffSize;
    uint8   *pTrxBuff;
} TrxMsgBuff;

typedef enum {
    BAUD_RATE_DET,
    WAIT_SYNC_FRM,
    SRCH_MSG_HEAD,
    RCV_MSG_BODY,
    RCV_ESC_CHAR,
} RcvMsgState;

typedef struct {
    UartBautRate         baut_rate;
    UartBitsNum4Char  data_bits;
    UartExistParity      exist_parity;
    UartParityMode        parity;   
    UartStopBitsNum   stop_bits;
    UartFlowCtrl         flow_ctrl;
    RcvMsgBuff          rcv_buff;
    TrxMsgBuff           trx_buff;
    RcvMsgState        rcv_state;
    int                      received;
    int                      buff_uart_no;  //indicate which uart use tx/rx buffer
} UartDevice;

void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
void uart0_sendStr(const char *str);


///////////////////////////////////////
#define UART_FIFO_LEN  128  //define the tx fifo length
#define UART_TX_EMPTY_THRESH_VAL 0x10


 struct UartBuffer{
    uint32     UartBuffSize;
    uint8     *pUartBuff;
    uint8     *pInPos;
    uint8     *pOutPos;
    STATUS  BuffState;
    uint16    Space;  //remanent space of the buffer
    uint8  TcpControl;
    struct  UartBuffer     *  nextBuff;
};

struct UartRxBuff{
    uint32     UartRxBuffSize;
    uint8     *pUartRxBuff;
    uint8     *pWritePos;
    uint8     *pReadPos;
    STATUS RxBuffState;
    uint32    Space;  //remanent space of the buffer
} ;

typedef enum {
    RUN = 0,
    BLOCK = 1,
} TCPState;

//void ICACHE_FLASH_ATTR uart_test_rx();
STATUS uart_tx_one_char(uint8 uart, uint8 TxChar);
STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar);
void  uart1_sendStr_no_wait(const char *str);
struct UartBuffer*  Uart_Buf_Init();


#if UART_BUFF_EN
LOCAL void  Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len);
void  uart_buf_free(struct UartBuffer* pBuff);
void  tx_buff_enq(char* pdata, uint16 data_len );
LOCAL void  tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len,  uint8 uart_no);
void  tx_start_uart_buffer(uint8 uart_no);
uint16  rx_buff_deq(char* pdata, uint16 data_len );
void  Uart_rx_buff_enq();
#endif
void  uart_rx_intr_enable(uint8 uart_no);
void  uart_rx_intr_disable(uint8 uart_no);
void uart0_tx_buffer(uint8 *buf, uint16 len);

//==============================================
#define FUNC_UART0_CTS 4
#define FUNC_U0CTS                      4
#define FUNC_U1TXD_BK                   2
#define UART_LINE_INV_MASK  (0x3f<<19)
void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len);
void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num);
void UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask);
void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode);
void UART_SetBaudrate(uint8 uart_no,uint32 baud_rate);
void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh);
void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us); //do not use if tx flow control enabled
void UART_ResetFifo(uint8 uart_no);
void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask);
void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask);
void UART_SetPrintPort(uint8 uart_no);
bool UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us);
//==============================================

#endif




My Makefile - Using "Make Flash"

Code: Select all

CC = xtensa-lx106-elf-gcc
CFLAGS = -I. -DICACHE_FLASH -mlongcalls
LDLIBS = -nostdlib -Wl,--start-group -lmain -lpwm -lnet80211 -lwpa -llwip -lpp -lphy -lc -Wl,--end-group -lgcc
LDFLAGS = -Teagle.app.v6.ld
INCLUDES = -Iinclude -I../driver_lib/include

html:
   esptool.py write_flash --flash_size 32m-c1 0x60000 index.html 0x65000 config.html
   screen /dev/ttyUSB0 115200

main-0x00000.bin: main
   echo a
   echo $(LDFLAGS)
   esptool.py elf2image $^

build-fotamain-0x81000.bin: LDFLAGS=-Teagle.app.v6.new.2048.ld
build-fotamain-0x81000.bin: main
   esptool.py elf2image --version 2 main -o main-0x81000.bin
build-fotamain-0x01000.bin: LDFLAGS=-Teagle.app.v6.new.2048.ld
build-fotamain-0x01000.bin: main
   esptool.py elf2image --version 2 main -o main-0x01000.bin

#fotamain-0x81000.bin: LDFLAGS=-Teagle.app.v6.new.1024.app2.ld
#fotamain-0x81000.bin: LDFLAGS=-Teagle.app.v6.new.2048.app2.ld
fotamain-0x81000.bin: LDFLAGS=-Teagle.app.v6.new.2048.ld
fotamain-0x81000.bin: main
   echo b
   #echo $(LDFLAGS)
   #esptool.py elf2image --version 2 main
   #esptool.py write_flash --flash_size 32m-c1 0x81000 main-0x81000.bin
   #esptool.py write_flash --flash_size 32m-c1 0x101000 main-0x101000.bin
   #esptool.py write_flash --flash_size detect 0x101000 main-0x81000.bin
   esptool.py write_flash --flash_size 32m-c1 0x101000 main-0x01000.bin
   
#fotamain-0x01000.bin: LDFLAGS=-Teagle.app.v6.new.1024.app1.ld
#For some reason the flag below is not applying
fotamain-0x01000.bin: LDFLAGS=-Teagle.app.v6.new.2048.ld
fotamain-0x01000.bin: main
   echo c
   echo $(LDFLAGS)
   esptool.py elf2image --version 2 main   
   esptool.py write_flash --flash_size 32m-c1 0 boot_v1.7.bin 0x1000 main-0x01000.bin 0x7e000 blank.bin 0xFE000 blank.bin 0x3FC000 ../library/esp_init_data_default_adc33.bin 0x60000 index.html 0x65000 config.html

main: main.o

main.o: main.c

dhonewire: dhonewire.o

dhonewire.o: dhonewire.c

fresh: clean main-0x00000.bin
   echo d
   echo $(LDFLAGS)
   #kill $(ps aux | grep '[S]CREEN' | awk '{print $2}')
   esptool.py erase_flash
   esptool.py write_flash 0 main-0x00000.bin 0x10000 main-0x10000.bin 0x7e000 blank.bin 0x3fc000 ../library/esp_init_data_default_adc33.bin 0x3fe000 blank.bin 0x60000 index.html 0x65000 config.html
   #screen /dev/ttyUSB0 74880
   screen /dev/ttyUSB0 115200

flash: LDFLAGS=-Teagle.app.v6.ld
flash: main-0x00000.bin
   echo e
   echo $(LDFLAGS)
   esptool.py write_flash 0 main-0x00000.bin 0x10000 main-0x10000.bin 0x60000 index.html 0x65000 config.html
   screen /dev/ttyUSB0 115200

quick: main-0x00000.bin
   echo f
   echo $(LDFLAGS)
   esptool.py write_flash 0 main-0x00000.bin 0x10000 main-0x10000.bin

build: main-0x00000.bin
   echo g
   echo $(LDFLAGS)

ota: fotamain-0x01000.bin fotamain-0x81000.bin
   #export -p
   echo h
   echo $(LDFLAGS)
   #esptool.py write_flash --flash_size 32m-c1 0x81000 main-0x81000.bin

screen:
   screen /dev/ttyUSB0 115200

clean:
   echo i
   rm -f main main.o main*.bin
   #echo 'osboxes.org' | sudo -S chmod 777 /dev/ttyUSB0 #No longer needed, osboxes added to dialout group with usermod

cleanall:
   echo j
   rm -f main main.o main-0x00000.bin main-0x10000.bin main-0x81000.bin main-0x01000.bin

   

Re: undefined reference to `uart0_tx_buffer'

Posted: Mon Jan 22, 2018 11:20 am
by AgentSmithers
I fixed it, I guess my makefile needs a uart.c and I need to include it so it compiled into the .o (object format)
I perfer not to do this so I just inlined the .C data into my UART.h
Any reason not to do this?

uart.h

Code: Select all

/*
 * ESPRSSIF MIT License
 *
 * Copyright (c) 2016 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
 *
 * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
 * it is free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#ifndef UART_APP_H
#define UART_APP_H

#include "uart_register.h"
#include "eagle_soc.h"
#include "c_types.h"
//#include "task.h"
#define recvTaskPrio        0
#define recvTaskQueueLen    64
//
#define UART_TX_BUFFER_SIZE 256  //Ring buffer length of tx buffer
#define UART_RX_BUFFER_SIZE 256 //Ring buffer length of rx buffer

#define UART_BUFF_EN  0   //use uart buffer  , FOR UART0
#define UART_SELFTEST  0  //set 1:enable the loop test demo for uart buffer, FOR UART0

#define UART_HW_RTS   0   //set 1: enable uart hw flow control RTS, PIN MTDO, FOR UART0
#define UART_HW_CTS  0    //set1: enable uart hw flow contrl CTS , PIN MTCK, FOR UART0

#define UART0   0
#define UART1   1

//calc bit 0..5 for  UART_CONF0 register
#define CALC_UARTMODE(data_bits,parity,stop_bits) \
   (((parity == NONE_BITS) ? 0x0 : (UART_PARITY_EN | (parity & UART_PARITY))) | \
   ((stop_bits & UART_STOP_BIT_NUM) << UART_STOP_BIT_NUM_S) | \
   ((data_bits & UART_BIT_NUM) << UART_BIT_NUM_S))
//get data_bits from UART_CONF0 register
#define GETUART_DATABITS(uartmode) ((uartmode >> UART_BIT_NUM_S) & UART_BIT_NUM)
//get stop_bits from UART_CONF0 register
#define GETUART_STOPBITS(uartmode) ((uartmode >> UART_STOP_BIT_NUM_S) & UART_STOP_BIT_NUM)
//get parity from UART_CONF0 register
#define GETUART_PARITYMODE(uartmode) ((uartmode & UART_PARITY_EN) ? uartmode & UART_PARITY : NONE_BITS)


typedef enum {
    FIVE_BITS = 0x0,
    SIX_BITS = 0x1,
    SEVEN_BITS = 0x2,
    EIGHT_BITS = 0x3
} UartBitsNum4Char;

typedef enum {
    ONE_STOP_BIT             = 0x1,
    ONE_HALF_STOP_BIT        = 0x2,
    TWO_STOP_BIT             = 0x3
} UartStopBitsNum;

typedef enum {
    NONE_BITS = 0x2,
    ODD_BITS   = 1,
    EVEN_BITS = 0
} UartParityMode;

typedef enum {
    STICK_PARITY_DIS   = 0,
    STICK_PARITY_EN    = 1
} UartExistParity;

typedef enum {
    UART_None_Inverse = 0x0,
    UART_Rxd_Inverse = UART_RXD_INV,
    UART_CTS_Inverse = UART_CTS_INV,
    UART_Txd_Inverse = UART_TXD_INV,
    UART_RTS_Inverse = UART_RTS_INV,
} UART_LineLevelInverse;


typedef enum {
    BIT_RATE_300 = 300,
    BIT_RATE_600 = 600,
    BIT_RATE_1200 = 1200,
    BIT_RATE_2400 = 2400,
    BIT_RATE_4800 = 4800,
    BIT_RATE_9600   = 9600,
    BIT_RATE_19200  = 19200,
    BIT_RATE_38400  = 38400,
    BIT_RATE_57600  = 57600,
    BIT_RATE_74880  = 74880,
    BIT_RATE_115200 = 115200,
    BIT_RATE_230400 = 230400,
    BIT_RATE_460800 = 460800,
    BIT_RATE_921600 = 921600,
    BIT_RATE_1843200 = 1843200,
    BIT_RATE_3686400 = 3686400,
} UartBautRate;

typedef enum {
    NONE_CTRL,
    HARDWARE_CTRL,
    XON_XOFF_CTRL
} UartFlowCtrl;

typedef enum {
    USART_HardwareFlowControl_None = 0x0,
    USART_HardwareFlowControl_RTS = 0x1,
    USART_HardwareFlowControl_CTS = 0x2,
    USART_HardwareFlowControl_CTS_RTS = 0x3
} UART_HwFlowCtrl;

typedef enum {
    EMPTY,
    UNDER_WRITE,
    WRITE_OVER
} RcvMsgBuffState;

typedef struct {
    uint32     RcvBuffSize;
    uint8     *pRcvMsgBuff;
    uint8     *pWritePos;
    uint8     *pReadPos;
    uint8      TrigLvl; //JLU: may need to pad
    RcvMsgBuffState  BuffState;
} RcvMsgBuff;

typedef struct {
    uint32   TrxBuffSize;
    uint8   *pTrxBuff;
} TrxMsgBuff;

typedef enum {
    BAUD_RATE_DET,
    WAIT_SYNC_FRM,
    SRCH_MSG_HEAD,
    RCV_MSG_BODY,
    RCV_ESC_CHAR,
} RcvMsgState;

typedef struct {
    UartBautRate         baut_rate;
    UartBitsNum4Char  data_bits;
    UartExistParity      exist_parity;
    UartParityMode        parity;   
    UartStopBitsNum   stop_bits;
    UartFlowCtrl         flow_ctrl;
    RcvMsgBuff          rcv_buff;
    TrxMsgBuff           trx_buff;
    RcvMsgState        rcv_state;
    int                      received;
    int                      buff_uart_no;  //indicate which uart use tx/rx buffer
} UartDevice;

void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
void uart0_sendStr(const char *str);


///////////////////////////////////////
#define UART_FIFO_LEN  128  //define the tx fifo length
#define UART_TX_EMPTY_THRESH_VAL 0x10


 struct UartBuffer{
    uint32     UartBuffSize;
    uint8     *pUartBuff;
    uint8     *pInPos;
    uint8     *pOutPos;
    STATUS  BuffState;
    uint16    Space;  //remanent space of the buffer
    uint8  TcpControl;
    struct  UartBuffer     *  nextBuff;
};

struct UartRxBuff{
    uint32     UartRxBuffSize;
    uint8     *pUartRxBuff;
    uint8     *pWritePos;
    uint8     *pReadPos;
    STATUS RxBuffState;
    uint32    Space;  //remanent space of the buffer
} ;

typedef enum {
    RUN = 0,
    BLOCK = 1,
} TCPState;

//void ICACHE_FLASH_ATTR uart_test_rx();
//STATUS uart_tx_one_char(uint8 uart, uint8 TxChar);
STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar);
void  uart1_sendStr_no_wait(const char *str);
struct UartBuffer*  Uart_Buf_Init();


#if UART_BUFF_EN
LOCAL void  Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len);
void  uart_buf_free(struct UartBuffer* pBuff);
void  tx_buff_enq(char* pdata, uint16 data_len );
LOCAL void  tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len,  uint8 uart_no);
void  tx_start_uart_buffer(uint8 uart_no);
uint16  rx_buff_deq(char* pdata, uint16 data_len );
void  Uart_rx_buff_enq();
#endif
void  uart_rx_intr_enable(uint8 uart_no);
void  uart_rx_intr_disable(uint8 uart_no);
void uart0_tx_buffer(uint8 *buf, uint16 len);

//==============================================
#define FUNC_UART0_CTS 4
#define FUNC_U0CTS                      4
#define FUNC_U1TXD_BK                   2
#define UART_LINE_INV_MASK  (0x3f<<19)
void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len);
void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num);
void UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask);
void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode);
void UART_SetBaudrate(uint8 uart_no,uint32 baud_rate);
void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh);
void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us); //do not use if tx flow control enabled
void UART_ResetFifo(uint8 uart_no);
void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask);
void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask);
void UART_SetPrintPort(uint8 uart_no);
bool UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us);
//==============================================

#endif




/*
 * File   : uart.c
 * This file is part of Espressif's AT+ command set program.
 * Copyright (C) 2013 - 2016, Espressif Systems
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of version 3 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/*#include "ets_sys.h"
#include "osapi.h"
#include "driver/uart.h"
#include "osapi.h"
#include "driver/uart_register.h"
//#include "ssc.h"
#include "task.h"
*/
// UartDev is defined and initialized in rom code.
extern UartDevice    UartDev;
//extern os_event_t    at_recvTaskQueue[at_recvTaskQueueLen];

LOCAL void uart0_rx_intr_handler(void *para);

/******************************************************************************
 * FunctionName : uart_config
 * Description  : Internal used function
 *                UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
 *                UART1 just used for debug output
 * Parameters   : uart_no, use UART0 or UART1 defined ahead
 * Returns      : NONE
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
uart_config(uint8 uart_no)
{
  if (uart_no == UART1)
  {
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
  }
  else
  {
    /* rcv_buff size if 0x100 */
    ETS_UART_INTR_ATTACH(uart0_rx_intr_handler,  &(UartDev.rcv_buff));
    PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
  }

  uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));

  if (uart_no == UART1)  //UART 1 always 8 N 1
     WRITE_PERI_REG(UART_CONF0(uart_no), CALC_UARTMODE(EIGHT_BITS, NONE_BITS, ONE_STOP_BIT));
  else
     WRITE_PERI_REG(UART_CONF0(uart_no), CALC_UARTMODE(UartDev.data_bits, UartDev.parity, UartDev.stop_bits));

  //clear rx and tx fifo,not ready
  SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
  CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);

  //set rx fifo trigger
//  WRITE_PERI_REG(UART_CONF1(uart_no),
//                 ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
//                 ((96 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) |
//                 UART_RX_FLOW_EN);
  if (uart_no == UART0)
  {
    //set rx fifo trigger
    WRITE_PERI_REG(UART_CONF1(uart_no),
                   ((0x10 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
                   ((0x10 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) |
                   UART_RX_FLOW_EN |
                   (0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S |
                   UART_RX_TOUT_EN);
    SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA |
                      UART_FRM_ERR_INT_ENA);
  }
  else
  {
    WRITE_PERI_REG(UART_CONF1(uart_no),
                   ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));
  }

  //clear all interrupt
  WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
  //enable rx_interrupt
  SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA);
}

/******************************************************************************
 * FunctionName : uart1_tx_one_char
 * Description  : Internal used function
 *                Use uart1 interface to transfer one char
 * Parameters   : uint8 TxChar - character to tx
 * Returns      : OK
*******************************************************************************/
LOCAL STATUS
uart_tx_one_char(uint8 uart, uint8 TxChar)
{
    while (true)
    {
      uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
      if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
        break;
      }
    }

    WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
    return OK;
}

/******************************************************************************
 * FunctionName : uart1_write_char
 * Description  : Internal used function
 *                Do some special deal while tx char is '\r' or '\n'
 * Parameters   : char c - character to tx
 * Returns      : NONE
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
uart1_write_char(char c)
{
  if (c == '\n')
  {
    uart_tx_one_char(UART1, '\r');
    uart_tx_one_char(UART1, '\n');
  }
  else if (c == '\r')
  {
  }
  else
  {
    uart_tx_one_char(UART1, c);
  }
}
/******************************************************************************
 * FunctionName : uart0_tx_buffer
 * Description  : use uart0 to transfer buffer
 * Parameters   : uint8 *buf - point to send buffer
 *                uint16 len - buffer len
 * Returns      :
*******************************************************************************/
void ICACHE_FLASH_ATTR
uart0_tx_buffer(uint8 *buf, uint16 len)
{
  uint16 i;

  for (i = 0; i < len; i++)
  {
    uart_tx_one_char(UART0, buf[i]);
  }
}

/******************************************************************************
 * FunctionName : uart0_sendStr
 * Description  : use uart0 to transfer buffer
 * Parameters   : uint8 *buf - point to send buffer
 *                uint16 len - buffer len
 * Returns      :
*******************************************************************************/
void ICACHE_FLASH_ATTR
uart0_sendStr(const char *str)
{
   while(*str)
   {
      uart_tx_one_char(UART0, *str++);
   }
}

/******************************************************************************
 * FunctionName : uart0_rx_intr_handler
 * Description  : Internal used function
 *                UART0 interrupt handler, add self handle code inside
 * Parameters   : void *para - point to ETS_UART_INTR_ATTACH's arg
 * Returns      : NONE
*******************************************************************************/
//extern void at_recvTask(void);

LOCAL void
uart0_rx_intr_handler(void *para)
{
  /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
    * uart1 and uart0 respectively
    */
//  RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
  uint8 RcvChar;
  uint8 uart_no = UART0;//UartDev.buff_uart_no;

//  if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
//  {
//    return;
//  }
//  if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
//  {
////    at_recvTask();
//    RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
//    system_os_post(at_recvTaskPrio, NULL, RcvChar);
//    WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
//  }
  if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST))
  {
    os_printf("FRM_ERR\r\n");
    WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
  }

  if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
  {
//    os_printf("fifo full\r\n");
    ETS_UART_INTR_DISABLE();/////////

    system_os_post(recvTaskPrio, 0, 0);

//    WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
//    while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S))
//    {
////      at_recvTask();
//      RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
//      system_os_post(at_recvTaskPrio, NULL, RcvChar);
//    }
  }
  else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST))
  {
    ETS_UART_INTR_DISABLE();/////////

//    os_printf("stat:%02X",*(uint8 *)UART_INT_ENA(uart_no));
    system_os_post(recvTaskPrio, 0, 0);

//    WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_TOUT_INT_CLR);
////    os_printf("rx time over\r\n");
//    while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S))
//    {
////      os_printf("process recv\r\n");
////      at_recvTask();
//      RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
//      system_os_post(at_recvTaskPrio, NULL, RcvChar);
//    }
  }

//  WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);

//  if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S))
//  {
//    RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
//    at_recvTask();
//    *(pRxBuff->pWritePos) = RcvChar;

//    system_os_post(at_recvTaskPrio, NULL, RcvChar);

//    //insert here for get one command line from uart
//    if (RcvChar == '\r')
//    {
//      pRxBuff->BuffState = WRITE_OVER;
//    }
//
//    pRxBuff->pWritePos++;
//
//    if (pRxBuff->pWritePos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE))
//    {
//      // overflow ...we may need more error handle here.
//      pRxBuff->pWritePos = pRxBuff->pRcvMsgBuff ;
//    }
//  }
}

/******************************************************************************
 * FunctionName : uart_init
 * Description  : user interface for init uart
 * Parameters   : UartBautRate uart0_br - uart0 bautrate
 *                UartBautRate uart1_br - uart1 bautrate
 * Returns      : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR
uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
{
  // rom use 74880 baut_rate, here reinitialize
  UartDev.baut_rate = uart0_br;
  uart_config(UART0);
  UartDev.baut_rate = uart1_br;
  uart_config(UART1);
  ETS_UART_INTR_ENABLE();

  // install uart1 putc callback
  os_install_putc1((void *)uart1_write_char);
}

void ICACHE_FLASH_ATTR
uart_reattach()
{
   uart_init(BIT_RATE_74880, BIT_RATE_74880);
//  ETS_UART_INTR_ATTACH(uart_rx_intr_handler_ssc,  &(UartDev.rcv_buff));
//  ETS_UART_INTR_ENABLE();
}