| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- /*
- * Copyright (c) 2021 ARM Limited. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the License); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * ----------------------------------------------------------------------
- *
- * $Date: 1. March 2021
- * $Revision: V1.0.0
- *
- * Project: CMSIS-DAP Source
- * Title: UART.c CMSIS-DAP UART
- *
- *---------------------------------------------------------------------------*/
- #include "DAP_config.h"
- #include "DAP.h"
- #if (DAP_UART != 0)
- #ifdef DAP_FW_V1
- #error "UART Communication Port not supported in DAP V1!"
- #endif
- #include "Driver_USART.h"
- #include "cmsis_os2.h"
- #include <string.h>
- #define UART_RX_BLOCK_SIZE 32U /* Uart Rx Block Size (must be 2^n) */
- // USART Driver
- #define _USART_Driver_(n) Driver_USART##n
- #define USART_Driver_(n) _USART_Driver_(n)
- extern ARM_DRIVER_USART USART_Driver_(DAP_UART_DRIVER);
- #define pUSART (&USART_Driver_(DAP_UART_DRIVER))
- // UART Configuration
- #if (DAP_UART_USB_COM_PORT != 0)
- static uint8_t UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
- #else
- static uint8_t UartTransport = DAP_UART_TRANSPORT_NONE;
- #endif
- // UART Flags
- static uint8_t UartConfigured = 0U;
- static uint8_t UartReceiveEnabled = 0U;
- static uint8_t UartTransmitEnabled = 0U;
- static uint8_t UartTransmitActive = 0U;
- // UART TX Buffer
- static uint8_t UartTxBuf[DAP_UART_TX_BUFFER_SIZE];
- static volatile uint32_t UartTxIndexI = 0U;
- static volatile uint32_t UartTxIndexO = 0U;
- // UART RX Buffer
- static uint8_t UartRxBuf[DAP_UART_RX_BUFFER_SIZE];
- static volatile uint32_t UartRxIndexI = 0U;
- static volatile uint32_t UartRxIndexO = 0U;
- // Uart Errors
- static volatile uint8_t UartErrorRxDataLost = 0U;
- static volatile uint8_t UartErrorFraming = 0U;
- static volatile uint8_t UartErrorParity = 0U;
- // UART Transmit
- static uint32_t UartTxNum = 0U;
- // Function prototypes
- static uint8_t UART_Init (void);
- static void UART_Uninit (void);
- static uint8_t UART_Get_Status (void);
- static uint8_t UART_Receive_Enable (void);
- static uint8_t UART_Transmit_Enable (void);
- static void UART_Receive_Disable (void);
- static void UART_Transmit_Disable (void);
- static void UART_Receive_Flush (void);
- static void UART_Transmit_Flush (void);
- static void UART_Receive (void);
- static void UART_Transmit (void);
- // USART Driver Callback function
- // event: event mask
- static void USART_Callback (uint32_t event) {
- if (event & ARM_USART_EVENT_SEND_COMPLETE) {
- UartTxIndexO += UartTxNum;
- UartTransmitActive = 0U;
- UART_Transmit();
- }
- if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) {
- UartRxIndexI += UART_RX_BLOCK_SIZE;
- UART_Receive();
- }
- if (event & ARM_USART_EVENT_RX_OVERFLOW) {
- UartErrorRxDataLost = 1U;
- }
- if (event & ARM_USART_EVENT_RX_FRAMING_ERROR) {
- UartErrorFraming = 1U;
- }
- if (event & ARM_USART_EVENT_RX_PARITY_ERROR) {
- UartErrorParity = 1U;
- }
- }
- // Init UART
- // return: DAP_OK or DAP_ERROR
- static uint8_t UART_Init (void) {
- int32_t status;
- uint8_t ret = DAP_ERROR;
- UartConfigured = 0U;
- UartReceiveEnabled = 0U;
- UartTransmitEnabled = 0U;
- UartTransmitActive = 0U;
- UartErrorRxDataLost = 0U;
- UartErrorFraming = 0U;
- UartErrorParity = 0U;
- UartTxIndexI = 0U;
- UartTxIndexO = 0U;
- UartRxIndexI = 0U;
- UartRxIndexO = 0U;
- UartTxNum = 0U;
- status = pUSART->Initialize(USART_Callback);
- if (status == ARM_DRIVER_OK) {
- status = pUSART->PowerControl(ARM_POWER_FULL);
- }
- if (status == ARM_DRIVER_OK) {
- ret = DAP_OK;
- }
- return (ret);
- }
- // Un-Init UART
- static void UART_Uninit (void) {
- UartConfigured = 0U;
- pUSART->PowerControl(ARM_POWER_OFF);
- pUSART->Uninitialize();
- }
- // Get UART Status
- // return: status
- static uint8_t UART_Get_Status (void) {
- uint8_t status = 0U;
- if (UartReceiveEnabled != 0U) {
- status |= DAP_UART_STATUS_RX_ENABLED;
- }
- if (UartErrorRxDataLost != 0U) {
- UartErrorRxDataLost = 0U;
- status |= DAP_UART_STATUS_RX_DATA_LOST;
- }
- if (UartErrorFraming != 0U) {
- UartErrorFraming = 0U;
- status |= DAP_UART_STATUS_FRAMING_ERROR;
- }
- if (UartErrorParity != 0U) {
- UartErrorParity = 0U;
- status |= DAP_UART_STATUS_PARITY_ERROR;
- }
- if (UartTransmitEnabled != 0U) {
- status |= DAP_UART_STATUS_TX_ENABLED;
- }
- return (status);
- }
- // Enable UART Receive
- // return: DAP_OK or DAP_ERROR
- static uint8_t UART_Receive_Enable (void) {
- int32_t status;
- uint8_t ret = DAP_ERROR;
- if (UartReceiveEnabled == 0U) {
- // Flush Buffers
- UartRxIndexI = 0U;
- UartRxIndexO = 0U;
- UART_Receive();
- status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
- if (status == ARM_DRIVER_OK) {
- UartReceiveEnabled = 1U;
- ret = DAP_OK;
- }
- } else {
- ret = DAP_OK;
- }
- return (ret);
- }
- // Enable UART Transmit
- // return: DAP_OK or DAP_ERROR
- static uint8_t UART_Transmit_Enable (void) {
- int32_t status;
- uint8_t ret = DAP_ERROR;
- if (UartTransmitEnabled == 0U) {
- // Flush Buffers
- UartTransmitActive = 0U;
- UartTxIndexI = 0U;
- UartTxIndexO = 0U;
- UartTxNum = 0U;
- status = pUSART->Control(ARM_USART_CONTROL_TX, 1U);
- if (status == ARM_DRIVER_OK) {
- UartTransmitEnabled = 1U;
- ret = DAP_OK;
- }
- } else {
- ret = DAP_OK;
- }
- return (ret);
- }
- // Disable UART Receive
- static void UART_Receive_Disable (void) {
- if (UartReceiveEnabled != 0U) {
- pUSART->Control(ARM_USART_CONTROL_RX, 0U);
- pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
- UartReceiveEnabled = 0U;
- }
- }
- // Disable UART Transmit
- static void UART_Transmit_Disable (void) {
- if (UartTransmitEnabled != 0U) {
- pUSART->Control(ARM_USART_ABORT_SEND, 0U);
- pUSART->Control(ARM_USART_CONTROL_TX, 0U);
- UartTransmitActive = 0U;
- UartTransmitEnabled = 0U;
- }
- }
- // Flush UART Receive buffer
- static void UART_Receive_Flush (void) {
- pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
- UartRxIndexI = 0U;
- UartRxIndexO = 0U;
- if (UartReceiveEnabled != 0U) {
- UART_Receive();
- }
- }
- // Flush UART Transmit buffer
- static void UART_Transmit_Flush (void) {
- pUSART->Control(ARM_USART_ABORT_SEND, 0U);
- UartTransmitActive = 0U;
- UartTxIndexI = 0U;
- UartTxIndexO = 0U;
- UartTxNum = 0U;
- }
- // Receive data from target via UART
- static void UART_Receive (void) {
- uint32_t index;
- index = UartRxIndexI & (DAP_UART_RX_BUFFER_SIZE - 1U);
- pUSART->Receive(&UartRxBuf[index], UART_RX_BLOCK_SIZE);
- }
- // Transmit available data to target via UART
- static void UART_Transmit (void) {
- uint32_t count;
- uint32_t index;
- count = UartTxIndexI - UartTxIndexO;
- index = UartTxIndexO & (DAP_UART_TX_BUFFER_SIZE - 1U);
- if (count != 0U) {
- if ((index + count) <= DAP_UART_TX_BUFFER_SIZE) {
- UartTxNum = count;
- } else {
- UartTxNum = DAP_UART_TX_BUFFER_SIZE - index;
- }
- UartTransmitActive = 1U;
- pUSART->Send(&UartTxBuf[index], UartTxNum);
- }
- }
- // Process UART Transport command and prepare response
- // request: pointer to request data
- // response: pointer to response data
- // return: number of bytes in response (lower 16 bits)
- // number of bytes in request (upper 16 bits)
- uint32_t UART_Transport (const uint8_t *request, uint8_t *response) {
- uint8_t transport;
- uint8_t ret = DAP_ERROR;
- transport = *request;
- switch (transport) {
- case DAP_UART_TRANSPORT_NONE:
- switch (UartTransport) {
- case DAP_UART_TRANSPORT_NONE:
- ret = DAP_OK;
- break;
- case DAP_UART_TRANSPORT_USB_COM_PORT:
- #if (DAP_UART_USB_COM_PORT != 0)
- USB_COM_PORT_Activate(0U);
- UartTransport = DAP_UART_TRANSPORT_NONE;
- ret = DAP_OK;
- #endif
- break;
- case DAP_UART_TRANSPORT_DAP_COMMAND:
- UART_Receive_Disable();
- UART_Transmit_Disable();
- UART_Uninit();
- UartTransport = DAP_UART_TRANSPORT_NONE;
- ret= DAP_OK;
- break;
- }
- break;
- case DAP_UART_TRANSPORT_USB_COM_PORT:
- switch (UartTransport) {
- case DAP_UART_TRANSPORT_NONE:
- #if (DAP_UART_USB_COM_PORT != 0)
- if (USB_COM_PORT_Activate(1U) == 0U) {
- UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
- ret = DAP_OK;
- }
- #endif
- break;
- case DAP_UART_TRANSPORT_USB_COM_PORT:
- ret = DAP_OK;
- break;
- case DAP_UART_TRANSPORT_DAP_COMMAND:
- UART_Receive_Disable();
- UART_Transmit_Disable();
- UART_Uninit();
- UartTransport = DAP_UART_TRANSPORT_NONE;
- #if (DAP_UART_USB_COM_PORT != 0)
- if (USB_COM_PORT_Activate(1U) == 0U) {
- UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
- ret = DAP_OK;
- }
- #endif
- break;
- }
- break;
- case DAP_UART_TRANSPORT_DAP_COMMAND:
- switch (UartTransport) {
- case DAP_UART_TRANSPORT_NONE:
- ret = UART_Init();
- if (ret == DAP_OK) {
- UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND;
- }
- break;
- case DAP_UART_TRANSPORT_USB_COM_PORT:
- #if (DAP_UART_USB_COM_PORT != 0)
- USB_COM_PORT_Activate(0U);
- UartTransport = DAP_UART_TRANSPORT_NONE;
- #endif
- ret = UART_Init();
- if (ret == DAP_OK) {
- UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND;
- }
- break;
- case DAP_UART_TRANSPORT_DAP_COMMAND:
- ret = DAP_OK;
- break;
- }
- break;
- default:
- break;
- }
- *response = ret;
- return ((1U << 16) | 1U);
- }
- // Process UART Configure command and prepare response
- // request: pointer to request data
- // response: pointer to response data
- // return: number of bytes in response (lower 16 bits)
- // number of bytes in request (upper 16 bits)
- uint32_t UART_Configure (const uint8_t *request, uint8_t *response) {
- uint8_t control, status;
- uint32_t baudrate;
- int32_t result;
- if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
- status = DAP_UART_CFG_ERROR_DATA_BITS |
- DAP_UART_CFG_ERROR_PARITY |
- DAP_UART_CFG_ERROR_STOP_BITS;
- baudrate = 0U; // baudrate error
- } else {
- status = 0U;
- control = *request;
- baudrate = (uint32_t)(*(request+1) << 0) |
- (uint32_t)(*(request+2) << 8) |
- (uint32_t)(*(request+3) << 16) |
- (uint32_t)(*(request+4) << 24);
- result = pUSART->Control(control |
- ARM_USART_MODE_ASYNCHRONOUS |
- ARM_USART_FLOW_CONTROL_NONE,
- baudrate);
- if (result == ARM_DRIVER_OK) {
- UartConfigured = 1U;
- } else {
- UartConfigured = 0U;
- switch (result) {
- case ARM_USART_ERROR_BAUDRATE:
- status = 0U;
- baudrate = 0U;
- break;
- case ARM_USART_ERROR_DATA_BITS:
- status = DAP_UART_CFG_ERROR_DATA_BITS;
- break;
- case ARM_USART_ERROR_PARITY:
- status = DAP_UART_CFG_ERROR_PARITY;
- break;
- case ARM_USART_ERROR_STOP_BITS:
- status = DAP_UART_CFG_ERROR_STOP_BITS;
- break;
- default:
- status = DAP_UART_CFG_ERROR_DATA_BITS |
- DAP_UART_CFG_ERROR_PARITY |
- DAP_UART_CFG_ERROR_STOP_BITS;
- baudrate = 0U;
- break;
- }
- }
- }
- *response++ = status;
- *response++ = (uint8_t)(baudrate >> 0);
- *response++ = (uint8_t)(baudrate >> 8);
- *response++ = (uint8_t)(baudrate >> 16);
- *response = (uint8_t)(baudrate >> 24);
- return ((5U << 16) | 5U);
- }
- // Process UART Control command and prepare response
- // request: pointer to request data
- // response: pointer to response data
- // return: number of bytes in response (lower 16 bits)
- // number of bytes in request (upper 16 bits)
- uint32_t UART_Control (const uint8_t *request, uint8_t *response) {
- uint8_t control;
- uint8_t result;
- uint8_t ret = DAP_OK;
- if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
- ret = DAP_ERROR;
- } else {
-
- control = *request;
- if ((control & DAP_UART_CONTROL_RX_DISABLE) != 0U) {
- // Receive disable
- UART_Receive_Disable();
- } else if ((control & DAP_UART_CONTROL_RX_ENABLE) != 0U) {
- // Receive enable
- if (UartConfigured != 0U) {
- result = UART_Receive_Enable();
- if (result != DAP_OK) {
- ret = DAP_ERROR;
- }
- } else {
- ret = DAP_ERROR;
- }
- }
- if ((control & DAP_UART_CONTROL_RX_BUF_FLUSH) != 0U) {
- UART_Receive_Flush();
- }
- if ((control & DAP_UART_CONTROL_TX_DISABLE) != 0U) {
- // Transmit disable
- UART_Transmit_Disable();
- } else if ((control & DAP_UART_CONTROL_TX_ENABLE) != 0U) {
- // Transmit enable
- if (UartConfigured != 0U) {
- result = UART_Transmit_Enable();
- if (result != DAP_OK) {
- ret = DAP_ERROR;
- }
- } else {
- ret = DAP_ERROR;
- }
- }
- if ((control & DAP_UART_CONTROL_TX_BUF_FLUSH) != 0U) {
- UART_Transmit_Flush();
- }
- }
- *response = ret;
- return ((1U << 16) | 1U);
- }
- // Process UART Status command and prepare response
- // response: pointer to response data
- // return: number of bytes in response (lower 16 bits)
- // number of bytes in request (upper 16 bits)
- uint32_t UART_Status (uint8_t *response) {
- uint32_t rx_cnt, tx_cnt;
- uint32_t cnt;
- uint8_t status;
- if ((UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) ||
- (UartConfigured == 0U)) {
- rx_cnt = 0U;
- tx_cnt = 0U;
- status = 0U;
- } else {
- rx_cnt = UartRxIndexI - UartRxIndexO;
- rx_cnt += pUSART->GetRxCount();
- if (rx_cnt > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) {
- // Overflow
- UartErrorRxDataLost = 1U;
- rx_cnt = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2));
- UartRxIndexO = UartRxIndexI - rx_cnt;
- }
- tx_cnt = UartTxIndexI - UartTxIndexO;
- cnt = pUSART->GetTxCount();
- if (UartTransmitActive != 0U) {
- tx_cnt -= cnt;
- }
- status = UART_Get_Status();
- }
- *response++ = status;
- *response++ = (uint8_t)(rx_cnt >> 0);
- *response++ = (uint8_t)(rx_cnt >> 8);
- *response++ = (uint8_t)(rx_cnt >> 16);
- *response++ = (uint8_t)(rx_cnt >> 24);
- *response++ = (uint8_t)(tx_cnt >> 0);
- *response++ = (uint8_t)(tx_cnt >> 8);
- *response++ = (uint8_t)(tx_cnt >> 16);
- *response = (uint8_t)(tx_cnt >> 24);
- return ((0U << 16) | 9U);
- }
- // Process UART Transfer command and prepare response
- // request: pointer to request data
- // response: pointer to response data
- // return: number of bytes in response (lower 16 bits)
- // number of bytes in request (upper 16 bits)
- uint32_t UART_Transfer (const uint8_t *request, uint8_t *response) {
- uint32_t rx_cnt, tx_cnt;
- uint32_t rx_num, tx_num;
- uint8_t *rx_data;
- const
- uint8_t *tx_data;
- uint32_t num;
- uint32_t index;
- uint8_t status;
- if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
- status = 0U;
- rx_cnt = 0U;
- tx_cnt = 0U;
- } else {
- // RX Data
- rx_cnt = ((uint32_t)(*(request+0) << 0) |
- (uint32_t)(*(request+1) << 8));
- if (rx_cnt > (DAP_PACKET_SIZE - 6U)) {
- rx_cnt = (DAP_PACKET_SIZE - 6U);
- }
- rx_num = UartRxIndexI - UartRxIndexO;
- rx_num += pUSART->GetRxCount();
- if (rx_num > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) {
- // Overflow
- UartErrorRxDataLost = 1U;
- rx_num = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2));
- UartRxIndexO = UartRxIndexI - rx_num;
- }
- if (rx_cnt > rx_num) {
- rx_cnt = rx_num;
- }
- rx_data = (response+5);
- index = UartRxIndexO & (DAP_UART_RX_BUFFER_SIZE - 1U);
- if ((index + rx_cnt) <= DAP_UART_RX_BUFFER_SIZE) {
- memcpy( rx_data, &UartRxBuf[index], rx_cnt);
- } else {
- num = DAP_UART_RX_BUFFER_SIZE - index;
- memcpy( rx_data, &UartRxBuf[index], num);
- memcpy(&rx_data[num], &UartRxBuf[0], rx_cnt - num);
- }
- UartRxIndexO += rx_cnt;
- // TX Data
- tx_cnt = ((uint32_t)(*(request+2) << 0) |
- (uint32_t)(*(request+3) << 8));
- tx_data = (request+4);
- if (tx_cnt > (DAP_PACKET_SIZE - 5U)) {
- tx_cnt = (DAP_PACKET_SIZE - 5U);
- }
- tx_num = UartTxIndexI - UartTxIndexO;
- num = pUSART->GetTxCount();
- if (UartTransmitActive != 0U) {
- tx_num -= num;
- }
- if (tx_cnt > (DAP_UART_TX_BUFFER_SIZE - tx_num)) {
- tx_cnt = (DAP_UART_TX_BUFFER_SIZE - tx_num);
- }
- index = UartTxIndexI & (DAP_UART_TX_BUFFER_SIZE - 1U);
- if ((index + tx_cnt) <= DAP_UART_TX_BUFFER_SIZE) {
- memcpy(&UartTxBuf[index], tx_data, tx_cnt);
- } else {
- num = DAP_UART_TX_BUFFER_SIZE - index;
- memcpy(&UartTxBuf[index], tx_data, num);
- memcpy(&UartTxBuf[0], &tx_data[num], tx_cnt - num);
- }
- UartTxIndexI += tx_cnt;
- if (UartTransmitActive == 0U) {
- UART_Transmit();
- }
- status = UART_Get_Status();
- }
- *response++ = status;
- *response++ = (uint8_t)(tx_cnt >> 0);
- *response++ = (uint8_t)(tx_cnt >> 8);
- *response++ = (uint8_t)(rx_cnt >> 0);
- *response = (uint8_t)(rx_cnt >> 8);
- return (((4U + tx_cnt) << 16) | (5U + rx_cnt));
- }
- #endif /* DAP_UART */
|