mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-19 00:13:21 +08:00
修改了Web后台的部分界面,增加了HAmqtt中的总电量传感器,后台新增mqtt上报频率设置
This commit is contained in:
820
mico-os/platform/MCU/MW3xx/peripherals/platform_uart.c
Normal file
820
mico-os/platform/MCU/MW3xx/peripherals/platform_uart.c
Normal file
@@ -0,0 +1,820 @@
|
||||
/*
|
||||
* Copyright 2016, MXCHIP.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* uart.c: mxchip driver for UART
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include <wmtypes.h>
|
||||
#include <wmstdio.h>
|
||||
#include <mdev_uart.h>
|
||||
//#include <wm_os.h>
|
||||
#include <pwrmgr.h>
|
||||
#include <mdev_dma.h>
|
||||
#include <wmassert.h>
|
||||
#include <system-work-queue.h>
|
||||
#include "common.h"
|
||||
#include "mico_platform.h"
|
||||
|
||||
#define DISABLE_DMA
|
||||
#ifdef DISABLE_DMA
|
||||
#define NUM_UART_PORTS 3
|
||||
#define UART_IRQn_BASE UART0_IRQn
|
||||
#define UART_INT_BASE INT_UART0
|
||||
|
||||
#ifdef NO_MICO_RTOS
|
||||
#define os_thread_relinquish()
|
||||
#endif
|
||||
|
||||
|
||||
static void (*uart_8bit_cb_p[NUM_UART_PORTS]) ();
|
||||
static void (*uart_9bit_cb_p[NUM_UART_PORTS]) ();
|
||||
|
||||
#define SET_RX_BUF_SIZE(uart_data_p, size) \
|
||||
uart_data_p->rx_ringbuf.buf_size = size
|
||||
#define GET_RX_BUF_SIZE(uart_data_p) (uart_data_p->rx_ringbuf.buf_size)
|
||||
|
||||
#define SET_DMA_BLK_SIZE(uart_data_p, size) \
|
||||
uart_data_p->rx_ringbuf.dma_block_size = size
|
||||
#define GET_DMA_BLK_SIZE(uart_data_p) (uart_data_p->rx_ringbuf.dma_block_size)
|
||||
|
||||
#define DEFINE_UART_CB(id, mode) \
|
||||
static void \
|
||||
uart ## id ## _ ## mode ## bit_cb() {\
|
||||
uart_ ## mode ## bit_cb(id); }
|
||||
#define GET_UART_CB(id, mode) uart ## id ## _ ## mode ## bit_cb
|
||||
|
||||
extern platform_uart_t platform_uart_peripherals[];
|
||||
extern platform_uart_driver_t platform_uart_drivers[];
|
||||
|
||||
/* UART callback functions */
|
||||
static void uart_8bit_cb(int port_num)
|
||||
{
|
||||
uint8_t recv_byte, i;
|
||||
platform_uart_driver_t* driver = NULL;
|
||||
|
||||
for ( i = 0; i < MICO_UART_MAX; i++ ) {
|
||||
if ( platform_uart_peripherals[i].port_id == port_num ) {
|
||||
driver = &platform_uart_drivers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( driver == NULL ) return;
|
||||
/* Receive new data */
|
||||
while (UART_GetLineStatus(port_num, UART_LINESTATUS_DR) == SET) {
|
||||
if (ring_buffer_is_full(driver->rx_ring_buffer) == 0) {
|
||||
recv_byte = UART_ReceiveData(port_num);
|
||||
ring_buffer_write( driver->rx_ring_buffer, &recv_byte,1 );
|
||||
if ( ( driver->rx_size > 0 ) &&
|
||||
( ring_buffer_used_space( driver->rx_ring_buffer) >= driver->rx_size ) ) {
|
||||
mico_rtos_set_semaphore( &driver->rx_complete );
|
||||
|
||||
driver->rx_size = 0;
|
||||
|
||||
}
|
||||
} else {
|
||||
/* Rx Buffer is full, discard received data */
|
||||
if (driver->flow_control != FLOW_CONTROL_DISABLED_DRV) {
|
||||
/* We need to mask the interrupt till the data
|
||||
is read; otherwise we keep getting
|
||||
data-ready interrupt infinitely */
|
||||
UART_IntMask(port_num, UART_INT_RDA, MASK);
|
||||
return;
|
||||
} else {
|
||||
UART_ReceiveData(port_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_9bit_cb(int port_num)
|
||||
{
|
||||
uint16_t data;
|
||||
platform_uart_driver_t* driver = &platform_uart_drivers[port_num];
|
||||
uint8_t recv_byte;
|
||||
/* Receive new data */
|
||||
while (UART_GetLineStatus(port_num, UART_LINESTATUS_DR) == SET) {
|
||||
if (ring_buffer_free_space(driver->rx_ring_buffer) > 1) {
|
||||
data = UART_Receive9bits(port_num);
|
||||
recv_byte = (uint8_t) ((data >> 8) & 0x01);
|
||||
ring_buffer_write( driver->rx_ring_buffer, &recv_byte,1 );
|
||||
recv_byte = (uint8_t) (data & 0xFF);
|
||||
ring_buffer_write( driver->rx_ring_buffer, &recv_byte,1 );
|
||||
|
||||
if ( ( driver->rx_size > 0 ) &&
|
||||
( ring_buffer_used_space( driver->rx_ring_buffer ) >= driver->rx_size ) ) {
|
||||
mico_rtos_set_semaphore( &driver->rx_complete );
|
||||
driver->rx_size = 0;
|
||||
}
|
||||
} else {
|
||||
/* Rx Buffer is full, discard received data */
|
||||
if (driver->flow_control != FLOW_CONTROL_DISABLED_DRV) {
|
||||
/* We need to mask the interrupt till the data
|
||||
is read; otherwise we keep getting
|
||||
data-ready interrupt infinitely */
|
||||
UART_IntMask(port_num, UART_INT_RDA, MASK);
|
||||
return;
|
||||
} else {
|
||||
UART_Receive9bits(port_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_UART_CB(0, 8)
|
||||
DEFINE_UART_CB(1, 8)
|
||||
DEFINE_UART_CB(0, 9)
|
||||
DEFINE_UART_CB(1, 9)
|
||||
#if (NUM_UART_PORTS > 2)
|
||||
DEFINE_UART_CB(2, 8)
|
||||
DEFINE_UART_CB(2, 9)
|
||||
#if (NUM_UART_PORTS > 3)
|
||||
DEFINE_UART_CB(3, 8)
|
||||
DEFINE_UART_CB(3, 9)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static void fill_cb_array()
|
||||
{
|
||||
uart_8bit_cb_p[0] = GET_UART_CB(0, 8);
|
||||
uart_8bit_cb_p[1] = GET_UART_CB(1, 8);
|
||||
uart_9bit_cb_p[0] = GET_UART_CB(0, 9);
|
||||
uart_9bit_cb_p[1] = GET_UART_CB(1, 9);
|
||||
#if (NUM_UART_PORTS > 2)
|
||||
uart_8bit_cb_p[2] = GET_UART_CB(2, 8);
|
||||
uart_9bit_cb_p[2] = GET_UART_CB(2, 9);
|
||||
#if (NUM_UART_PORTS > 3)
|
||||
uart_8bit_cb_p[3] = GET_UART_CB(3, 8);
|
||||
uart_9bit_cb_p[3] = GET_UART_CB(3, 9);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
OSStatus platform_uart_init( platform_uart_driver_t* driver, const platform_uart_t* peripheral, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer )
|
||||
//int platform_uart_init(int port_id, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer)
|
||||
{
|
||||
UART_CFG_Type uartcfg;
|
||||
UART_FifoCfg_Type fifocfg;
|
||||
uint32_t port_id = peripheral->port_id;
|
||||
//platform_uart_driver_t* driver;
|
||||
|
||||
//sys_work_queue_init();
|
||||
if (port_id < 0 || port_id >= NUM_UART_PORTS) {
|
||||
UART_LOG("Port %d not enabled\r\n", port_id);
|
||||
return -1;
|
||||
}
|
||||
fill_cb_array();
|
||||
|
||||
//driver = &uart_drivers[port_id];
|
||||
driver->id = port_id;
|
||||
|
||||
switch (driver->id) {
|
||||
case UART0_ID:
|
||||
CLK_SetUARTClkSrc(CLK_UART_ID_0, CLK_UART_FAST);
|
||||
CLK_ModuleClkEnable(CLK_UART0);
|
||||
break;
|
||||
case UART1_ID:
|
||||
CLK_SetUARTClkSrc(CLK_UART_ID_1, CLK_UART_SLOW);
|
||||
CLK_ModuleClkEnable(CLK_UART1);
|
||||
break;
|
||||
case UART2_ID:
|
||||
CLK_SetUARTClkSrc(CLK_UART_ID_2, CLK_UART_SLOW);
|
||||
CLK_ModuleClkEnable(CLK_UART2);
|
||||
break;
|
||||
}
|
||||
if (optional_ring_buffer != NULL){
|
||||
/* Note that the ring_buffer should've been initialised first */
|
||||
driver->rx_ring_buffer = optional_ring_buffer;
|
||||
|
||||
} else {
|
||||
uint8_t *pbuf;
|
||||
pbuf = malloc(512);
|
||||
ring_buffer_init(driver->rx_ring_buffer, pbuf, 512);
|
||||
}
|
||||
|
||||
/* Initialize the UART port's mdev structure */
|
||||
driver->rx_size = 0;
|
||||
driver->tx_size = 0;
|
||||
driver->last_transmit_result = kNoErr;
|
||||
driver->last_receive_result = kNoErr;
|
||||
|
||||
uartcfg.baudRate = config->baud_rate;
|
||||
uartcfg.stickyParity = DISABLE;
|
||||
fifocfg.fifoEnable = ENABLE;
|
||||
|
||||
switch (config->data_width) {
|
||||
case DATA_WIDTH_5BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_5;
|
||||
break;
|
||||
case DATA_WIDTH_6BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_6;
|
||||
break;
|
||||
case DATA_WIDTH_7BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_7;
|
||||
break;
|
||||
case DATA_WIDTH_8BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_8;
|
||||
break;
|
||||
case DATA_WIDTH_9BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_8;
|
||||
uartcfg.parity = UART_PARITY_EVEN;
|
||||
uartcfg.stickyParity = DISABLE;
|
||||
fifocfg.fifoEnable = DISABLE;
|
||||
break;
|
||||
default:
|
||||
uartcfg.dataBits = UART_DATABITS_8;
|
||||
break;
|
||||
}
|
||||
switch ( config->parity )
|
||||
{
|
||||
case NO_PARITY:
|
||||
uartcfg.parity = UART_PARITY_NONE;
|
||||
break;
|
||||
|
||||
case EVEN_PARITY:
|
||||
uartcfg.parity = UART_PARITY_EVEN;
|
||||
break;
|
||||
|
||||
case ODD_PARITY:
|
||||
uartcfg.parity = UART_PARITY_ODD;
|
||||
break;
|
||||
|
||||
default:
|
||||
uartcfg.parity = UART_PARITY_NONE;
|
||||
break;
|
||||
}
|
||||
if (config->flow_control != FLOW_CONTROL_DISABLED) {
|
||||
fifocfg.autoFlowControl = ENABLE;
|
||||
} else {
|
||||
fifocfg.autoFlowControl = DISABLE;
|
||||
}
|
||||
|
||||
if ( config->stop_bits == STOP_BITS_1 )
|
||||
UART_SetStopBits(port_id, UART_STOPBITS_1);
|
||||
else
|
||||
UART_SetStopBits(port_id, UART_STOPBITS_2);
|
||||
|
||||
fifocfg.rxFifoLevel = UART_RXFIFO_BYTE_1;
|
||||
fifocfg.txFifoLevel = UART_TXFIFO_HALF_EMPTY;
|
||||
fifocfg.peripheralBusType = UART_PERIPHERAL_BITS_8;
|
||||
fifocfg.fifoDmaEnable = DISABLE;
|
||||
|
||||
UART_Disable(driver->id);
|
||||
UART_Enable(driver->id);
|
||||
UART_Init(driver->id, &uartcfg);
|
||||
UART_FifoConfig(driver->id, &fifocfg);
|
||||
|
||||
install_int_callback(UART_INT_BASE + driver->id,
|
||||
UART_INT_RDA,
|
||||
(config->data_width == DATA_WIDTH_9BIT) ?
|
||||
uart_9bit_cb_p[driver->id] :
|
||||
uart_8bit_cb_p[driver->id]);
|
||||
|
||||
NVIC_EnableIRQ(UART_IRQn_BASE + driver->id);
|
||||
NVIC_SetPriority(UART_IRQn_BASE + driver->id, 0xf);
|
||||
UART_IntMask(driver->id, UART_INT_RDA, UNMASK);
|
||||
|
||||
/* Configure the pinmux for uart pins */
|
||||
board_uart_pin_config(driver->id);
|
||||
|
||||
mico_rtos_init_semaphore( &driver->tx_complete, 1 );
|
||||
mico_rtos_init_semaphore( &driver->rx_complete, 1 );
|
||||
mico_rtos_init_semaphore( &driver->sem_wakeup, 1 );
|
||||
mico_rtos_init_mutex ( &driver->tx_mutex );
|
||||
return WM_SUCCESS;
|
||||
}
|
||||
|
||||
//uint32_t mico_get_time_no_os(void)
|
||||
//{
|
||||
// return os_total_ticks_get();
|
||||
//}
|
||||
|
||||
OSStatus platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
if (( data_in == NULL ) || ( expected_data_size == 0 )) {
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
while (expected_data_size != 0)
|
||||
{
|
||||
uint32_t transfer_size = MIN( driver->rx_ring_buffer->size/2, expected_data_size );
|
||||
|
||||
/* Check if ring buffer already contains the required amount of data. */
|
||||
if ( transfer_size > ring_buffer_used_space( driver->rx_ring_buffer ) )
|
||||
{
|
||||
/* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
|
||||
driver->rx_size = transfer_size;
|
||||
|
||||
if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms) != kNoErr )
|
||||
{
|
||||
driver->rx_size = 0;
|
||||
return kTimeoutErr;
|
||||
}
|
||||
|
||||
/* Reset rx_size to prevent semaphore being set while nothing waits for the data */
|
||||
driver->rx_size = 0;
|
||||
}
|
||||
|
||||
expected_data_size -= transfer_size;
|
||||
|
||||
// Grab data from the buffer
|
||||
do
|
||||
{
|
||||
uint8_t* available_data;
|
||||
uint32_t bytes_available;
|
||||
|
||||
ring_buffer_get_data( driver->rx_ring_buffer, &available_data, &bytes_available );
|
||||
bytes_available = MIN( bytes_available, transfer_size );
|
||||
memcpy( data_in, available_data, bytes_available );
|
||||
transfer_size -= bytes_available;
|
||||
data_in = ( (uint8_t*) data_in + bytes_available );
|
||||
ring_buffer_consume( driver->rx_ring_buffer, bytes_available );
|
||||
} while ( transfer_size != 0 );
|
||||
}
|
||||
|
||||
if ( expected_data_size != 0 )
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
exit:
|
||||
//platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus platform_uart_transmit_bytes( platform_uart_driver_t* driver, const uint8_t* data_out, uint32_t size )
|
||||
//OSStatus platform_uart_transmit_bytes( int port_id, const uint8_t* data_out, uint32_t size )
|
||||
{
|
||||
int i;
|
||||
|
||||
if (driver->tx_mutex)
|
||||
mico_rtos_lock_mutex( &driver->tx_mutex );
|
||||
for(i=0; i<size; i++) {
|
||||
while (UART_GetLineStatus(driver->id,
|
||||
UART_LINESTATUS_TDRQ) != SET) {
|
||||
os_thread_relinquish();
|
||||
}
|
||||
|
||||
UART_SendData(driver->id, data_out[i]);
|
||||
}
|
||||
if (driver->tx_mutex)
|
||||
mico_rtos_unlock_mutex( &driver->tx_mutex );
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
uint32_t platform_uart_get_length_in_buffer( platform_uart_driver_t* driver )
|
||||
{
|
||||
return ring_buffer_used_space( driver->rx_ring_buffer );
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_uart_deinit( platform_uart_driver_t* driver )
|
||||
{
|
||||
|
||||
mico_rtos_deinit_semaphore( &driver->rx_complete );
|
||||
mico_rtos_deinit_semaphore( &driver->tx_complete );
|
||||
mico_rtos_deinit_semaphore( &driver->sem_wakeup );
|
||||
mico_rtos_deinit_mutex( &driver->tx_mutex );
|
||||
driver->rx_size = 0;
|
||||
driver->tx_size = 0;
|
||||
driver->last_transmit_result = kNoErr;
|
||||
driver->last_receive_result = kNoErr;
|
||||
|
||||
while (UART_GetLineStatus(driver->id, UART_LINESTATUS_TEMT)!= SET)
|
||||
;
|
||||
|
||||
UART_Disable(driver->id);
|
||||
|
||||
/* de-register interrupt callbacks */
|
||||
NVIC_DisableIRQ(UART_IRQn_BASE + driver->id);
|
||||
install_int_callback(UART_INT_BASE + driver->id, UART_INT_RDA, 0);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define NUM_UART_PORTS 3
|
||||
#define UART_IRQn_BASE UART0_IRQn
|
||||
#define UART_INT_BASE INT_UART0
|
||||
|
||||
static platform_uart_driver_t uart_drivers[NUM_UART_PORTS];
|
||||
static void (*uart_8bit_cb_p[NUM_UART_PORTS]) ();
|
||||
static void (*uart_9bit_cb_p[NUM_UART_PORTS]) ();
|
||||
|
||||
#define SET_RX_BUF_SIZE(uart_data_p, size) \
|
||||
uart_data_p->rx_ringbuf.buf_size = size
|
||||
#define GET_RX_BUF_SIZE(uart_data_p) (uart_data_p->rx_ringbuf.buf_size)
|
||||
|
||||
#define SET_DMA_BLK_SIZE(uart_data_p, size) \
|
||||
uart_data_p->rx_ringbuf.dma_block_size = size
|
||||
#define GET_DMA_BLK_SIZE(uart_data_p) (uart_data_p->rx_ringbuf.dma_block_size)
|
||||
|
||||
#define DEFINE_UART_CB(id, mode) \
|
||||
static void \
|
||||
uart ## id ## _ ## mode ## bit_cb() {\
|
||||
uart_ ## mode ## bit_cb(id); }
|
||||
#define GET_UART_CB(id, mode) uart ## id ## _ ## mode ## bit_cb
|
||||
|
||||
/* UART callback functions */
|
||||
static void uart_8bit_cb(int port_num)
|
||||
{
|
||||
uint8_t recv_byte;
|
||||
platform_uart_driver_t* driver = &uart_drivers[port_num];
|
||||
|
||||
|
||||
/* Receive new data */
|
||||
while (UART_GetLineStatus(port_num, UART_LINESTATUS_DR) == SET) {
|
||||
if (ring_buffer_is_full(driver->rx_ring_buffer) == 0) {
|
||||
recv_byte = UART_ReceiveData(port_num);
|
||||
ring_buffer_write( driver->rx_ring_buffer, &recv_byte,1 );
|
||||
if ( ( driver->rx_size > 0 ) &&
|
||||
( ring_buffer_used_space( driver->rx_ring_buffer) >= driver->rx_size ) ) {
|
||||
mico_rtos_set_semaphore( &driver->rx_complete );
|
||||
driver->rx_size = 0;
|
||||
|
||||
}
|
||||
} else {
|
||||
/* Rx Buffer is full, discard received data */
|
||||
if (driver->flow_control != FLOW_CONTROL_DISABLED) {
|
||||
/* We need to mask the interrupt till the data
|
||||
is read; otherwise we keep getting
|
||||
data-ready interrupt infinitely */
|
||||
UART_IntMask(port_num, UART_INT_RDA, MASK);
|
||||
return;
|
||||
} else {
|
||||
UART_ReceiveData(port_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_9bit_cb(int port_num)
|
||||
{
|
||||
uint16_t data;
|
||||
platform_uart_driver_t* driver = &uart_drivers[port_num];
|
||||
uint8_t recv_byte;
|
||||
/* Receive new data */
|
||||
while (UART_GetLineStatus(port_num, UART_LINESTATUS_DR) == SET) {
|
||||
if (ring_buffer_free_space(driver->rx_ring_buffer) > 1) {
|
||||
data = UART_Receive9bits(port_num);
|
||||
recv_byte = (uint8_t) ((data >> 8) & 0x01);
|
||||
ring_buffer_write( driver->rx_ring_buffer, &recv_byte,1 );
|
||||
recv_byte = (uint8_t) (data & 0xFF);
|
||||
ring_buffer_write( driver->rx_ring_buffer, &recv_byte,1 );
|
||||
|
||||
if ( ( driver->rx_size > 0 ) &&
|
||||
( ring_buffer_used_space( driver->rx_ring_buffer ) >= driver->rx_size ) ) {
|
||||
mico_rtos_set_semaphore( &driver->rx_complete );
|
||||
driver->rx_size = 0;
|
||||
}
|
||||
} else {
|
||||
/* Rx Buffer is full, discard received data */
|
||||
if (driver->flow_control != FLOW_CONTROL_DISABLED) {
|
||||
/* We need to mask the interrupt till the data
|
||||
is read; otherwise we keep getting
|
||||
data-ready interrupt infinitely */
|
||||
UART_IntMask(port_num, UART_INT_RDA, MASK);
|
||||
return;
|
||||
} else {
|
||||
UART_Receive9bits(port_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_UART_CB(0, 8)
|
||||
DEFINE_UART_CB(1, 8)
|
||||
DEFINE_UART_CB(0, 9)
|
||||
DEFINE_UART_CB(1, 9)
|
||||
#if (NUM_UART_PORTS > 2)
|
||||
DEFINE_UART_CB(2, 8)
|
||||
DEFINE_UART_CB(2, 9)
|
||||
#if (NUM_UART_PORTS > 3)
|
||||
DEFINE_UART_CB(3, 8)
|
||||
DEFINE_UART_CB(3, 9)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static void fill_cb_array()
|
||||
{
|
||||
uart_8bit_cb_p[0] = GET_UART_CB(0, 8);
|
||||
uart_8bit_cb_p[1] = GET_UART_CB(1, 8);
|
||||
uart_9bit_cb_p[0] = GET_UART_CB(0, 9);
|
||||
uart_9bit_cb_p[1] = GET_UART_CB(1, 9);
|
||||
#if (NUM_UART_PORTS > 2)
|
||||
uart_8bit_cb_p[2] = GET_UART_CB(2, 8);
|
||||
uart_9bit_cb_p[2] = GET_UART_CB(2, 9);
|
||||
#if (NUM_UART_PORTS > 3)
|
||||
uart_8bit_cb_p[3] = GET_UART_CB(3, 8);
|
||||
uart_9bit_cb_p[3] = GET_UART_CB(3, 9);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int platform_uart_init(int port_id, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer)
|
||||
{
|
||||
UART_CFG_Type uartcfg;
|
||||
UART_FifoCfg_Type fifocfg;
|
||||
platform_uart_driver_t* driver;
|
||||
int ret;
|
||||
|
||||
//sys_work_queue_init();
|
||||
if (port_id < 0 || port_id >= NUM_UART_PORTS) {
|
||||
UART_LOG("Port %d not enabled\r\n", port_id);
|
||||
return -1;
|
||||
}
|
||||
fill_cb_array();
|
||||
|
||||
driver = &uart_drivers[port_id];
|
||||
driver->id = port_id;
|
||||
|
||||
switch (driver->id) {
|
||||
case UART0_ID:
|
||||
CLK_SetUARTClkSrc(CLK_UART_ID_0, CLK_UART_FAST);
|
||||
CLK_ModuleClkEnable(CLK_UART0);
|
||||
break;
|
||||
case UART1_ID:
|
||||
CLK_SetUARTClkSrc(CLK_UART_ID_1, CLK_UART_SLOW);
|
||||
CLK_ModuleClkEnable(CLK_UART1);
|
||||
break;
|
||||
case UART2_ID:
|
||||
CLK_SetUARTClkSrc(CLK_UART_ID_2, CLK_UART_SLOW);
|
||||
CLK_ModuleClkEnable(CLK_UART2);
|
||||
break;
|
||||
}
|
||||
/* Initialize the UART port's mdev structure */
|
||||
driver->rx_size = 0;
|
||||
driver->tx_size = 0;
|
||||
driver->last_transmit_result = kNoErr;
|
||||
driver->last_receive_result = kNoErr;
|
||||
|
||||
uartcfg.baudRate = config->baud_rate;
|
||||
uartcfg.stickyParity = DISABLE;
|
||||
fifocfg.fifoEnable = ENABLE;
|
||||
|
||||
switch (config->data_width) {
|
||||
case DATA_WIDTH_5BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_5;
|
||||
break;
|
||||
case DATA_WIDTH_6BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_6;
|
||||
break;
|
||||
case DATA_WIDTH_7BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_7;
|
||||
break;
|
||||
case DATA_WIDTH_8BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_8;
|
||||
break;
|
||||
case DATA_WIDTH_9BIT:
|
||||
uartcfg.dataBits = UART_DATABITS_8;
|
||||
uartcfg.parity = UART_PARITY_EVEN;
|
||||
uartcfg.stickyParity = DISABLE;
|
||||
fifocfg.fifoEnable = DISABLE;
|
||||
break;
|
||||
default:
|
||||
uartcfg.dataBits = UART_DATABITS_8;
|
||||
break;
|
||||
}
|
||||
switch ( config->parity )
|
||||
{
|
||||
case NO_PARITY:
|
||||
uartcfg.parity = UART_PARITY_NONE;
|
||||
break;
|
||||
|
||||
case EVEN_PARITY:
|
||||
uartcfg.parity = UART_PARITY_EVEN;
|
||||
break;
|
||||
|
||||
case ODD_PARITY:
|
||||
uartcfg.parity = UART_PARITY_ODD;
|
||||
break;
|
||||
|
||||
default:
|
||||
uartcfg.parity = UART_PARITY_NONE;
|
||||
break;
|
||||
}
|
||||
if (config->flow_control != FLOW_CONTROL_DISABLED) {
|
||||
fifocfg.autoFlowControl = ENABLE;
|
||||
} else {
|
||||
fifocfg.autoFlowControl = DISABLE;
|
||||
}
|
||||
|
||||
if ( config->stop_bits == STOP_BITS_1 )
|
||||
UART_SetStopBits(port_id, UART_STOPBITS_1);
|
||||
else
|
||||
UART_SetStopBits(port_id, UART_STOPBITS_2);
|
||||
|
||||
fifocfg.rxFifoLevel = UART_RXFIFO_BYTE_1;
|
||||
fifocfg.txFifoLevel = UART_TXFIFO_HALF_EMPTY;
|
||||
fifocfg.peripheralBusType = UART_PERIPHERAL_BITS_8;
|
||||
fifocfg.fifoDmaEnable = DISABLE;
|
||||
|
||||
UART_Disable(driver->id);
|
||||
UART_Enable(driver->id);
|
||||
UART_Init(driver->id, &uartcfg);
|
||||
UART_FifoConfig(driver->id, &fifocfg);
|
||||
|
||||
/* initialize dma driver */
|
||||
ret = dma_drv_init();
|
||||
if (ret != WM_SUCCESS) {
|
||||
UART_LOG("Failed to initialize dma driver\r\n");
|
||||
return NULL;
|
||||
}
|
||||
ret = sys_work_queue_init();
|
||||
if (ret != WM_SUCCESS) {
|
||||
UART_LOG("Failed to initialize system workqueue\r\n");
|
||||
return NULL;
|
||||
}
|
||||
if (optional_ring_buffer != NULL){
|
||||
/* Note that the ring_buffer should've been initialised first */
|
||||
driver->rx_ring_buffer = optional_ring_buffer;
|
||||
|
||||
} else {
|
||||
uint8_t *pbuf;
|
||||
pbuf = os_mem_alloc(512);
|
||||
ring_buffer_init(driver->rx_ring_buffer, pbuf, 512);
|
||||
}
|
||||
driver->rx_size = 0;
|
||||
|
||||
/* Enable UART to send dma request to DMAC */
|
||||
UART_DmaCmd(port_id, ENABLE);
|
||||
uart_dma_read_start(port_id,
|
||||
(uint8_t *)driver->rx_ring_buffer->buffer,
|
||||
driver->rx_ring_buffer->size);
|
||||
UART_IntMask(driver->id, UART_INT_RDA, UNMASK);
|
||||
|
||||
/* Configure the pinmux for uart pins */
|
||||
board_uart_pin_config(driver->id);
|
||||
|
||||
|
||||
return WM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t mico_get_time_no_os(void)
|
||||
{
|
||||
return os_total_ticks_get();
|
||||
}
|
||||
|
||||
OSStatus platform_uart_receive_bytes( int port_id, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
platform_uart_driver_t* driver;
|
||||
|
||||
if (port_id < 0 || port_id >= NUM_UART_PORTS) {
|
||||
UART_LOG("Port %d not enabled\r\n", port_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
driver = &uart_drivers[port_id];
|
||||
|
||||
|
||||
if (( data_in == NULL ) || ( expected_data_size == 0 )) {
|
||||
err = kParamErr;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
while (expected_data_size != 0)
|
||||
{
|
||||
uint32_t transfer_size = MIN( driver->rx_ring_buffer->size/2, expected_data_size );
|
||||
|
||||
/* Check if ring buffer already contains the required amount of data. */
|
||||
if ( transfer_size > ring_buffer_used_space( driver->rx_ring_buffer ) )
|
||||
{
|
||||
/* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
|
||||
driver->rx_size = transfer_size;
|
||||
|
||||
if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms) != kNoErr )
|
||||
{
|
||||
driver->rx_size = 0;
|
||||
return kTimeoutErr;
|
||||
}
|
||||
|
||||
/* Reset rx_size to prevent semaphore being set while nothing waits for the data */
|
||||
driver->rx_size = 0;
|
||||
}
|
||||
|
||||
expected_data_size -= transfer_size;
|
||||
|
||||
// Grab data from the buffer
|
||||
do
|
||||
{
|
||||
uint8_t* available_data;
|
||||
uint32_t bytes_available;
|
||||
|
||||
ring_buffer_get_data( driver->rx_ring_buffer, &available_data, &bytes_available );
|
||||
bytes_available = MIN( bytes_available, transfer_size );
|
||||
memcpy( data_in, available_data, bytes_available );
|
||||
transfer_size -= bytes_available;
|
||||
data_in = ( (uint8_t*) data_in + bytes_available );
|
||||
ring_buffer_consume( driver->rx_ring_buffer, bytes_available );
|
||||
} while ( transfer_size != 0 );
|
||||
}
|
||||
|
||||
if ( expected_data_size != 0 )
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
exit:
|
||||
//platform_mcu_powersave_enable();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_uart_transmit_bytes( int port_id, const uint8_t* data_out, uint32_t size )
|
||||
{
|
||||
int i;
|
||||
|
||||
if (port_id < 0 || port_id >= NUM_UART_PORTS) {
|
||||
UART_LOG("Port %d not enabled\r\n", port_id);
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
for(i=0; i<size; i++) {
|
||||
while (UART_GetLineStatus(port_id,
|
||||
UART_LINESTATUS_TDRQ) != SET) {
|
||||
os_thread_relinquish();
|
||||
}
|
||||
|
||||
UART_SendData(port_id, data_out[i]);
|
||||
}
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSStatus platform_uart_get_length_in_buffer( int port_id )
|
||||
{
|
||||
platform_uart_driver_t* driver;
|
||||
|
||||
if (port_id < 0 || port_id >= NUM_UART_PORTS) {
|
||||
UART_LOG("Port %d not enabled\r\n", port_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
driver = &uart_drivers[port_id];
|
||||
|
||||
return ring_buffer_used_space( driver->rx_ring_buffer );
|
||||
}
|
||||
|
||||
|
||||
OSStatus platform_uart_deinit( int port_id )
|
||||
{
|
||||
platform_uart_driver_t* driver;
|
||||
|
||||
if (port_id < 0 || port_id >= NUM_UART_PORTS) {
|
||||
UART_LOG("Port %d not enabled\r\n", port_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
driver = &uart_drivers[port_id];
|
||||
|
||||
mico_rtos_deinit_semaphore( &driver->rx_complete );
|
||||
mico_rtos_deinit_semaphore( &driver->tx_complete );
|
||||
mico_rtos_deinit_semaphore( &driver->sem_wakeup );
|
||||
mico_rtos_deinit_mutex( &driver->tx_mutex );
|
||||
driver->rx_size = 0;
|
||||
driver->tx_size = 0;
|
||||
driver->last_transmit_result = kNoErr;
|
||||
driver->last_receive_result = kNoErr;
|
||||
|
||||
while (UART_GetLineStatus(port_id, UART_LINESTATUS_TEMT)!= SET)
|
||||
;
|
||||
|
||||
UART_Disable(port_id);
|
||||
|
||||
/* de-register interrupt callbacks */
|
||||
NVIC_DisableIRQ(UART_IRQn_BASE + port_id);
|
||||
install_int_callback(UART_INT_BASE + port_id, UART_INT_RDA, 0);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user