mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-17 15:38:14 +08:00
680 lines
20 KiB
C
680 lines
20 KiB
C
/**
|
|
******************************************************************************
|
|
* @file paltform_uart.c
|
|
* @author William Xu
|
|
* @version V1.0.0
|
|
* @date 05-May-2014
|
|
* @brief This file provide UART driver functions.
|
|
******************************************************************************
|
|
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
|
* Copyright (c) 2016 MXCHIP Inc.
|
|
*
|
|
* The contents of this file may not be disclosed to third parties, copied or
|
|
* duplicated in any form, in whole or in part, without the prior written
|
|
* permission of MXCHIP Corporation.
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
#include "mico_rtos.h"
|
|
#include "mico_platform.h"
|
|
|
|
#include "platform.h"
|
|
#include "platform_peripheral.h"
|
|
#include "debug.h"
|
|
|
|
#include "pinmap.h"
|
|
|
|
#define mico_log(M, ...) custom_log("MICO", M, ##__VA_ARGS__)
|
|
#define mico_log_trace() custom_log_trace("MICO")
|
|
|
|
|
|
/******************************************************
|
|
* Constants
|
|
******************************************************/
|
|
|
|
/******************************************************
|
|
* Enumerations
|
|
******************************************************/
|
|
|
|
/******************************************************
|
|
* Type Definitions
|
|
******************************************************/
|
|
|
|
/******************************************************
|
|
* Structures
|
|
******************************************************/
|
|
|
|
/******************************************************
|
|
* Variables Definitions
|
|
******************************************************/
|
|
static const PinMap PinMap_UART_TX[] = {
|
|
{PC_3, RTL_PIN_PERI(UART0, 0, S0), RTL_PIN_FUNC(UART0, S0)},
|
|
{PE_0, RTL_PIN_PERI(UART0, 0, S1), RTL_PIN_FUNC(UART0, S1)},
|
|
{PA_7, RTL_PIN_PERI(UART0, 0, S2), RTL_PIN_FUNC(UART0, S2)},
|
|
{PD_3, RTL_PIN_PERI(UART1, 1, S0), RTL_PIN_FUNC(UART1, S0)},
|
|
{PE_4, RTL_PIN_PERI(UART1, 1, S1), RTL_PIN_FUNC(UART1, S1)},
|
|
{PB_5, RTL_PIN_PERI(UART1, 1, S2), RTL_PIN_FUNC(UART1, S2)},
|
|
{PA_4, RTL_PIN_PERI(UART2, 2, S0), RTL_PIN_FUNC(UART2, S0)},
|
|
{PC_9, RTL_PIN_PERI(UART2, 2, S1), RTL_PIN_FUNC(UART2, S1)},
|
|
{PD_7, RTL_PIN_PERI(UART2, 2, S2), RTL_PIN_FUNC(UART2, S2)},
|
|
{NC, NC, 0}
|
|
};
|
|
|
|
static const PinMap PinMap_UART_RX[] = {
|
|
{PC_0, RTL_PIN_PERI(UART0, 0, S0), RTL_PIN_FUNC(UART0, S0)},
|
|
{PE_3, RTL_PIN_PERI(UART0, 0, S1), RTL_PIN_FUNC(UART0, S1)},
|
|
{PA_6, RTL_PIN_PERI(UART0, 0, S2), RTL_PIN_FUNC(UART0, S2)},
|
|
{PD_0, RTL_PIN_PERI(UART1, 1, S0), RTL_PIN_FUNC(UART1, S0)},
|
|
{PE_7, RTL_PIN_PERI(UART1, 1, S1), RTL_PIN_FUNC(UART1, S1)},
|
|
{PB_4, RTL_PIN_PERI(UART1, 1, S2), RTL_PIN_FUNC(UART1, S2)},
|
|
{PA_0, RTL_PIN_PERI(UART2, 2, S0), RTL_PIN_FUNC(UART2, S0)},
|
|
{PC_6, RTL_PIN_PERI(UART2, 2, S1), RTL_PIN_FUNC(UART2, S1)},
|
|
{PD_4, RTL_PIN_PERI(UART2, 2, S2), RTL_PIN_FUNC(UART2, S2)},
|
|
{NC, NC, 0}
|
|
};
|
|
|
|
static uint8_t tmp_data_out;
|
|
|
|
#define UART_NUM (3)
|
|
#define SERIAL_TX_IRQ_EN 0x01
|
|
#define SERIAL_RX_IRQ_EN 0x02
|
|
#define SERIAL_TX_DMA_EN 0x01
|
|
#define SERIAL_RX_DMA_EN 0x02
|
|
|
|
//static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0};
|
|
|
|
//static uart_irq_handler irq_handler[UART_NUM];
|
|
//static uint32_t serial_irq_en[UART_NUM]={0, 0, 0};
|
|
|
|
#ifdef CONFIG_GDMA_EN
|
|
static uint32_t serial_dma_en[UART_NUM] = {0, 0, 0};
|
|
static HAL_GDMA_OP UartGdmaOp;
|
|
#endif
|
|
|
|
extern u32 ConfigDebugErr;
|
|
extern u32 ConfigDebuginfo;
|
|
|
|
/******************************************************
|
|
* Static Function Declarations
|
|
******************************************************/
|
|
/* Interrupt service functions - called from interrupt vector table */
|
|
#ifndef NO_MICO_RTOS
|
|
static void thread_wakeup(void *arg);
|
|
static void RX_PIN_WAKEUP_handler(void *arg);
|
|
#endif
|
|
|
|
/******************************************************
|
|
* Function Definitions
|
|
******************************************************/
|
|
OSStatus rtk_uart_init( platform_uart_driver_t* driver, platform_uart_t* peripheral, const platform_uart_config_t* config, ring_buffer_t* optional_ring_buffer )
|
|
{
|
|
OSStatus err = kNoErr;
|
|
uint32_t uart_tx, uart_rx;
|
|
uint32_t uart_sel;
|
|
uint8_t uart_idx;
|
|
PHAL_RUART_OP pHalRuartOp;
|
|
PHAL_RUART_ADAPTER pHalRuartAdapter;
|
|
#ifdef CONFIG_GDMA_EN
|
|
PUART_DMA_CONFIG pHalRuartDmaCfg;
|
|
PHAL_GDMA_OP pHalGdmaOp=&UartGdmaOp;
|
|
#endif
|
|
|
|
ConfigDebugErr &= (~_DBG_UART_);
|
|
ConfigDebugInfo &= (~_DBG_UART_);
|
|
|
|
|
|
//rtk_uart_deinit(driver);
|
|
|
|
// Determine the UART to use (UART0, UART1, or UART3)
|
|
uart_tx = pinmap_peripheral(peripheral->tx, PinMap_UART_TX);
|
|
uart_rx = pinmap_peripheral(peripheral->rx, PinMap_UART_RX);
|
|
|
|
uart_sel = pinmap_merge(uart_tx, uart_rx);
|
|
uart_idx = RTL_GET_PERI_IDX(uart_sel);
|
|
if (unlikely(uart_idx == (uint8_t)NC)) {
|
|
DBG_UART_ERR("%s: Cannot find matched UART\n", __FUNCTION__);
|
|
return kParamErr;
|
|
}
|
|
|
|
pHalRuartOp = &(peripheral->hal_uart_op);
|
|
pHalRuartAdapter = &(peripheral->hal_uart_adp);
|
|
|
|
if ((NULL == pHalRuartOp) || (NULL == pHalRuartAdapter)) {
|
|
DBG_UART_ERR("%s: Allocate Adapter Failed\n", __FUNCTION__);
|
|
return kParamErr;
|
|
}
|
|
|
|
HalRuartOpInit((VOID*)pHalRuartOp);
|
|
|
|
#ifdef CONFIG_GDMA_EN
|
|
HalGdmaOpInit((VOID*)pHalGdmaOp);
|
|
pHalRuartDmaCfg = &peripheral->uart_gdma_cfg;
|
|
pHalRuartDmaCfg->pHalGdmaOp = pHalGdmaOp;
|
|
pHalRuartDmaCfg->pTxHalGdmaAdapter = &peripheral->uart_gdma_adp_tx;
|
|
pHalRuartDmaCfg->pRxHalGdmaAdapter = &peripheral->uart_gdma_adp_rx;
|
|
_memset((void*)(pHalRuartDmaCfg->pTxHalGdmaAdapter), 0, sizeof(HAL_GDMA_ADAPTER));
|
|
_memset((void*)(pHalRuartDmaCfg->pRxHalGdmaAdapter), 0, sizeof(HAL_GDMA_ADAPTER));
|
|
#endif
|
|
|
|
pHalRuartOp->HalRuartAdapterLoadDef(pHalRuartAdapter, uart_idx);
|
|
pHalRuartAdapter->PinmuxSelect = RTL_GET_PERI_SEL(uart_sel);
|
|
//pHalRuartAdapter->BaudRate = 9600;
|
|
pHalRuartAdapter->IrqHandle.Priority = 6;
|
|
|
|
|
|
pHalRuartAdapter->BaudRate = config->baud_rate;
|
|
// HalRuartInit(pHalRuartAdapter);
|
|
//HalRuartSetBaudRate((VOID*)pHalRuartAdapter);
|
|
|
|
switch ( config->data_width)
|
|
{
|
|
case DATA_WIDTH_7BIT :
|
|
pHalRuartAdapter->WordLen = RUART_WLS_7BITS;
|
|
break;
|
|
|
|
case DATA_WIDTH_8BIT:
|
|
pHalRuartAdapter->WordLen = RUART_WLS_8BITS;
|
|
break;
|
|
|
|
default:
|
|
err = kParamErr;
|
|
goto exit;
|
|
}
|
|
|
|
switch ( config->parity )
|
|
{
|
|
case NO_PARITY:
|
|
pHalRuartAdapter->Parity = RUART_PARITY_DISABLE;
|
|
break;
|
|
|
|
case EVEN_PARITY:
|
|
pHalRuartAdapter->Parity = RUART_PARITY_ENABLE;
|
|
pHalRuartAdapter->ParityType = RUART_EVEN_PARITY;
|
|
break;
|
|
|
|
case ODD_PARITY:
|
|
pHalRuartAdapter->Parity = RUART_PARITY_ENABLE;
|
|
pHalRuartAdapter->ParityType = RUART_ODD_PARITY;
|
|
break;
|
|
|
|
default:
|
|
err = kParamErr;
|
|
goto exit;
|
|
}
|
|
|
|
switch ( config->stop_bits )
|
|
{
|
|
case STOP_BITS_1:
|
|
pHalRuartAdapter->StopBit = RUART_STOP_BIT_1;
|
|
break;
|
|
|
|
case STOP_BITS_2:
|
|
pHalRuartAdapter->StopBit = RUART_STOP_BIT_2;
|
|
break;
|
|
|
|
default:
|
|
err = kParamErr;
|
|
goto exit;
|
|
}
|
|
|
|
switch ( config->flow_control )
|
|
{
|
|
case FLOW_CONTROL_DISABLED:
|
|
case FLOW_CONTROL_RTS:
|
|
pHalRuartAdapter->FlowControl = AUTOFLOW_DISABLE;
|
|
break;
|
|
|
|
case FLOW_CONTROL_CTS:
|
|
case FLOW_CONTROL_CTS_RTS:
|
|
pHalRuartAdapter->FlowControl = AUTOFLOW_ENABLE;
|
|
break;
|
|
|
|
default:
|
|
err = kParamErr;
|
|
goto exit;
|
|
}
|
|
|
|
//pHalRuartOp->HalRuartInit(pHalRuartAdapter);
|
|
//pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter);
|
|
//pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter);
|
|
HalRuartInit(pHalRuartAdapter);
|
|
HalRuartSetBaudRateRtl8195a(pHalRuartAdapter);
|
|
|
|
pHalRuartAdapter->TxCompCallback = (void(*)(void*))platform_uart_tx_dma_irq;
|
|
pHalRuartAdapter->TxCompCbPara = (void*)driver;
|
|
|
|
if(!optional_ring_buffer){
|
|
pHalRuartAdapter->RxCompCallback = (void(*)(void*))platform_uart_rx_dma_irq;
|
|
pHalRuartAdapter->RxCompCbPara = (void*)driver;
|
|
}else{
|
|
pHalRuartAdapter->RxDRCallback = (void(*)(void*))platform_uart_irq;
|
|
pHalRuartAdapter->RxDRCbPara = (void*)driver;
|
|
pHalRuartAdapter->Interrupts |= RUART_IER_ERBI | RUART_IER_ELSI;
|
|
HalRuartSetIMRRtl8195a (pHalRuartAdapter);
|
|
}
|
|
|
|
//pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter);
|
|
//pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter);
|
|
pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter);
|
|
pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter);
|
|
|
|
exit:
|
|
return err;
|
|
}
|
|
|
|
OSStatus rtk_uart_deinit( platform_uart_driver_t* driver)
|
|
{
|
|
OSStatus err = kNoErr;
|
|
PHAL_RUART_ADAPTER pHalRuartAdapter;
|
|
#ifdef CONFIG_GDMA_EN
|
|
u8 uart_idx;
|
|
PUART_DMA_CONFIG pHalRuartDmaCfg;
|
|
#endif
|
|
|
|
pHalRuartAdapter = &(driver->peripheral->hal_uart_adp);
|
|
|
|
HalRuartDeInit(pHalRuartAdapter);
|
|
|
|
#ifdef CONFIG_GDMA_EN
|
|
uart_idx = pHalRuartAdapter->UartIndex;
|
|
pHalRuartDmaCfg = &driver->peripheral->uart_gdma_cfg;
|
|
if (serial_dma_en[uart_idx] & SERIAL_RX_DMA_EN) {
|
|
HalRuartRxGdmaDeInit(pHalRuartDmaCfg);
|
|
serial_dma_en[uart_idx] &= ~SERIAL_RX_DMA_EN;
|
|
}
|
|
|
|
if (serial_dma_en[uart_idx] & SERIAL_TX_DMA_EN) {
|
|
HalRuartTxGdmaDeInit(pHalRuartDmaCfg);
|
|
serial_dma_en[uart_idx] &= ~SERIAL_TX_DMA_EN;
|
|
}
|
|
#endif
|
|
exit:
|
|
return err;
|
|
}
|
|
|
|
// return the byte count received before timeout, or error(<0)
|
|
OSStatus rtk_uart_recv_stream_timeout (platform_uart_driver_t* driver, char *prxbuf, uint32_t len, uint32_t timeout_ms, void *force_cs)
|
|
{
|
|
PHAL_RUART_OP pHalRuartOp;
|
|
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(driver->peripheral->hal_uart_adp);
|
|
uint32_t TimeoutCount=0, StartCount;
|
|
int ret;
|
|
void (*task_yield)(void);
|
|
|
|
task_yield = NULL;
|
|
pHalRuartOp = &(driver->peripheral->hal_uart_op);
|
|
ret = pHalRuartOp->HalRuartIntRecv(pHalRuartAdapter, (u8*)prxbuf, len);
|
|
if ((ret == HAL_OK) && (timeout_ms > 0)) {
|
|
TimeoutCount = (timeout_ms*1000/TIMER_TICK_US);
|
|
StartCount = HalTimerOp.HalTimerReadCount(1);
|
|
task_yield = (void(*)(void))force_cs;
|
|
while (pHalRuartAdapter->State & HAL_UART_STATE_BUSY_RX) {
|
|
if (HAL_TIMEOUT == RuartIsTimeout(StartCount, TimeoutCount)) {
|
|
ret = pHalRuartOp->HalRuartStopRecv((VOID*)pHalRuartAdapter);
|
|
ret = pHalRuartOp->HalRuartResetRxFifo((VOID*)pHalRuartAdapter);
|
|
pHalRuartAdapter->Status = HAL_UART_STATUS_TIMEOUT;
|
|
return kTimeoutErr;
|
|
}
|
|
if (NULL != task_yield) {
|
|
task_yield();
|
|
}
|
|
}
|
|
return kNoErr;
|
|
}else {
|
|
return kGeneralErr;
|
|
}
|
|
}
|
|
|
|
int rtk_uart_readable(platform_uart_driver_t* driver)
|
|
{
|
|
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(driver->peripheral->hal_uart_adp);
|
|
u8 uart_idx = pHalRuartAdapter->UartIndex;
|
|
|
|
if ((HAL_RUART_READ32(uart_idx, RUART_LINE_STATUS_REG_OFF)) & RUART_LINE_STATUS_REG_DR) {
|
|
return 1;
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int rtk_uart_getc(platform_uart_driver_t* driver)
|
|
{
|
|
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(driver->peripheral->hal_uart_adp);
|
|
u8 uart_idx = pHalRuartAdapter->UartIndex;
|
|
|
|
while (!rtk_uart_readable(driver));
|
|
return (int)((HAL_RUART_READ32(uart_idx, RUART_REV_BUF_REG_OFF)) & 0xFF);
|
|
}
|
|
|
|
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 )
|
|
{
|
|
OSStatus err = kNoErr;
|
|
|
|
platform_mcu_powersave_disable();
|
|
|
|
require_action_quiet( ( driver != NULL ) && ( peripheral != NULL ) && ( config != NULL ), exit, err = kParamErr);
|
|
require_action_quiet( (optional_ring_buffer == NULL) || ((optional_ring_buffer->buffer != NULL ) && (optional_ring_buffer->size != 0)), exit, err = kParamErr);
|
|
|
|
driver->rx_size = 0;
|
|
driver->tx_size = 0;
|
|
driver->last_transmit_result = kNoErr;
|
|
driver->last_receive_result = kNoErr;
|
|
driver->peripheral = (platform_uart_t*)peripheral;
|
|
#ifndef NO_MICO_RTOS
|
|
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 );
|
|
#else
|
|
driver->tx_complete = false;
|
|
driver->rx_complete = false;
|
|
#endif
|
|
|
|
err = rtk_uart_init(driver, (platform_uart_t*)peripheral, config, optional_ring_buffer);
|
|
|
|
if (optional_ring_buffer != NULL){
|
|
/* Note that the ring_buffer should've been initialised first */
|
|
driver->rx_buffer = optional_ring_buffer;
|
|
driver->rx_size = 0;
|
|
//platform_uart_receive_bytes( uart, optional_rx_buffer->buffer, optional_rx_buffer->size, 0 );
|
|
}
|
|
|
|
exit:
|
|
MicoMcuPowerSaveConfig(true);
|
|
return err;
|
|
}
|
|
|
|
OSStatus platform_uart_deinit( platform_uart_driver_t* driver )
|
|
{
|
|
uint8_t uart_number;
|
|
OSStatus err = kNoErr;
|
|
|
|
platform_mcu_powersave_disable();
|
|
|
|
require_action_quiet( ( driver != NULL ), exit, err = kParamErr);
|
|
|
|
err = rtk_uart_deinit(driver);
|
|
|
|
#ifndef NO_MICO_RTOS
|
|
mico_rtos_deinit_semaphore( &driver->rx_complete );
|
|
mico_rtos_deinit_semaphore( &driver->tx_complete );
|
|
mico_rtos_deinit_mutex( &driver->tx_mutex );
|
|
#else
|
|
driver->rx_complete = false;
|
|
driver->tx_complete = false;
|
|
#endif
|
|
driver->rx_size = 0;
|
|
driver->tx_size = 0;
|
|
driver->last_transmit_result = kNoErr;
|
|
driver->last_receive_result = 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 err = kNoErr;
|
|
#ifndef NO_MICO_RTOS
|
|
mico_rtos_lock_mutex(&driver->tx_mutex);
|
|
#endif
|
|
if( size == 1 )
|
|
{
|
|
tmp_data_out = *data_out;
|
|
data_out = &tmp_data_out;
|
|
}
|
|
|
|
platform_mcu_powersave_disable();
|
|
|
|
PHAL_RUART_OP pHalRuartOp;
|
|
PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(driver->peripheral->hal_uart_adp);
|
|
u8 uart_idx = pHalRuartAdapter->UartIndex;
|
|
int32_t ret;
|
|
|
|
pHalRuartOp = &(driver->peripheral->hal_uart_op);
|
|
|
|
if ((serial_dma_en[uart_idx] & SERIAL_TX_DMA_EN)==0) {
|
|
PUART_DMA_CONFIG pHalRuartDmaCfg;
|
|
|
|
pHalRuartDmaCfg = &driver->peripheral->uart_gdma_cfg;
|
|
if (HAL_OK == HalRuartTxGdmaInit(pHalRuartOp, pHalRuartAdapter, pHalRuartDmaCfg)) {
|
|
serial_dma_en[uart_idx] |= SERIAL_TX_DMA_EN;
|
|
}
|
|
else {
|
|
return kGeneralErr;
|
|
}
|
|
}
|
|
|
|
HalRuartEnterCritical(pHalRuartAdapter);
|
|
ret = pHalRuartOp->HalRuartDmaSend(pHalRuartAdapter, (u8*)data_out, size);
|
|
HalRuartExitCritical(pHalRuartAdapter);
|
|
if(ret != HAL_OK)
|
|
return kGeneralErr;
|
|
|
|
/* Wait for transmission complete */
|
|
#ifndef NO_MICO_RTOS
|
|
mico_rtos_get_semaphore( &driver->tx_complete, MICO_NEVER_TIMEOUT );
|
|
#else
|
|
while( driver->tx_complete == false );
|
|
driver->tx_complete = false;
|
|
#endif
|
|
|
|
/* Disable DMA and clean up */
|
|
driver->tx_size = 0;
|
|
err = driver->last_transmit_result;
|
|
|
|
exit:
|
|
platform_mcu_powersave_enable();
|
|
#ifndef NO_MICO_RTOS
|
|
mico_rtos_unlock_mutex(&driver->tx_mutex);
|
|
#endif
|
|
return err;
|
|
}
|
|
|
|
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;
|
|
|
|
//platform_mcu_powersave_disable();
|
|
|
|
require_action_quiet( ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ), exit, err = kParamErr);
|
|
|
|
if ( driver->rx_buffer != NULL )
|
|
{
|
|
/* Check if ring buffer already contains the required amount of data. */
|
|
if ( expected_data_size > ring_buffer_used_space( driver->rx_buffer ) )
|
|
{
|
|
/* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
|
|
driver->rx_size = expected_data_size;
|
|
if(expected_data_size <= ring_buffer_used_space( driver->rx_buffer ))
|
|
{
|
|
goto end;
|
|
}
|
|
|
|
#ifndef NO_MICO_RTOS
|
|
if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms) != kNoErr )
|
|
{
|
|
driver->rx_size = 0;
|
|
return kTimeoutErr;
|
|
}
|
|
#else
|
|
driver->rx_complete = false;
|
|
if(expected_data_size <= ring_buffer_used_space( driver->rx_buffer ))
|
|
{
|
|
goto end;
|
|
}
|
|
int delay_start = mico_get_time_no_os();
|
|
while(driver->rx_complete == false){
|
|
if(mico_get_time_no_os() >= delay_start + timeout_ms && timeout_ms != MICO_NEVER_TIMEOUT){
|
|
driver->rx_size = 0;
|
|
return kTimeoutErr;
|
|
}
|
|
}
|
|
#endif
|
|
end:
|
|
/* Reset rx_size to prevent semaphore being set while nothing waits for the data */
|
|
driver->rx_size = 0;
|
|
}
|
|
|
|
// Grab data from the buffer
|
|
uint32_t read_size = 0;
|
|
ring_buffer_read(driver->rx_buffer, data_in, expected_data_size, &read_size);
|
|
}
|
|
else
|
|
{
|
|
err = rtk_uart_recv_stream_timeout( driver, data_in, expected_data_size, timeout_ms, NULL );
|
|
}
|
|
|
|
exit:
|
|
//platform_mcu_powersave_enable();
|
|
return err;
|
|
}
|
|
|
|
|
|
uint32_t platform_uart_get_length_in_buffer( platform_uart_driver_t* driver )
|
|
{
|
|
return ring_buffer_used_space( driver->rx_buffer );
|
|
}
|
|
|
|
|
|
#if 0
|
|
uint8_t platform_uart_get_port_number( USART_TypeDef* uart )
|
|
{
|
|
if ( uart == USART1 )
|
|
{
|
|
return 0;
|
|
}
|
|
else if ( uart == USART2 )
|
|
{
|
|
return 1;
|
|
}
|
|
else if ( uart == USART3 )
|
|
{
|
|
return 2;
|
|
}
|
|
else if ( uart == UART4 )
|
|
{
|
|
return 3;
|
|
}
|
|
else if ( uart == UART5 )
|
|
{
|
|
return 4;
|
|
}
|
|
else if ( uart == USART6 )
|
|
{
|
|
return 5;
|
|
}
|
|
else
|
|
{
|
|
return 0xff;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifndef NO_MICO_RTOS
|
|
static void thread_wakeup(void *arg)
|
|
{
|
|
#if 0
|
|
platform_uart_driver_t* driver = arg;
|
|
|
|
while(1){
|
|
if( mico_rtos_get_semaphore( driver->sem_wakeup, 1000) != kNoErr )
|
|
{
|
|
platform_gpio_irq_enable( driver->peripheral->pin_rx, IRQ_TRIGGER_FALLING_EDGE, RX_PIN_WAKEUP_handler, driver );
|
|
platform_mcu_powersave_enable( );
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/******************************************************
|
|
* Interrupt Service Routines
|
|
******************************************************/
|
|
#ifndef NO_MICO_RTOS
|
|
void RX_PIN_WAKEUP_handler(void *arg)
|
|
{
|
|
#if 0
|
|
(void)arg;
|
|
platform_uart_driver_t* driver = arg;
|
|
uint32_t uart_number;
|
|
|
|
platform_gpio_enable_clock( driver->peripheral->pin_rx );
|
|
|
|
uart_number = platform_uart_get_port_number( driver->peripheral->port );
|
|
|
|
uart_peripheral_clock_functions[ uart_number ]( uart_peripheral_clocks[ uart_number ], ENABLE );
|
|
|
|
/* Enable DMA peripheral clock */
|
|
if ( driver->peripheral->tx_dma_config.controller == DMA1 )
|
|
{
|
|
RCC->AHB1ENR |= RCC_AHB1Periph_DMA1;
|
|
}
|
|
else
|
|
{
|
|
RCC->AHB1ENR |= RCC_AHB1Periph_DMA2;
|
|
}
|
|
|
|
platform_gpio_irq_disable( driver->peripheral->pin_rx );
|
|
platform_mcu_powersave_disable( );
|
|
mico_rtos_set_semaphore( &driver->sem_wakeup );
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
void platform_uart_irq( platform_uart_driver_t* driver )
|
|
{
|
|
int status;
|
|
uint8_t rxData;
|
|
//platform_uart_port_t* uart = (platform_uart_port_t*) driver->peripheral->port;
|
|
|
|
rxData = rtk_uart_getc(driver);
|
|
ring_buffer_write( driver->rx_buffer, &rxData,1 );
|
|
|
|
status++;
|
|
|
|
//printf("\r\nnuart irq %d\r\n", status);
|
|
|
|
// Notify thread if sufficient data are available
|
|
if ( ( driver->rx_size > 0 ) &&
|
|
( ring_buffer_used_space( driver->rx_buffer ) >= driver->rx_size ) )
|
|
{
|
|
#ifndef NO_MICO_RTOS
|
|
mico_rtos_set_semaphore( &driver->rx_complete );
|
|
#else
|
|
driver->rx_complete = true;
|
|
#endif
|
|
driver->rx_size = 0;
|
|
}
|
|
|
|
}
|
|
|
|
void platform_uart_tx_dma_irq( platform_uart_driver_t* driver )
|
|
{
|
|
#ifndef NO_MICO_RTOS
|
|
/* Set semaphore regardless of result to prevent waiting thread from locking up */
|
|
mico_rtos_set_semaphore( &driver->tx_complete );
|
|
#else
|
|
driver->tx_complete = true;
|
|
#endif
|
|
}
|
|
|
|
void platform_uart_rx_dma_irq( platform_uart_driver_t* driver )
|
|
{
|
|
mico_log("uart irq");
|
|
|
|
/* Set semaphore regardless of result to prevent waiting thread from locking up */
|
|
#ifndef NO_MICO_RTOS
|
|
mico_rtos_set_semaphore( &driver->rx_complete );
|
|
#else
|
|
driver->rx_complete = true;
|
|
#endif
|
|
|
|
}
|
|
|
|
|