1102 lines
29 KiB
C
1102 lines
29 KiB
C
|
#include <stdio.h>
|
|||
|
#include <stddef.h>
|
|||
|
#include <string.h>
|
|||
|
|
|||
|
#include "FreeRTOS.h"
|
|||
|
#include "chip.h"
|
|||
|
#include "board.h"
|
|||
|
#include "serial.h"
|
|||
|
#include "sysinfo.h"
|
|||
|
|
|||
|
/* UART Register Offsets. */
|
|||
|
#define UART_DR 0x00 /* Data read or written from the interface. */
|
|||
|
#define UART_RSR 0x04 /* Receive status register (Read). */
|
|||
|
#define UART_FR 0x18 /* Flag register (Read only). */
|
|||
|
#define UART_ILPR 0x20 /* IrDA low power counter register. */
|
|||
|
#define UART_IBRD 0x24 /* Integer baud rate divisor register. */
|
|||
|
#define UART_FBRD 0x28 /* Fractional baud rate divisor register. */
|
|||
|
#define UART_LCRH 0x2c /* Line control register. */
|
|||
|
#define UART_CR 0x30 /* Control register. */
|
|||
|
#define UART_IFLS 0x34 /* Interrupt fifo level select. */
|
|||
|
#define UART_IMSC 0x38 /* Interrupt mask. */
|
|||
|
#define UART_RIS 0x3c /* Raw interrupt status. */
|
|||
|
#define UART_MIS 0x40 /* Masked interrupt status. */
|
|||
|
#define UART_ICR 0x44 /* Interrupt clear register. */
|
|||
|
#define UART_DMACR 0x48 /* DMA control register. */
|
|||
|
|
|||
|
|
|||
|
#define UART_DR_OE (1 << 11)
|
|||
|
#define UART_DR_BE (1 << 10)
|
|||
|
#define UART_DR_PE (1 << 9)
|
|||
|
#define UART_DR_FE (1 << 8)
|
|||
|
|
|||
|
#define UART_RSR_OE 0x08
|
|||
|
#define UART_RSR_BE 0x04
|
|||
|
#define UART_RSR_PE 0x02
|
|||
|
#define UART_RSR_FE 0x01
|
|||
|
|
|||
|
#define UART_FR_RI 0x100
|
|||
|
#define UART_FR_TXFE 0x080
|
|||
|
#define UART_FR_RXFF 0x040
|
|||
|
#define UART_FR_TXFF 0x020
|
|||
|
#define UART_FR_RXFE 0x010
|
|||
|
#define UART_FR_BUSY 0x008
|
|||
|
#define UART_FR_DCD 0x004
|
|||
|
#define UART_FR_DSR 0x002
|
|||
|
#define UART_FR_CTS 0x001
|
|||
|
#define UART_FR_TMSK (UART_FR_TXFF + UART_FR_BUSY)
|
|||
|
|
|||
|
#define UART_CR_CTSEN 0x8000 /* CTS hardware flow control */
|
|||
|
#define UART_CR_RTSEN 0x4000 /* RTS hardware flow control */
|
|||
|
#define UART_CR_OUT2 0x2000 /* OUT2 */
|
|||
|
#define UART_CR_OUT1 0x1000 /* OUT1 */
|
|||
|
#define UART_CR_RTS 0x0800 /* RTS */
|
|||
|
#define UART_CR_DTR 0x0400 /* DTR */
|
|||
|
#define UART_CR_RXE 0x0200 /* receive enable */
|
|||
|
#define UART_CR_TXE 0x0100 /* transmit enable */
|
|||
|
#define UART_CR_LBE 0x0080 /* loopback enable */
|
|||
|
#define UART_CR_RTIE 0x0040
|
|||
|
#define UART_CR_TIE 0x0020
|
|||
|
#define UART_CR_RIE 0x0010
|
|||
|
#define UART_CR_MSIE 0x0008
|
|||
|
#define UART_CR_IIRLP 0x0004 /* SIR low power mode */
|
|||
|
#define UART_CR_SIREN 0x0002 /* SIR enable */
|
|||
|
#define UART_CR_UARTEN 0x0001 /* UART enable */
|
|||
|
|
|||
|
#define UART_LCRH_SPS 0x80
|
|||
|
#define UART_LCRH_WLEN_8 0x60
|
|||
|
#define UART_LCRH_WLEN_7 0x40
|
|||
|
#define UART_LCRH_WLEN_6 0x20
|
|||
|
#define UART_LCRH_WLEN_5 0x00
|
|||
|
#define UART_LCRH_FEN 0x10
|
|||
|
#define UART_LCRH_STP2 0x08
|
|||
|
#define UART_LCRH_EPS 0x04
|
|||
|
#define UART_LCRH_PEN 0x02
|
|||
|
#define UART_LCRH_BRK 0x01
|
|||
|
|
|||
|
|
|||
|
#define UART_IFLS_RX1_8 (0 << 3)
|
|||
|
#define UART_IFLS_RX2_8 (1 << 3)
|
|||
|
#define UART_IFLS_RX4_8 (2 << 3)
|
|||
|
#define UART_IFLS_RX6_8 (3 << 3)
|
|||
|
#define UART_IFLS_RX7_8 (4 << 3)
|
|||
|
#define UART_IFLS_TX1_8 (0 << 0)
|
|||
|
#define UART_IFLS_TX2_8 (1 << 0)
|
|||
|
#define UART_IFLS_TX4_8 (2 << 0)
|
|||
|
#define UART_IFLS_TX6_8 (3 << 0)
|
|||
|
#define UART_IFLS_TX7_8 (4 << 0)
|
|||
|
|
|||
|
#define UART_OEIM (1 << 10) /* overrun error interrupt mask */
|
|||
|
#define UART_BEIM (1 << 9) /* break error interrupt mask */
|
|||
|
#define UART_PEIM (1 << 8) /* parity error interrupt mask */
|
|||
|
#define UART_FEIM (1 << 7) /* framing error interrupt mask */
|
|||
|
#define UART_RTIM (1 << 6) /* receive timeout interrupt mask */
|
|||
|
#define UART_TXIM (1 << 5) /* transmit interrupt mask */
|
|||
|
#define UART_RXIM (1 << 4) /* receive interrupt mask */
|
|||
|
#define UART_DSRMIM (1 << 3) /* DSR interrupt mask */
|
|||
|
#define UART_DCDMIM (1 << 2) /* DCD interrupt mask */
|
|||
|
#define UART_CTSMIM (1 << 1) /* CTS interrupt mask */
|
|||
|
#define UART_RIMIM (1 << 0) /* RI interrupt mask */
|
|||
|
|
|||
|
#define UART_OEIS (1 << 10) /* overrun error interrupt status */
|
|||
|
#define UART_BEIS (1 << 9) /* break error interrupt status */
|
|||
|
#define UART_PEIS (1 << 8) /* parity error interrupt status */
|
|||
|
#define UART_FEIS (1 << 7) /* framing error interrupt status */
|
|||
|
#define UART_RTIS (1 << 6) /* receive timeout interrupt status */
|
|||
|
#define UART_TXIS (1 << 5) /* transmit interrupt status */
|
|||
|
#define UART_RXIS (1 << 4) /* receive interrupt status */
|
|||
|
#define UART_DSRMIS (1 << 3) /* DSR interrupt status */
|
|||
|
#define UART_DCDMIS (1 << 2) /* DCD interrupt status */
|
|||
|
#define UART_CTSMIS (1 << 1) /* CTS interrupt status */
|
|||
|
#define UART_RIMIS (1 << 0) /* RI interrupt status */
|
|||
|
|
|||
|
|
|||
|
#define UART485_RBR_THR_DLL 0x000
|
|||
|
#define UART485_DLH_IER 0x004
|
|||
|
#define UART485_IIR_FCR 0x008
|
|||
|
#define UART485_RBR 0x000
|
|||
|
#define UART485_THR 0x000
|
|||
|
#define UART485_DLL 0x000
|
|||
|
#define UART485_DLH 0x004
|
|||
|
#define UART485_IER 0x004
|
|||
|
#define UART485_IIR 0x008
|
|||
|
#define UART485_FCR 0x008
|
|||
|
#define UART485_LCR 0x00C
|
|||
|
#define UART485_MCR 0x010
|
|||
|
#define UART485_LSR 0x014
|
|||
|
#define UART485_MSR 0x018
|
|||
|
#define UART485_SCR 0x01C
|
|||
|
#define UART485_LPDLL 0x020
|
|||
|
#define UART485_LPDLH 0x024
|
|||
|
#define UART485_RESERVED 0x028
|
|||
|
#define UART485_SRBR 0x030
|
|||
|
#define UART485_STHR 0x06C
|
|||
|
#define UART485_FAR 0x070
|
|||
|
#define UART485_TFR 0x074
|
|||
|
#define UART485_RFW 0x078
|
|||
|
#define UART485_USR 0x07C
|
|||
|
#define UART485_TFL 0x080
|
|||
|
#define UART485_RFL 0x084
|
|||
|
#define UART485_SRR 0x088
|
|||
|
#define UART485_SRTS 0x08C
|
|||
|
#define UART485_SBCR 0x090
|
|||
|
#define UART485_SDMAM 0x094
|
|||
|
#define UART485_SFE 0x098
|
|||
|
#define UART485_SRT 0x09C
|
|||
|
#define UART485_STET 0x0A0
|
|||
|
#define UART485_HTX 0x0A4
|
|||
|
#define UART485_DMASA 0x0A8
|
|||
|
#define UART485_TCR 0x0AC
|
|||
|
#define UART485_DE_EN 0x0B0
|
|||
|
#define UART485_RE_EN 0x0B4
|
|||
|
#define UART485_DET 0x0B8
|
|||
|
#define UART485_TAT 0x0BC
|
|||
|
#define UART485_DLF 0x0C0
|
|||
|
#define UART485_RAR 0x0C4
|
|||
|
#define UART485_TAR 0x0C8
|
|||
|
#define UART485_LCR_EXT 0x0CC
|
|||
|
#define UART485_CPR 0x0F4
|
|||
|
#define UART485_UCV 0x0F8
|
|||
|
#define UART485_CTR 0x0FC
|
|||
|
|
|||
|
#define UART485_LSR_RFE (1 << 7)
|
|||
|
#define UART485_LSR_TEMT (1 << 6)
|
|||
|
#define UART485_LSR_THRE (1 << 5)
|
|||
|
#define UART485_LSR_BI (1 << 4)
|
|||
|
#define UART485_LSR_FE (1 << 3)
|
|||
|
#define UART485_LSR_PE (1 << 2)
|
|||
|
#define UART485_LSR_OE (1 << 1)
|
|||
|
#define UART485_LSR_DR (1 << 0)
|
|||
|
|
|||
|
#define UART485_IIR_IID_MASK (0xf << 0)
|
|||
|
#define UART485_IIR_IID_MODEM_STATUS 0x0
|
|||
|
#define UART485_IIR_IID_NO_INT_PENDING 0x1
|
|||
|
#define UART485_IIR_IID_THR_EMPTY 0x2
|
|||
|
#define UART485_IIR_IID_REV_DATA_AVAIL 0x4
|
|||
|
#define UART485_IIR_IID_REV_LINE_STATUS 0x6
|
|||
|
#define UART485_IIR_IID_BUSY_DETECT 0x7
|
|||
|
#define UART485_IIR_IID_CHAR_TIMEOUT 0xc
|
|||
|
|
|||
|
|
|||
|
#define CSIZE 0x0003
|
|||
|
#define CS8 0x0000
|
|||
|
#define CS6 0x0001
|
|||
|
#define CS7 0x0002
|
|||
|
#define CS5 0x0003
|
|||
|
#define CSTOPB 0x0004
|
|||
|
#define PARENB 0x0010
|
|||
|
#define PARODD 0x0020
|
|||
|
#define CMSPAR 0x0100 /* mark or space (stick) parity */
|
|||
|
#define CRTSCTS 0x0200 /* flow control */
|
|||
|
|
|||
|
#define UART_CLK 24000000
|
|||
|
#define UART_DEBUG_PORT UART_ID0
|
|||
|
|
|||
|
#define UART_BUF_SIZE 4096
|
|||
|
#define UART_ISR_PASS_LIMIT 16
|
|||
|
|
|||
|
#define UART_BLOCK_TIMEOUT pdMS_TO_TICKS(100)
|
|||
|
#define UART_NO_BLOCK ( ( TickType_t ) 0 )
|
|||
|
|
|||
|
static uint32_t ulUartBase[UART_NUM] = {REGS_UART0_BASE, REGS_UART1_BASE, REGS_UART2_BASE, REGS_UART3_BASE};
|
|||
|
static UartPort_t *pxUartPort[UART_NUM] = {NULL};
|
|||
|
|
|||
|
#define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
|
|||
|
#define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
|
|||
|
|
|||
|
#define uart_circ_chars_pending(circ) \
|
|||
|
(CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
|
|||
|
|
|||
|
#define uart_circ_chars_free(circ) \
|
|||
|
(CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
|
|||
|
|
|||
|
|
|||
|
/* static void vUartSlectPad(uint32_t id)
|
|||
|
{
|
|||
|
switch (id) {
|
|||
|
case UART_ID0:
|
|||
|
vSysctlConfigure(SYS_PAD_CTRL02, 12, 0xf, 5);
|
|||
|
break;
|
|||
|
case UART_ID1:
|
|||
|
vSysctlConfigure(SYS_PAD_CTRL02, 16, 0xf, 5);
|
|||
|
break;
|
|||
|
case UART_ID2:
|
|||
|
vSysctlConfigure(SYS_PAD_CTRL02, 20, 0xf, 5);
|
|||
|
break;
|
|||
|
case UART_ID3:
|
|||
|
vSysctlConfigure(SYS_PAD_CTRL02, 24, 0xf, 5);
|
|||
|
break;
|
|||
|
}
|
|||
|
} */
|
|||
|
|
|||
|
static int iUartRxChars(UartPort_t *uap)
|
|||
|
{
|
|||
|
uint32_t status;
|
|||
|
unsigned int ch, max_count = 256;
|
|||
|
int fifotaken = 0;
|
|||
|
|
|||
|
while (max_count--) {
|
|||
|
status = readl(uap->regbase + UART_FR);
|
|||
|
if (status & UART_FR_RXFE)
|
|||
|
break;
|
|||
|
|
|||
|
/* Take chars from the FIFO and update status */
|
|||
|
ch = readl(uap->regbase + UART_DR);
|
|||
|
fifotaken++;
|
|||
|
|
|||
|
/* discard when rx buf is full */
|
|||
|
if (CIRC_SPACE_TO_END(uap->rxbuf.head, uap->rxbuf.tail, UART_BUF_SIZE) > 0) {
|
|||
|
*(uap->rxbuf.buf + uap->rxbuf.head) = ch;
|
|||
|
uap->rxbuf.head = (uap->rxbuf.head + 1) & (UART_BUF_SIZE - 1);
|
|||
|
} else {
|
|||
|
;//printf("uart%d rx buf is full, discard a data.\n", uap->id);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (fifotaken > 0)
|
|||
|
xSemaphoreGiveFromISR(uap->xRev, NULL);
|
|||
|
|
|||
|
return fifotaken;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void vUartStopTx(UartPort_t *uap)
|
|||
|
{
|
|||
|
writel(readl(uap->regbase + UART_IMSC) & ~UART_TXIM, uap->regbase + UART_IMSC);
|
|||
|
}
|
|||
|
|
|||
|
static void vUartStartTx(UartPort_t *uap)
|
|||
|
{
|
|||
|
writel(readl(uap->regbase + UART_IMSC) | UART_TXIM, uap->regbase + UART_IMSC);
|
|||
|
}
|
|||
|
|
|||
|
static BaseType_t xUartTxChar(UartPort_t *uap, unsigned char c, int from_irq)
|
|||
|
{
|
|||
|
if (!from_irq && (readl(uap->regbase + UART_FR) & UART_FR_TXFF))
|
|||
|
return pdFALSE; /* unable to transmit character */
|
|||
|
|
|||
|
writel(c, uap->regbase + UART_DR);
|
|||
|
|
|||
|
return pdTRUE;
|
|||
|
}
|
|||
|
|
|||
|
/* Returns true if tx interrupts have to be (kept) enabled */
|
|||
|
static BaseType_t xUartTxChars(UartPort_t *uap, int from_irq)
|
|||
|
{
|
|||
|
struct circ_buf *xmit = &uap->txbuf;
|
|||
|
int count = uap->fifosize >> 1;
|
|||
|
|
|||
|
if (uart_circ_empty(xmit)) {
|
|||
|
vUartStopTx(uap);
|
|||
|
return pdFALSE;
|
|||
|
}
|
|||
|
|
|||
|
do {
|
|||
|
if (from_irq && count-- == 0)
|
|||
|
break;
|
|||
|
|
|||
|
if (!xUartTxChar(uap, xmit->buf[xmit->tail], from_irq))
|
|||
|
break;
|
|||
|
|
|||
|
xmit->tail = (xmit->tail + 1) & (UART_BUF_SIZE - 1);
|
|||
|
} while (!uart_circ_empty(xmit));
|
|||
|
|
|||
|
if (from_irq)
|
|||
|
xSemaphoreGiveFromISR(uap->xSend, NULL);
|
|||
|
|
|||
|
if (uart_circ_empty(xmit)) {
|
|||
|
vUartStopTx(uap);
|
|||
|
return pdFALSE;
|
|||
|
}
|
|||
|
|
|||
|
return pdTRUE;
|
|||
|
}
|
|||
|
|
|||
|
static void vUartIntHandler(void *param)
|
|||
|
{
|
|||
|
UartPort_t *uap = param;
|
|||
|
uint32_t status;
|
|||
|
uint32_t imsc;
|
|||
|
uint32_t pass_counter = UART_ISR_PASS_LIMIT;
|
|||
|
|
|||
|
imsc = readl(uap->regbase + UART_IMSC);
|
|||
|
status = readl(uap->regbase + UART_RIS) & imsc;
|
|||
|
if (status) {
|
|||
|
do {
|
|||
|
writel(status & ~(UART_TXIS | UART_RTIS | UART_RXIS),
|
|||
|
uap->regbase + UART_ICR);
|
|||
|
|
|||
|
if (status & (UART_RTIS | UART_RXIS)) {
|
|||
|
iUartRxChars(uap);
|
|||
|
}
|
|||
|
if (status & UART_TXIS)
|
|||
|
xUartTxChars(uap, pdTRUE);
|
|||
|
|
|||
|
if (pass_counter-- == 0)
|
|||
|
break;
|
|||
|
|
|||
|
status = readl(uap->regbase + UART_RIS) & imsc;
|
|||
|
} while (status != 0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void vUart485StopTx(UartPort_t *uap)
|
|||
|
{
|
|||
|
writel(readl(uap->regbase + UART485_IER) & ~(1 << 1), uap->regbase + UART485_IER);
|
|||
|
}
|
|||
|
|
|||
|
static void vUart485StartTx(UartPort_t *uap)
|
|||
|
{
|
|||
|
writel(readl(uap->regbase + UART485_IER) | (1 << 1), uap->regbase + UART485_IER);
|
|||
|
}
|
|||
|
|
|||
|
static int iUart485RxChars(UartPort_t *uap)
|
|||
|
{
|
|||
|
uint32_t lsr;
|
|||
|
unsigned int ch, max_count = 256;
|
|||
|
int fifotaken = 0;
|
|||
|
|
|||
|
while (max_count--) {
|
|||
|
lsr = readl(uap->regbase + UART485_LSR);
|
|||
|
if (!(lsr & UART485_LSR_DR))
|
|||
|
break;
|
|||
|
|
|||
|
/* Take chars from the FIFO and update status */
|
|||
|
ch = readl(uap->regbase + UART485_RBR);
|
|||
|
fifotaken++;
|
|||
|
|
|||
|
/* discard when rx buf is full */
|
|||
|
if (CIRC_SPACE_TO_END(uap->rxbuf.head, uap->rxbuf.tail, UART_BUF_SIZE) > 0) {
|
|||
|
*(uap->rxbuf.buf + uap->rxbuf.head) = ch;
|
|||
|
uap->rxbuf.head = (uap->rxbuf.head + 1) & (UART_BUF_SIZE - 1);
|
|||
|
} else {
|
|||
|
//printf("uart%d rx buf is full, discard a data.\n", uap->id);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (fifotaken > 0)
|
|||
|
xSemaphoreGiveFromISR(uap->xRev, NULL);
|
|||
|
|
|||
|
return fifotaken;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/* Returns true if tx interrupts have to be (kept) enabled */
|
|||
|
static BaseType_t xUart485TxChars(UartPort_t *uap, int from_irq)
|
|||
|
{
|
|||
|
struct circ_buf *xmit = &uap->txbuf;
|
|||
|
int count = uap->fifosize >> 1;
|
|||
|
|
|||
|
if (uart_circ_empty(xmit)) {
|
|||
|
vUart485StopTx(uap);
|
|||
|
return pdFALSE;
|
|||
|
}
|
|||
|
|
|||
|
do {
|
|||
|
if (from_irq && count-- == 0)
|
|||
|
break;
|
|||
|
writel(xmit->buf[xmit->tail], uap->regbase + UART485_THR);
|
|||
|
xmit->tail = (xmit->tail + 1) & (UART_BUF_SIZE - 1);
|
|||
|
} while (!uart_circ_empty(xmit));
|
|||
|
|
|||
|
if (from_irq)
|
|||
|
xSemaphoreGiveFromISR(uap->xSend, NULL);
|
|||
|
|
|||
|
return pdTRUE;
|
|||
|
}
|
|||
|
|
|||
|
static void vUart485IntHandler(void *param)
|
|||
|
{
|
|||
|
UartPort_t *uap = param;
|
|||
|
uint32_t iir;
|
|||
|
|
|||
|
iir = readl(uap->regbase + UART485_IIR);
|
|||
|
switch (iir & UART485_IIR_IID_MASK) {
|
|||
|
case UART485_IIR_IID_THR_EMPTY:
|
|||
|
xUart485TxChars(uap, 1);
|
|||
|
break;
|
|||
|
case UART485_IIR_IID_REV_DATA_AVAIL:
|
|||
|
case UART485_IIR_IID_REV_LINE_STATUS:
|
|||
|
case UART485_IIR_IID_CHAR_TIMEOUT:
|
|||
|
iUart485RxChars(uap);
|
|||
|
break;
|
|||
|
case UART485_IIR_IID_BUSY_DETECT:
|
|||
|
iir = readl(uap->regbase + UART485_USR); //clear busy interrupt
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
UartPort_t *xUartOpen(uint32_t id)
|
|||
|
{
|
|||
|
int irq;
|
|||
|
|
|||
|
if (id >= UART_NUM) {
|
|||
|
TRACE_INFO("Wrong input uart id.\n");
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
if (pxUartPort[id] != NULL) {
|
|||
|
if (id != UART_DEBUG_PORT)
|
|||
|
TRACE_ERROR("Uart %d is already in use.\n", id);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
UartPort_t *uap = (UartPort_t *)pvPortMalloc(sizeof(UartPort_t));
|
|||
|
if (uap == NULL) {
|
|||
|
if (id != UART_DEBUG_PORT)
|
|||
|
TRACE_ERROR("Out of memory for uart%d.\n", id);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
memset(uap, 0, sizeof(*uap));
|
|||
|
|
|||
|
uap->rxbuf.buf = (char*)pvPortMalloc(UART_BUF_SIZE);
|
|||
|
if (uap->rxbuf.buf == NULL) {
|
|||
|
if (id != UART_DEBUG_PORT)
|
|||
|
TRACE_ERROR("Out of memory for uart%d.\n", id);
|
|||
|
goto err;
|
|||
|
}
|
|||
|
|
|||
|
uap->txbuf.buf = (char*)pvPortMalloc(UART_BUF_SIZE);
|
|||
|
if (uap->txbuf.buf == NULL) {
|
|||
|
if (id != UART_DEBUG_PORT)
|
|||
|
TRACE_ERROR("Out of memory for uart%d.\n", id);
|
|||
|
goto err;
|
|||
|
}
|
|||
|
|
|||
|
uap->xMutex = xSemaphoreCreateRecursiveMutex();
|
|||
|
configASSERT(uap->xMutex);
|
|||
|
|
|||
|
uap->xRev = xSemaphoreCreateBinary();
|
|||
|
configASSERT(uap->xRev);
|
|||
|
|
|||
|
uap->xSend = xSemaphoreCreateBinary();
|
|||
|
configASSERT(uap->xSend);
|
|||
|
|
|||
|
//vUartSlectPad(id);
|
|||
|
uap->id = id;
|
|||
|
uap->regbase = ulUartBase[id];
|
|||
|
if ((uap->id == UART_ID0) || (uap->id == UART_ID2))
|
|||
|
uap->fifosize = 16;
|
|||
|
else if (uap->id == UART_ID1)
|
|||
|
uap->fifosize = 32;
|
|||
|
else
|
|||
|
uap->fifosize = 128;
|
|||
|
|
|||
|
irq = UART0_IRQn + id;
|
|||
|
if ((uap->id == UART_ID0) || (uap->id == UART_ID2))
|
|||
|
request_irq(irq, 0, vUartIntHandler, uap);
|
|||
|
else
|
|||
|
request_irq(irq, 0, vUart485IntHandler, uap);
|
|||
|
|
|||
|
return pxUartPort[id] = uap;
|
|||
|
|
|||
|
err:
|
|||
|
if (uap->txbuf.buf)
|
|||
|
vPortFree(uap->txbuf.buf);
|
|||
|
if (uap->rxbuf.buf)
|
|||
|
vPortFree(uap->rxbuf.buf);
|
|||
|
vPortFree(uap);
|
|||
|
return NULL;
|
|||
|
};
|
|||
|
|
|||
|
void vUartInit(UartPort_t *uap, uint32_t baud, uint32_t flags)
|
|||
|
{
|
|||
|
unsigned int lcr_h, quot, cr;
|
|||
|
int count = 0;
|
|||
|
|
|||
|
/* soft reset */
|
|||
|
sys_soft_reset(softreset_uart0 + uap->id - UART_ID0);
|
|||
|
|
|||
|
if ((uap->id == UART_ID0) || (uap->id == UART_ID2)) {
|
|||
|
if (baud > UART_CLK / 16)
|
|||
|
quot = (UART_CLK * 8 + baud / 2) / baud;
|
|||
|
else
|
|||
|
quot = (UART_CLK * 4 + baud / 2) / baud;
|
|||
|
|
|||
|
switch (flags & CSIZE) {
|
|||
|
case CS5:
|
|||
|
lcr_h = UART_LCRH_WLEN_5;
|
|||
|
break;
|
|||
|
case CS6:
|
|||
|
lcr_h = UART_LCRH_WLEN_6;
|
|||
|
break;
|
|||
|
case CS7:
|
|||
|
lcr_h = UART_LCRH_WLEN_7;
|
|||
|
break;
|
|||
|
default: // CS8
|
|||
|
lcr_h = UART_LCRH_WLEN_8;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (flags & CSTOPB)
|
|||
|
lcr_h |= UART_LCRH_STP2;
|
|||
|
if (flags & PARENB) {
|
|||
|
lcr_h |= UART_LCRH_PEN;
|
|||
|
if (!(flags & PARODD))
|
|||
|
lcr_h |= UART_LCRH_EPS;
|
|||
|
if (flags & CMSPAR)
|
|||
|
lcr_h |= UART_LCRH_SPS;
|
|||
|
}
|
|||
|
lcr_h |= UART_LCRH_FEN;
|
|||
|
|
|||
|
/* Provoke TX FIFO interrupt into asserting */
|
|||
|
cr = UART_CR_UARTEN | UART_CR_TXE | UART_CR_LBE;
|
|||
|
reconfig:
|
|||
|
writel(cr, uap->regbase + UART_CR);
|
|||
|
writel(0, uap->regbase + UART_FBRD);
|
|||
|
writel(1, uap->regbase + UART_IBRD);
|
|||
|
writel(0, uap->regbase + UART_LCRH);
|
|||
|
writel(0, uap->regbase + UART_DR);
|
|||
|
while (readl(uap->regbase + UART_FR) & UART_FR_BUSY);
|
|||
|
if (count++ < 10 && !(readl(uap->regbase + UART_RIS) & UART_TXIS)) {
|
|||
|
printf("ERROR! Uart status wrong.\n");
|
|||
|
goto reconfig;
|
|||
|
}
|
|||
|
|
|||
|
/* first, disable everything */
|
|||
|
writel(0, uap->regbase + UART_CR);
|
|||
|
|
|||
|
cr = UART_CR_RXE | UART_CR_TXE;
|
|||
|
if (flags & CRTSCTS)
|
|||
|
cr |= UART_CR_CTSEN | UART_CR_RTSEN;
|
|||
|
|
|||
|
/* Set baud rate */
|
|||
|
writel(quot & 0x3f, uap->regbase + UART_FBRD);
|
|||
|
writel(quot >> 6, uap->regbase + UART_IBRD);
|
|||
|
|
|||
|
writel(UART_RTIM | UART_RXIM, uap->regbase + UART_IMSC);
|
|||
|
writel(UART_IFLS_RX4_8 | UART_IFLS_TX4_8, uap->regbase + UART_IFLS);
|
|||
|
writel(lcr_h, uap->regbase + UART_LCRH);
|
|||
|
writel(cr | UART_CR_UARTEN, uap->regbase + UART_CR);
|
|||
|
} else {
|
|||
|
//set modem
|
|||
|
writel(0, uap->regbase + UART485_MCR);
|
|||
|
|
|||
|
// baud = clk/(16*U_DLL)
|
|||
|
//set baud rate
|
|||
|
writel(readl(uap->regbase + UART485_LCR) | (1 << 7), uap->regbase + UART485_LCR);
|
|||
|
writel(UART_CLK / (16 * baud), uap->regbase + UART485_DLL);
|
|||
|
writel(0, uap->regbase + UART485_DLH);
|
|||
|
if ((uap->id == UART_ID1) || (uap->id == UART_ID3)) { //Set fractional baud rate
|
|||
|
//Fractional baud divisor = ((uart_clk%(16*baud))/(16*baud)) * 16 = (uart_clk%(16*baud)) * 16 / (16*baud);
|
|||
|
u32 divisor = (UART_CLK % (16*baud)) * 16 / (16*baud);
|
|||
|
printf("fractional divisor:%d\n", divisor);
|
|||
|
writel(divisor, uap->regbase + UART485_DLF);
|
|||
|
}
|
|||
|
writel(readl(uap->regbase + UART485_LCR) & ~(1 << 7), uap->regbase + UART485_LCR);
|
|||
|
|
|||
|
cr = readl(uap->regbase + UART485_LCR);
|
|||
|
//校验
|
|||
|
cr &= ~(7 << 3);
|
|||
|
if (flags & PARENB) {
|
|||
|
cr |= (1 << 3);
|
|||
|
if (!(flags & PARODD))
|
|||
|
cr |= (1 << 4);
|
|||
|
if (flags & CMSPAR)
|
|||
|
cr |= (1 << 5);
|
|||
|
}
|
|||
|
//停止位
|
|||
|
if (flags & CSTOPB)
|
|||
|
cr |= (1 << 2);
|
|||
|
else
|
|||
|
cr &= ~(1 << 2);
|
|||
|
//数据位
|
|||
|
cr &= ~(3 << 0);
|
|||
|
switch (flags & CSIZE) {
|
|||
|
case CS5:
|
|||
|
break;
|
|||
|
case CS6:
|
|||
|
cr |= 1;
|
|||
|
break;
|
|||
|
case CS7:
|
|||
|
cr |= 2;
|
|||
|
break;
|
|||
|
default: // CS8
|
|||
|
cr |= 3;
|
|||
|
break;
|
|||
|
}
|
|||
|
writel(cr, uap->regbase + UART485_LCR);
|
|||
|
|
|||
|
//set fifo
|
|||
|
writel((2 << 6) | (3 << 4) | 7, uap->regbase + UART485_FCR);
|
|||
|
|
|||
|
//enable rx and err interrupt
|
|||
|
writel((1 << 4) | 1, uap->regbase + UART485_IER);
|
|||
|
|
|||
|
//设置通信模式全双工还是半双工
|
|||
|
//485mode disable
|
|||
|
writel(0, uap->regbase + UART485_TCR);
|
|||
|
}
|
|||
|
|
|||
|
/* 高速串口先初始化再配置pad脚,否则在初始化过程中有收到数据会导致串口出错 */
|
|||
|
if(uap->id == UART_ID1)
|
|||
|
pinctrl_set_group(PGRP_UART1);
|
|||
|
else if(uap->id == UART_ID3)
|
|||
|
pinctrl_set_group(PGRP_UART3);
|
|||
|
}
|
|||
|
|
|||
|
void vUartClose(UartPort_t *uap)
|
|||
|
{
|
|||
|
if (uap == NULL) return;
|
|||
|
|
|||
|
if ((uap->id == UART_ID0) || (uap->id == UART_ID2)) {
|
|||
|
writel(0, uap->regbase + UART_IMSC);
|
|||
|
writel(0, uap->regbase + UART_CR);
|
|||
|
} else {
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
vSemaphoreDelete(uap->xSend);
|
|||
|
vSemaphoreDelete(uap->xRev);
|
|||
|
vSemaphoreDelete(uap->xMutex);
|
|||
|
vPortFree(uap->rxbuf.buf);
|
|||
|
uap->rxbuf.tail = uap->rxbuf.head = 0;
|
|||
|
vPortFree(uap->txbuf.buf);
|
|||
|
uap->rxbuf.tail = uap->rxbuf.head = 0;
|
|||
|
vPortFree(uap);
|
|||
|
pxUartPort[uap->id] = NULL;
|
|||
|
}
|
|||
|
|
|||
|
int iUartWrite(UartPort_t *uap, uint8_t *buf, size_t len, TickType_t xBlockTime)
|
|||
|
{
|
|||
|
int c, ret = 0;
|
|||
|
TickType_t timeout = xBlockTime;
|
|||
|
TickType_t starttime = xTaskGetTickCount();
|
|||
|
TickType_t sptime;
|
|||
|
|
|||
|
while (len) {
|
|||
|
xSemaphoreTakeRecursive(uap->xMutex, portMAX_DELAY);
|
|||
|
|
|||
|
c = CIRC_SPACE_TO_END(uap->txbuf.head, uap->txbuf.tail, UART_BUF_SIZE);
|
|||
|
if (len < c)
|
|||
|
c = len;
|
|||
|
if (c <= 0) {
|
|||
|
xSemaphoreGiveRecursive(uap->xMutex);
|
|||
|
sptime = xTaskGetTickCount() - starttime;
|
|||
|
if (timeout > sptime) {
|
|||
|
xSemaphoreTake(uap->xSend, timeout - sptime);
|
|||
|
continue;
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
memcpy(uap->txbuf.buf + uap->txbuf.head, buf, c);
|
|||
|
uap->txbuf.head = (uap->txbuf.head + c) & (UART_BUF_SIZE - 1);
|
|||
|
buf += c;
|
|||
|
len -= c;
|
|||
|
ret += c;
|
|||
|
|
|||
|
xSemaphoreGiveRecursive(uap->xMutex);
|
|||
|
}
|
|||
|
|
|||
|
if ((uap->id == UART_ID0) || (uap->id == UART_ID2))
|
|||
|
vUartStartTx(uap);
|
|||
|
else
|
|||
|
vUart485StartTx(uap);
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
int iUartReadNoBlock(UartPort_t *uap, uint8_t *buf, size_t len)
|
|||
|
{
|
|||
|
int c;
|
|||
|
|
|||
|
xSemaphoreTakeRecursive(uap->xMutex, portMAX_DELAY);
|
|||
|
|
|||
|
c = CIRC_CNT_TO_END(uap->rxbuf.head, uap->rxbuf.tail, UART_BUF_SIZE);
|
|||
|
if (len < c)
|
|||
|
c = len;
|
|||
|
if (c <= 0) {
|
|||
|
xSemaphoreGiveRecursive(uap->xMutex);
|
|||
|
}
|
|||
|
memcpy(buf, uap->rxbuf.buf + uap->rxbuf.tail, c);
|
|||
|
uap->rxbuf.tail = (uap->rxbuf.tail + c) & (UART_BUF_SIZE - 1);
|
|||
|
xSemaphoreGiveRecursive(uap->xMutex);
|
|||
|
|
|||
|
return c;
|
|||
|
}
|
|||
|
|
|||
|
int iUartRead(UartPort_t *uap, uint8_t *buf, size_t len, TickType_t xBlockTime)
|
|||
|
{
|
|||
|
int c, ret = 0;
|
|||
|
TickType_t timeout = xBlockTime;
|
|||
|
TickType_t starttime = xTaskGetTickCount();
|
|||
|
TickType_t sptime;
|
|||
|
|
|||
|
while (len) {
|
|||
|
xSemaphoreTakeRecursive(uap->xMutex, portMAX_DELAY);
|
|||
|
|
|||
|
c = CIRC_CNT_TO_END(uap->rxbuf.head, uap->rxbuf.tail, UART_BUF_SIZE);
|
|||
|
if (len < c)
|
|||
|
c = len;
|
|||
|
if (c <= 0) {
|
|||
|
xSemaphoreGiveRecursive(uap->xMutex);
|
|||
|
sptime = xTaskGetTickCount() - starttime;
|
|||
|
if (timeout > sptime) {
|
|||
|
xSemaphoreTake(uap->xRev, timeout - sptime);
|
|||
|
continue;
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
memcpy(buf, uap->rxbuf.buf + uap->rxbuf.tail, c);
|
|||
|
uap->rxbuf.tail = (uap->rxbuf.tail + c) & (UART_BUF_SIZE - 1);
|
|||
|
buf += c;
|
|||
|
len -= c;
|
|||
|
ret += c;
|
|||
|
|
|||
|
xSemaphoreGiveRecursive(uap->xMutex);
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
void vDebugConsoleInitialise(void)
|
|||
|
{
|
|||
|
UartPort_t *uap = xUartOpen(UART_DEBUG_PORT);
|
|||
|
|
|||
|
if (uap != NULL) {
|
|||
|
|
|||
|
vUartInit(uap, 115200, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* retarget printf function */
|
|||
|
int32_t putchar(int32_t ch)
|
|||
|
{
|
|||
|
while (readl(REGS_UART0_BASE + UART_FR) & UART_FR_TXFF);
|
|||
|
writel(ch, REGS_UART0_BASE + UART_DR);
|
|||
|
|
|||
|
return ch;
|
|||
|
}
|
|||
|
|
|||
|
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
|
|||
|
{
|
|||
|
return pxUartPort[UART_DEBUG_PORT];
|
|||
|
}
|
|||
|
|
|||
|
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
|
|||
|
{
|
|||
|
if (iUartWrite(pxPort, (uint8_t *)&cOutChar, 1, xBlockTime) == 1)
|
|||
|
return pdPASS;
|
|||
|
|
|||
|
return pdFAIL;
|
|||
|
}
|
|||
|
|
|||
|
void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )
|
|||
|
{
|
|||
|
signed char *pxNext;
|
|||
|
|
|||
|
/* NOTE: This implementation does not handle the queue being full as no
|
|||
|
block time is used! */
|
|||
|
|
|||
|
/* The port handle is not required as this driver only supports UART0. */
|
|||
|
( void ) pxPort;
|
|||
|
( void ) usStringLength;
|
|||
|
|
|||
|
/* Send each character in the string, one at a time. */
|
|||
|
pxNext = ( signed char * ) pcString;
|
|||
|
while( *pxNext )
|
|||
|
{
|
|||
|
xSerialPutChar( pxPort, *pxNext, UART_NO_BLOCK );
|
|||
|
pxNext++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )
|
|||
|
{
|
|||
|
if (iUartRead(pxPort, (uint8_t *)pcRxedChar, 1, xBlockTime) == 1)
|
|||
|
return pdPASS;
|
|||
|
|
|||
|
return pdFAIL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#define UUP_PACKET_SIZE 128
|
|||
|
#define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16)
|
|||
|
#define UUP_RX_FRAME_NUM 16
|
|||
|
static unsigned char uup_rx_buf[UUP_RX_FRAME_NUM][UUP_MAX_FRAME_LEN];
|
|||
|
static unsigned char *uup_rx_ptr;
|
|||
|
static int uup_rx_rev_len = 0;
|
|||
|
static int uup_rx_head = 0;
|
|||
|
static int uup_rx_tail = 0;
|
|||
|
static int uup_rx_state = 0;
|
|||
|
static int uup_rx_data_len = 0;
|
|||
|
|
|||
|
#ifdef OTA_UPDATE_SUPPORT
|
|||
|
#include "ota_update.h"
|
|||
|
#include "updatefile.h"
|
|||
|
#include "romfile.h"
|
|||
|
#include "animation.h"
|
|||
|
#include "ff_stdio.h"
|
|||
|
|
|||
|
#if DEVICE_TYPE_SELECT != EMMC_FLASH
|
|||
|
#include "ff_sfdisk.h"
|
|||
|
#endif
|
|||
|
/*
|
|||
|
typedef enum {
|
|||
|
UART_FRAME_START,
|
|||
|
UART_FRAME_FILEINFO,
|
|||
|
UART_FRAME_FILEXFER,
|
|||
|
UART_FRAME_FINISH,
|
|||
|
} eUartFrameType;
|
|||
|
|
|||
|
typedef enum {
|
|||
|
UUP_STATE_IDLE,
|
|||
|
UUP_STATE_START,
|
|||
|
UUP_STATE_GET_FILEINFO,
|
|||
|
UUP_STATE_FILE_TFR,
|
|||
|
UUP_STATE_END,
|
|||
|
} eUartUpdateState;
|
|||
|
|
|||
|
#define UUP_ACK_OK 1
|
|||
|
#define UUP_ACK_FAIL 0
|
|||
|
|
|||
|
#define UUP_MAX_FILE_SIZE 0x1000000
|
|||
|
#define UUP_RX_FRAME_NUM 16
|
|||
|
#define UUP_MAX_LOADER_SIZE STEPLDR_MAX_SIZE//0x10000
|
|||
|
*/
|
|||
|
// static int uup_status = UUP_STATE_IDLE;
|
|||
|
static int uup_file_type = 0;
|
|||
|
static int uup_file_size = 0;
|
|||
|
static int uup_packet_num = 0;
|
|||
|
static int uup_rev_packet = 0;
|
|||
|
static int uup_rev_len = 0;
|
|||
|
static char uup_filename[32];
|
|||
|
static FF_FILE *uup_file = NULL;
|
|||
|
|
|||
|
static void uup_send_ack(UartPort_t *uap, int type, int ret)
|
|||
|
{
|
|||
|
unsigned char buf[7] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00};
|
|||
|
int i;
|
|||
|
|
|||
|
buf[4] = type;
|
|||
|
buf[5] = ret;
|
|||
|
for (i = 1; i < 6; i++)
|
|||
|
buf[6] ^= buf[i];
|
|||
|
|
|||
|
iUartWrite(uap, buf, 7, pdMS_TO_TICKS(100));
|
|||
|
}
|
|||
|
#if 0
|
|||
|
void uup_ota_update(UartPort_t *uap, uint8_t *framebuf, size_t len)
|
|||
|
{
|
|||
|
int frametype = framebuf[0];
|
|||
|
uint8_t *buf = framebuf + 1;
|
|||
|
unsigned int framelen;
|
|||
|
unsigned int packetnum;
|
|||
|
SysInfo *sysinfo = GetSysInfo();
|
|||
|
|
|||
|
switch (frametype) {
|
|||
|
case UART_FRAME_START:
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_OK);
|
|||
|
uup_status = UUP_STATE_START;
|
|||
|
break;
|
|||
|
case UART_FRAME_FILEINFO:
|
|||
|
if (uup_status != UUP_STATE_START && uup_status != UUP_STATE_GET_FILEINFO) {
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
uup_rev_len = 0;
|
|||
|
uup_rev_packet = 0;
|
|||
|
if (uup_file) {
|
|||
|
ff_fclose(uup_file);
|
|||
|
uup_file = NULL;
|
|||
|
}
|
|||
|
uup_file_type = buf[0];
|
|||
|
if (uup_file_type > UPFILE_TYPE_LNCHEMMC) {
|
|||
|
printf("Rev wrong file type %d.\n", uup_file_type);
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
uup_packet_num = (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
|||
|
uup_file_size = UUP_PACKET_SIZE * uup_packet_num;
|
|||
|
if (uup_file_size > UUP_MAX_FILE_SIZE) {
|
|||
|
printf("Rev wrong file size.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
#if DEVICE_TYPE_SELECT != EMMC_FLASH
|
|||
|
{
|
|||
|
FF_Disk_t *sfdisk = FF_SFDiskInit(SF_MOUNT_PATH);
|
|||
|
if (!sfdisk) {
|
|||
|
printf("FF_SFDiskInit fail.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
strcpy(uup_filename, OTA_MOUNT_PATH);
|
|||
|
strcat(uup_filename, "/");
|
|||
|
strcat(uup_filename, g_upfilename[uup_file_type]);
|
|||
|
uup_file = ff_fopen(uup_filename, "wb");
|
|||
|
if (!uup_file) {
|
|||
|
printf("create uup_file %s fail.\n", uup_filename);
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_OK);
|
|||
|
uup_status = UUP_STATE_GET_FILEINFO;
|
|||
|
break;
|
|||
|
case UART_FRAME_FILEXFER:
|
|||
|
if (uup_status != UUP_STATE_GET_FILEINFO && uup_status != UUP_STATE_FILE_TFR) {
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
packetnum = buf[0];
|
|||
|
printf("uup_rev_packet %d.\n", uup_rev_packet);
|
|||
|
if ((uup_rev_packet & 0xff) != packetnum) {
|
|||
|
printf("Wrong packet number.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
framelen = len - 2;
|
|||
|
/* only last frame size is less than UUP_PACKET_SIZE */
|
|||
|
if (framelen > UUP_PACKET_SIZE ||
|
|||
|
(framelen < UUP_PACKET_SIZE && uup_rev_packet != uup_packet_num - 1)) {
|
|||
|
printf("Wrong packet len.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
uup_rev_len += framelen;
|
|||
|
if (uup_file_type >= UPFILE_TYPE_FIRSTLDR && uup_rev_len > UUP_MAX_LOADER_SIZE) {
|
|||
|
printf("loader file is too large.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
uup_rev_packet++;
|
|||
|
if (uup_file) {
|
|||
|
if (ff_fwrite(buf + 1, 1, framelen, uup_file) != framelen) {
|
|||
|
printf("write ota data fail.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
} else {
|
|||
|
printf("uup_file is not created.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_OK);
|
|||
|
uup_status = UUP_STATE_FILE_TFR;
|
|||
|
break;
|
|||
|
case UART_FRAME_FINISH:
|
|||
|
if (uup_status != UUP_STATE_FILE_TFR && uup_status != UART_FRAME_FINISH) {
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
break;
|
|||
|
}
|
|||
|
if (!buf[0]) {
|
|||
|
printf("update end with error!\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
uup_status = UUP_STATE_END;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (uup_file) {
|
|||
|
ff_fclose(uup_file);
|
|||
|
uup_file = NULL;
|
|||
|
if (update_from_media(OTA_MOUNT_PATH, uup_file_type)) {
|
|||
|
printf("update from ota fail.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
} else {
|
|||
|
printf("update from ota ok.\n");
|
|||
|
SaveSysInfo();
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_OK);
|
|||
|
}
|
|||
|
} else {
|
|||
|
printf("uup_file is not created.\n");
|
|||
|
uup_send_ack(uap, frametype, UUP_ACK_FAIL);
|
|||
|
}
|
|||
|
uup_status = UUP_STATE_END;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#else
|
|||
|
static void uart_tx_demo_thread(void *param)
|
|||
|
{
|
|||
|
UartPort_t *uap = param;
|
|||
|
uint8_t uarttx[32] = "hello, i am amt630h\n";
|
|||
|
|
|||
|
//printf("### uart_tx_demo_thread\n");
|
|||
|
for (;;) {
|
|||
|
iUartWrite(uap, uarttx, strlen((char*)uarttx), pdMS_TO_TICKS(100));
|
|||
|
vTaskDelay(1000);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
uint8_t cmdstr[64];
|
|||
|
uint16_t cmdlen = 0;
|
|||
|
#define CALL_NUM_SIZE 20
|
|||
|
extern void uart_test_tx_demo_thread(void *param);
|
|||
|
static void uart_rx_demo_thread(void *param)
|
|||
|
{
|
|||
|
UartPort_t *uap = xUartOpen(UART_MCU_PORT);
|
|||
|
uint8_t uartrx[64];
|
|||
|
int len;
|
|||
|
int i;
|
|||
|
|
|||
|
if (!uap) {
|
|||
|
printf("open uart %d fail.\n", UART_MCU_PORT);
|
|||
|
vTaskDelete(NULL);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
vUartInit(uap, 115200, 0);
|
|||
|
|
|||
|
#if 0
|
|||
|
if (xTaskCreate(uart_tx_demo_thread, "uartsend", configMINIMAL_STACK_SIZE, uap,
|
|||
|
configMAX_PRIORITIES / 3, NULL) != pdPASS) {
|
|||
|
printf("create uart tx demo task fail.\n");
|
|||
|
vTaskDelete(NULL);
|
|||
|
return;
|
|||
|
}
|
|||
|
#endif
|
|||
|
if (xTaskCreate(uart_test_tx_demo_thread, "uartsend", configMINIMAL_STACK_SIZE, uap,
|
|||
|
configMAX_PRIORITIES / 3, NULL) != pdPASS) {
|
|||
|
printf("create uart tx demo task fail.\n");
|
|||
|
vTaskDelete(NULL);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
for (;;) {
|
|||
|
len = iUartRead(uap, uartrx, 64, pdMS_TO_TICKS(100));
|
|||
|
//打印
|
|||
|
|
|||
|
if(len!=0){
|
|||
|
printf("uart2>>>>>>");
|
|||
|
for(uint8_t i=0;i<len;i++){
|
|||
|
printf("%c",uartrx[i]);
|
|||
|
}
|
|||
|
printf("\r\n");
|
|||
|
|
|||
|
if((0x01 == len) && (0x00 == uartrx[0])) break;
|
|||
|
memcpy((cmdstr+cmdlen), uartrx, len);
|
|||
|
cmdlen += len;
|
|||
|
|
|||
|
//收完一条数据标志以\r\r结尾
|
|||
|
if((cmdstr[cmdlen-2]=='\r'|| cmdstr[cmdlen-2]=='\n'))
|
|||
|
{
|
|||
|
parseATCommand(cmdstr,cmdlen);
|
|||
|
cmdlen = 0;
|
|||
|
memset(cmdstr, 0, sizeof(cmdstr));
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int uart_rx_demo(void)
|
|||
|
{
|
|||
|
/* Create a task to process uart rx data */
|
|||
|
if (xTaskCreate(uart_rx_demo_thread, "uartdemo", configMINIMAL_STACK_SIZE, NULL,
|
|||
|
configMAX_PRIORITIES / 3, NULL) != pdPASS) {
|
|||
|
printf("create uart rx demo task fail.\n");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|