summaryrefslogtreecommitdiffhomepage
path: root/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c
diff options
context:
space:
mode:
Diffstat (limited to 'digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c')
-rw-r--r--digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c1061
1 files changed, 1061 insertions, 0 deletions
diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c
new file mode 100644
index 00000000..53a63927
--- /dev/null
+++ b/digital/zigbit/bitcloud/stack/Components/HAL/avr/common/src/usart.c
@@ -0,0 +1,1061 @@
+/**************************************************************************//**
+\file usart.c
+
+\brief USART implementation. Asynchronous mode.
+
+\author
+ Atmel Corporation: http://www.atmel.com \n
+ Support email: avr@atmel.com
+
+ Copyright (c) 2008-2011, Atmel Corporation. All rights reserved.
+ Licensed under Atmel's Limited License Agreement (BitCloudTM).
+
+\internal
+ History:
+ 29/05/07 E. Ivanov - Created
+ 18/02/09 A. Luzhetsky - Corretced.
+*******************************************************************************/
+/******************************************************************************
+ * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. *
+ * EXPERT USERS SHOULD PROCEED WITH CAUTION. *
+ ******************************************************************************/
+/******************************************************************************
+ Includes section
+******************************************************************************/
+#include <halDbg.h>
+#include <usart.h>
+#include <appTimer.h>
+#include <halDiagnostic.h>
+
+/******************************************************************************
+ Define(s) section
+******************************************************************************/
+#define HANDLERS_GET(A, I) memcpy_P(A, &halUsartHandlers[I], sizeof(HalUsartTask_t))
+/** \brief Amount of reserved bytes in received buffer. Some clients (PC Windows for example)
+ send few more bytes after CTS setting, so we need to reserve some space for them.
+ Reserved space = Buffer Size / 2^BUFFER_RESERV. */
+#define BUFFER_RESERV 1
+#define USART_HW_CONTROLLER_TIMER_PERIOD 10
+#if defined(_USE_USART_ERROR_EVENT_)
+ #define HAL_BM_FRAME_ERROR (1 << 4)
+ #define HAL_BM_DATA_OVERRUN (1 << 3)
+ #define HAL_BM_PARITY_ERROR (1 << 2)
+#endif
+#if NUM_USART_CHANNELS == 0
+ #error 'USART channels is not alowed.'
+#endif
+
+/******************************************************************************
+ Types definition section
+******************************************************************************/
+/**************************************************************************//**
+ \brief HAL USART tasks bit mask.
+******************************************************************************/
+typedef volatile uint8_t HalUsartTaskBitMask_t;
+
+/**************************************************************************//**
+ \brief HAL USART task type declaration.
+******************************************************************************/
+typedef void (* HalUsartTask_t)(void);
+
+/******************************************************************************
+ Global functions prototypes section
+******************************************************************************/
+void halSigUsartHandler(void);
+void halSetUsartConfig(HAL_UsartDescriptor_t *usartmode);
+void halPostUsartTask(HalUsartTaskId_t taskId);
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ void hwControlPinsPollCallback(void);
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+/******************************************************************************
+ Static function prototypes section
+******************************************************************************/
+#if defined(HAL_USE_USART_CHANNEL_0)
+ static void halUsartTaskUsart0Dre(void);
+ static void halUsartTaskUsart0Txc(void);
+ static void halUsartTaskUsart0Rxc(void);
+ #if defined(_USE_USART_ERROR_EVENT_)
+ static void halUsartTaskUsart0Err(void);
+ #endif
+#endif
+
+#if defined(HAL_USE_USART_CHANNEL_1)
+ static void halUsartTaskUsart1Dre(void);
+ static void halUsartTaskUsart1Txc(void);
+ static void halUsartTaskUsart1Rxc(void);
+ #if defined(_USE_USART_ERROR_EVENT_)
+ static void halUsartTaskUsart1Err(void);
+ #endif
+#endif
+
+static void halUsartHwController(UsartChannel_t tty);
+static void halSigUsartReceptionComplete(UsartChannel_t tty);
+static void halSetUsartClockPinDirection(HAL_UsartDescriptor_t *descriptor);
+
+/******************************************************************************
+ Static variables section
+******************************************************************************/
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ static HAL_AppTimer_t halUsartAppTimer;
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+HAL_UsartDescriptor_t *halPointDescrip[NUM_USART_CHANNELS] =
+{
+ #if defined(HAL_USE_USART_CHANNEL_0)
+ NULL,
+ #endif
+ #if defined(HAL_USE_USART_CHANNEL_1)
+ NULL
+ #endif
+};
+static volatile HalUsartTaskBitMask_t halUsartTaskBitMask = 0; // HAL USART tasks' bit mask.
+static const HalUsartTask_t PROGMEM_DECLARE(halUsartHandlers[HAL_USART_TASKS_NUMBER]) =
+{
+ #if defined(HAL_USE_USART_CHANNEL_0)
+ halUsartTaskUsart0Dre,
+ halUsartTaskUsart0Txc,
+ halUsartTaskUsart0Rxc,
+ #if defined(_USE_USART_ERROR_EVENT_)
+ halUsartTaskUsart0Err,
+ #endif
+ #endif
+
+ #if defined(HAL_USE_USART_CHANNEL_1)
+ halUsartTaskUsart1Dre,
+ halUsartTaskUsart1Txc,
+ halUsartTaskUsart1Rxc,
+ #if defined(_USE_USART_ERROR_EVENT_)
+ halUsartTaskUsart1Err,
+ #endif
+ #endif
+}; // List Of possible HAL USART tasks.
+
+/******************************************************************************
+ DTR service
+******************************************************************************/
+volatile bool halEnableDtrWakeUp = false;
+void (* dtrWakeUpCallback)(void) = NULL;
+
+/******************************************************************************
+ Implementations section
+******************************************************************************/
+/**************************************************************************//**
+\brief HAL USART task. Exact action depends on USART internal task.
+******************************************************************************/
+void halSigUsartHandler(void)
+{
+ HalUsartTask_t handler;
+ HalUsartTaskBitMask_t mask = 1;
+ HalUsartTaskId_t index = 0;
+
+ for ( ; index < HAL_USART_TASKS_NUMBER; index++, mask <<= 1)
+ {
+ if (halUsartTaskBitMask & mask)
+ {
+ ATOMIC_SECTION_ENTER
+ halUsartTaskBitMask ^= mask;
+ ATOMIC_SECTION_LEAVE
+ HANDLERS_GET(&handler, index);
+ handler();
+ }
+ }
+}
+
+/**************************************************************************//**
+\brief Posts specific USART task.
+
+\param[in]
+ taskId - unique identifier of the task to be posted.
+******************************************************************************/
+void halPostUsartTask(HalUsartTaskId_t taskId)
+{
+ halUsartTaskBitMask |= (HalUsartTaskBitMask_t)1 << taskId;
+ halPostTask2(HAL_TASK_USART);
+}
+
+/**************************************************************************//**
+\brief Puts the byte received to the cyclic buffer.
+
+\param[in]
+ tty - channel number.
+\param[in]
+ data - data to put.
+******************************************************************************/
+void halUsartRxBufferFiller(UsartChannel_t tty, uint8_t data)
+{
+ uint16_t old;
+ uint8_t i;
+ HalUsartService_t *halUsartControl;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(tty);
+ if (NULL == halPointDescrip[i])
+ {// abnormal
+ halDisableUsartRxcInterrupt(tty); // disable usart
+ return;
+ }
+
+ if (halPointDescrip[i]->flowControl & USART_SPI_WRITE_MODE)
+ return;
+
+ if (halPointDescrip[i]->flowControl & USART_SPI_READ_MODE)
+ { // For spi mode.
+ *(uint8_t*)(halPointDescrip[i]->rxBuffer) = data;
+ halPointDescrip[i]->rxBuffer++;
+ return;
+ } // For spi mode.
+
+ halUsartControl = &halPointDescrip[i]->service;
+ if (NULL != halPointDescrip[i]->rxBuffer)
+ {
+ old = halUsartControl->rxPointOfWrite;
+
+ if (++halUsartControl->rxPointOfWrite == halPointDescrip[i]->rxBufferLength)
+ halUsartControl->rxPointOfWrite = 0;
+
+ if (halUsartControl->rxPointOfWrite == halUsartControl->rxPointOfRead)
+ { // Buffer full.
+ halUsartControl->rxPointOfWrite = old;
+ return;
+ } // Buffer full.
+
+ halPointDescrip[i]->rxBuffer[old] = data;
+ halUsartControl->rxBytesInBuffer++;
+
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ if ((halPointDescrip[i]->flowControl & USART_FLOW_CONTROL_HARDWARE) && (HW_CONTROL_PINS_PORT_ASSIGNMENT == halPointDescrip[i]->tty))
+ {
+ if (halUsartControl->rxBytesInBuffer > (halPointDescrip[i]->rxBufferLength >> BUFFER_RESERV))
+ GPIO_USART_CTS_set();// CTS_ON
+ }
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+ }
+}
+
+#if defined(_USE_USART_ERROR_EVENT_)
+/**************************************************************************//**
+\brief Save status register for analyzing of the error reason.
+
+\param[in]
+ tty - channel number.
+\param[in]
+ status - usart status register.
+******************************************************************************/
+void halUsartSaveErrorReason(UsartChannel_t tty, uint8_t status)
+{
+ HalUsartService_t *halUsartControl;
+ uint8_t i;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(tty);
+ if (NULL == halPointDescrip[i])
+ {// abnormal
+ halDisableUsartRxcInterrupt(tty); // disable usart
+ return;
+ }
+
+ halUsartControl = &halPointDescrip[i]->service;
+ halUsartControl->errorReason = status;
+}
+#endif
+
+/**************************************************************************//**
+\brief Registers uasrt's event handlers. Performs configuration
+of usart registers. Performs configuration of RTS, CTS and DTR pins.
+
+\param[in]
+ descriptor - pointer to HAL_UsartDescriptor_t structure
+
+\return
+ Returns positive usart descriptor on success or -1 in cases: \n
+ - bad usart channel. \n
+ - unsupported parameters. \n
+ - the channel was already opened. \n
+ - there are not enough resources. \n
+******************************************************************************/
+int HAL_OpenUsart(HAL_UsartDescriptor_t *descriptor)
+{
+ uint8_t i; // Descriptor index
+
+ if (NULL == descriptor)
+ return -1;
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ if ((descriptor->flowControl & USART_FLOW_CONTROL_HARDWARE) &&
+ (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty))
+ return -1; // Hardware control cannot be used for this channel.
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (NULL != halPointDescrip[i])
+ return -1; // Channel is already opened.
+
+ halPointDescrip[i] = descriptor;
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ if (HW_CONTROL_PINS_PORT_ASSIGNMENT == descriptor->tty)
+ {
+ if (descriptor->flowControl & USART_DTR_CONTROL)
+ GPIO_USART_DTR_make_in();
+ if (descriptor->flowControl & USART_FLOW_CONTROL_HARDWARE)
+ {
+ GPIO_USART_CTS_make_out();
+ GPIO_USART_RTS_make_in();
+ if (NULL == descriptor->rxBuffer)
+ GPIO_USART_CTS_set(); // CTS_ON
+ else
+ GPIO_USART_CTS_clr(); // CTS_OFF
+ }
+ }
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+ if (USART_MODE_SYNC == descriptor->mode)
+ halSetUsartClockPinDirection(descriptor);
+
+ descriptor->service.txPointOfRead = 0;
+ descriptor->service.txPointOfWrite = 0;
+ if (NULL == descriptor->rxBuffer)
+ descriptor->rxBufferLength = 0;
+ if (NULL == descriptor->txBuffer)
+ descriptor->txBufferLength = 0;
+ descriptor->service.rxPointOfRead = 0;
+ descriptor->service.rxPointOfWrite = 0;
+ descriptor->service.usartShiftRegisterEmpty = 1;
+
+ halSetUsartConfig(descriptor);
+
+ return descriptor->tty;
+}
+
+/**************************************************************************//**
+\brief Frees the usart channel and pins, if hardware flow control was used.
+
+\param[in]
+ descriptor - the usart descriptor.
+\return
+ 0 on success, \n
+ -1 if bad descriptor or channel is already closed.
+******************************************************************************/
+int HAL_CloseUsart(HAL_UsartDescriptor_t *descriptor)
+{
+ uint8_t i;
+
+ if (NULL == descriptor)
+ return -1;
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (NULL == halPointDescrip[i])
+ return -1; // Channel is already closed.
+
+ halCloseUsart(halPointDescrip[i]->tty);
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ if (halPointDescrip[i]->flowControl & USART_FLOW_CONTROL_HARDWARE)
+ GPIO_USART_CTS_make_in();
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+ if (USART_MODE_SYNC == halPointDescrip[i]->mode)
+ {
+ halPointDescrip[i]->syncMode = USART_CLK_MODE_SLAVE;
+ halSetUsartClockPinDirection(halPointDescrip[i]);
+ }
+ halPointDescrip[i] = NULL;
+
+ return 0;
+}
+
+/**************************************************************************//**
+\brief Controls RTS and DTR the pins and makes decision if the usart can transmit
+ byte.
+
+\param[in]
+ tty - channel number.
+******************************************************************************/
+static void halUsartHwController(UsartChannel_t tty)
+{
+ uint8_t i;
+ HalUsartService_t *halUsartControl;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(tty);
+ if (NULL == halPointDescrip[i])
+ return; // Port closed.
+
+ halUsartControl = &halPointDescrip[i]->service;
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ if (HW_CONTROL_PINS_PORT_ASSIGNMENT == tty)
+ {
+ uint8_t hw1 = 0;
+ uint8_t hw2 = 0;
+
+ if (halPointDescrip[i]->flowControl & USART_DTR_CONTROL)
+ hw1 = GPIO_USART_DTR_read();
+
+ if (halPointDescrip[i]->flowControl & USART_FLOW_CONTROL_HARDWARE)
+ hw2 = GPIO_USART_RTS_read();
+
+ if (hw1 || hw2)
+ {
+ halUsartAppTimer.interval = USART_HW_CONTROLLER_TIMER_PERIOD;
+ halUsartAppTimer.mode = TIMER_ONE_SHOT_MODE;
+ halUsartAppTimer.callback = hwControlPinsPollCallback;
+ HAL_StartAppTimer(&halUsartAppTimer);
+ return;
+ }
+ }
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+ uint16_t poW;
+ uint16_t poR;
+
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ poW = halUsartControl->txPointOfWrite;
+ poR = halUsartControl->txPointOfRead;
+ END_MEASURE(HAL_USART_HW_CONTROLLER_LIMIT)
+ ATOMIC_SECTION_LEAVE
+
+ if (poW != poR)
+ {
+ halSendUsartByte(tty, halPointDescrip[i]->txBuffer[poR++]);
+ if (poR == halPointDescrip[i]->txBufferLength)
+ poR = 0;
+ halEnableUsartDremInterrupt(tty);
+
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ halUsartControl->txPointOfRead = poR;
+ END_MEASURE(HAL_USART_HW_CONTROLLER_LIMIT)
+ ATOMIC_SECTION_LEAVE
+
+ }
+ else
+ {
+ // data register empty interrupt was disabled
+ halEnableUsartTxcInterrupt(tty);// TX Complete interrupt enable
+ }
+}
+
+/**************************************************************************//**
+\brief Writes a number of bytes to a usart channel.
+txCallback function will be used to notify when the transmission is finished.
+If hardware flow control is used for transmitting then RTS and DTR pins will
+be tested during transmission.
+
+\param[in]
+ descriptor - pointer to HAL_UsartDescriptor_t structure;
+
+\param[in]
+ buffer - pointer to the application data buffer;
+
+\param[in]
+ length - number of bytes to transfer;
+
+\return
+ -1 - bad descriptor; \n
+ Number of bytes placed to the buffer - success.
+******************************************************************************/
+int HAL_WriteUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length)
+{
+ uint8_t i;
+ uint16_t poW;
+ uint16_t poR;
+ uint16_t old;
+ uint16_t wasWrote = 0;
+ bool needStartTrmt = false;
+ HalUsartService_t *halUsartControl;
+
+ if (NULL == descriptor)
+ return -1;
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+ if (!buffer || !length)
+ return -1;
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (descriptor != halPointDescrip[i])
+ return -1; // Channel is not opened.
+
+ halUsartControl = &descriptor->service;
+ if (0 == descriptor->txBufferLength)
+ { // Callback mode
+ if (halUsartControl->txPointOfWrite != halUsartControl->txPointOfRead)
+ return -1; // there is unsent data
+ descriptor->txBuffer = buffer;
+ halUsartControl->txPointOfWrite = length;
+ halUsartControl->txPointOfRead = 0;
+ needStartTrmt = true;
+ wasWrote = length;
+ } // Callback mode.
+ else
+ { // Polling mode.
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ poW = halUsartControl->txPointOfWrite;
+ poR = halUsartControl->txPointOfRead;
+ END_MEASURE(HALATOM_WRITE_USART_TIME_LIMIT)
+ ATOMIC_SECTION_LEAVE
+
+ if (poW == poR)
+ needStartTrmt = true; // Buffer empty.
+
+ while (wasWrote < length)
+ {
+ old = poW;
+
+ if (++poW == descriptor->txBufferLength)
+ poW = 0;
+
+ if (poW == poR)
+ { // Buffer full.
+ poW = old;
+ break;
+ } // Buffer full.
+
+ descriptor->txBuffer[old] = buffer[wasWrote++];
+ }
+
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ halUsartControl->txPointOfWrite = poW;
+ END_MEASURE(HALATOM_WRITE_USART_TIME_LIMIT)
+ ATOMIC_SECTION_LEAVE
+ } // Polling mode
+
+ if (needStartTrmt)
+ {
+ halUsartControl->usartShiftRegisterEmpty = 0; // Buffer and shift register is full
+ // Enable interrupt. Transaction will be launched in the callback.
+ halEnableUsartDremInterrupt(descriptor->tty);
+ }
+
+ return wasWrote;
+}
+
+/*************************************************************************//**
+\brief Reads length bytes from usart and places ones to buffer.
+
+\param[in]
+ descriptor - usart descriptor;
+\param[out]
+ buffer - pointer to a application buffer;
+\param[in]
+ length - the number of bytes which should be placed to buffer
+
+\return
+ -1 - bad descriptor, bad number to read or number of bytes that \n
+ were placed to buffer.
+*****************************************************************************/
+int HAL_ReadUsart(HAL_UsartDescriptor_t *descriptor, uint8_t *buffer, uint16_t length)
+{
+ uint8_t i = 0;
+ uint16_t wasRead = 0;
+ uint16_t poW;
+ uint16_t poR;
+ HalUsartService_t *halUsartControl;
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ uint16_t number;
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+ if (NULL == descriptor)
+ return -1;
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+ if (!buffer || !length)
+ return -1;
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (descriptor != halPointDescrip[i])
+ return -1; // Channel is not opened.
+
+ halUsartControl = &halPointDescrip[i]->service;
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ poW = halUsartControl->rxPointOfWrite;
+ poR = halUsartControl->rxPointOfRead;
+ END_MEASURE(HALATOM_READ_USART_TIME_LIMIT)
+ ATOMIC_SECTION_LEAVE
+
+ while ((poR != poW) && (wasRead < length))
+ {
+ buffer[wasRead] = descriptor->rxBuffer[poR];
+ if (++poR == descriptor->rxBufferLength)
+ poR = 0;
+ wasRead++;
+ }
+
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ halUsartControl->rxPointOfRead = poR;
+ halUsartControl->rxBytesInBuffer -= wasRead;
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ number = halUsartControl->rxBytesInBuffer;
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+ END_MEASURE(HALATOM_READ_USART_TIME_LIMIT)
+ ATOMIC_SECTION_LEAVE
+
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+ if ((HW_CONTROL_PINS_PORT_ASSIGNMENT == descriptor->tty) && (descriptor->flowControl & USART_FLOW_CONTROL_HARDWARE))
+ if (number <= (descriptor->rxBufferLength >> BUFFER_RESERV))
+ GPIO_USART_CTS_clr();
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+ return wasRead;
+}
+
+/**************************************************************************//**
+\brief Forbids to the host data transmiting. Only HW_CONTROL_PINS_PORT_ASSIGNMENT
+ port can be used for hardware flow control.
+
+\param[in]
+ descriptor - usart descriptor.
+
+\return
+ -1 - bad descriptor, bad usart, unsupported mode;
+ 0 - on success.
+******************************************************************************/
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+int HAL_OnUsartCts(HAL_UsartDescriptor_t *descriptor)
+{
+ uint8_t i;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (descriptor != halPointDescrip[i])
+ return -1; // Channel is not opened.
+
+ if (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty)
+ return -1;
+
+ GPIO_USART_CTS_set();// CTS_ON
+
+ return 0;
+}
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+/**************************************************************************//**
+\brief Allows to transfer a host data. Only HW_CONTROL_PINS_PORT_ASSIGNMENT
+can be used for hardware flow control.
+
+\param[in]
+ descriptor - usart descriptor.
+
+\return
+ -1 - bad descriptor, bad usart, unsupported mode;
+ 0 - on success.
+******************************************************************************/
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+int HAL_OffUsartCts(HAL_UsartDescriptor_t *descriptor)
+{
+ uint8_t i;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (descriptor != halPointDescrip[i])
+ return -1; // Channel is not opened.
+
+ if (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty)
+ return -1;
+
+ GPIO_USART_CTS_clr(); // CTS_OFF
+
+ return 0;
+}
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+/**************************************************************************//**
+\brief Fills UsartHardwareControl_t variable by potential of RTS pin. Only
+ HW_CONTROL_PINS_PORT_ASSIGNMENT can be used for hardware flow control.
+
+\param[in]
+ descriptor - usart descriptor.
+\return
+ -1 - bad descriptor, bad usart, unsupported mode;
+ 0 - on success.
+******************************************************************************/
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+int HAL_ReadUsartRts(HAL_UsartDescriptor_t *descriptor)
+{
+ uint8_t i;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (descriptor != halPointDescrip[i])
+ return -1; // Channel is not opened.
+
+ if (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty)
+ return -1;
+
+ return GPIO_USART_RTS_read();
+}
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+/**************************************************************************//**
+\brief Fills UsartHardwareControl_t variable by potential of DTR pin. Only
+ HW_CONTROL_PINS_PORT_ASSIGNMENT can be used for hardware flow control.
+
+\param[in]
+ descriptor - usart descriptor.
+\return
+ -1 - bad descriptor, bad usart, unsupported mode;
+ 0 - on success.
+******************************************************************************/
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+int HAL_ReadUsartDtr(HAL_UsartDescriptor_t *descriptor)
+{
+ uint8_t i;
+
+ if (NULL == descriptor)
+ return -1;
+
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (descriptor != halPointDescrip[i])
+ return -1; // Channel is not opened.
+
+ if (HW_CONTROL_PINS_PORT_ASSIGNMENT != descriptor->tty)
+ return -1;
+
+ return GPIO_USART_DTR_read();
+}
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+// Interrupt handlers
+/**************************************************************************//**
+\brief Hardware Control pins polling timer callback.
+******************************************************************************/
+#ifdef HW_CONTROL_PINS_PORT_ASSIGNMENT
+void hwControlPinsPollCallback(void)
+{
+ halUsartHwController(HW_CONTROL_PINS_PORT_ASSIGNMENT);
+}
+#endif // HW_CONTROL_PINS_PORT_ASSIGNMENT
+
+/**************************************************************************//**
+\brief Transmission complete interrupt handler.
+
+\param[in]
+ tty - USART channel identifier.
+******************************************************************************/
+void halSigUsartTransmissionComplete(UsartChannel_t tty)
+{
+ uint8_t i;
+ HalUsartService_t *halUsartControl;
+ uint16_t poW;
+ uint16_t poR;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(tty);
+ if (NULL == halPointDescrip[i])
+ {
+ assert(false, USARTC_HALSIGUSARTTRANSMISSIONCOMPLETE_0);
+ return; // Descriptor with "tty" channel is not found.
+ }
+
+ halUsartControl = &halPointDescrip[i]->service;
+
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ poW = halUsartControl->txPointOfWrite;
+ poR = halUsartControl->txPointOfRead;
+ END_MEASURE(HAL_USART_TRANS_COMPLETE_LIMIT)
+ ATOMIC_SECTION_LEAVE
+
+ if (poW == poR)
+ halUsartControl->usartShiftRegisterEmpty = 1; // Buffer is empty, shift register is empty too.
+
+ if (0 == halPointDescrip[i]->txBufferLength)
+ halPointDescrip[i]->txBuffer = NULL; // nulling pointer for callback mode
+
+ if (NULL != halPointDescrip[i]->txCallback)
+ halPointDescrip[i]->txCallback();
+}
+
+/**************************************************************************//**
+\brief Reception complete interrupt handler.
+
+\param[in]
+ tty - USART channel identifier.
+******************************************************************************/
+static void halSigUsartReceptionComplete(UsartChannel_t tty)
+{
+ uint8_t i;
+ HalUsartService_t *halUsartControl;
+ uint16_t number;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(tty);
+ if (NULL == halPointDescrip[i])
+ {
+ assert(false, USARTC_HALSIGUSARTRECEPTIONCOMPLETE_0);
+ return; // Descriptor with "tty" channel is not found.
+ }
+
+ if (halPointDescrip[i]->flowControl & (USART_SPI_READ_MODE | USART_SPI_WRITE_MODE))
+ return; // for spi mode
+
+ halUsartControl = &halPointDescrip[i]->service;
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ number = halUsartControl->rxBytesInBuffer;
+ END_MEASURE(HALATOM_USART_RX_COMPLETE_TIME_LIMIT)
+ ATOMIC_SECTION_LEAVE
+
+ if (number)
+ if (NULL != halPointDescrip[i]->rxCallback)
+ halPointDescrip[i]->rxCallback(number);
+}
+
+#if defined(_USE_USART_ERROR_EVENT_)
+/**************************************************************************//**
+\brief Error occurred action handler.
+
+\param[in]
+ tty - USART channel identifier.
+******************************************************************************/
+static void halSigUsartErrorOccurred(UsartChannel_t tty)
+{
+ uint8_t i;
+ HalUsartService_t *halUsartControl;
+ UsartErrorReason_t errReason = FRAME_ERROR;
+
+ i = HAL_GET_INDEX_BY_CHANNEL(tty);
+ if (NULL == halPointDescrip[i])
+ {
+ assert(false, USARTC_HALSIGUSARTERROROCCURED_0);
+ return; // Descriptor with "tty" channel is not found.
+ }
+
+ halUsartControl = &halPointDescrip[i]->service;
+ if (halUsartControl->errorReason & HAL_BM_FRAME_ERROR)
+ errReason = FRAME_ERROR;
+ else if (halUsartControl->errorReason & HAL_BM_DATA_OVERRUN)
+ errReason = DATA_OVERRUN;
+ else if (halUsartControl->errorReason & HAL_BM_PARITY_ERROR)
+ errReason = PARITY_ERROR;
+ else
+ {
+ assert(false, USARTC_HALUNKNOWNERRORREASON_0);
+ }
+
+ if (NULL != halPointDescrip[i]->errCallback)
+ halPointDescrip[i]->errCallback(errReason);
+}
+#endif
+
+/**************************************************************************//**
+\brief Enables DTR wake up.
+
+\param[in] callback - callback method pointer.
+******************************************************************************/
+void HAL_EnableDtrWakeUp(void (* callback)(void))
+{
+ dtrWakeUpCallback = callback;
+ halEnableDtrWakeUp = true;
+}
+
+/**************************************************************************//**
+\brief Disables DTR wake up.
+******************************************************************************/
+void HAL_DisableDtrWakeUp(void)
+{
+ halEnableDtrWakeUp = false;
+}
+
+/**************************************************************************//**
+\brief Checks the status of tx buffer.
+
+\param[in]
+ descriptor - pointer to HAL_UsartDescriptor_t structure;
+
+\return
+ -1 - bad descriptor, no tx buffer; \n
+ 1 - tx buffer is empty; \n
+ 0 - tx buffer is not empty;
+******************************************************************************/
+int HAL_IsTxEmpty(HAL_UsartDescriptor_t *descriptor)
+{
+ uint8_t i;
+ HalUsartService_t *halUsartControl;
+ uint16_t poW;
+ uint16_t poR;
+
+ if (NULL == descriptor)
+ return -1;
+ if (false == halIsUsartChannelCorrect(descriptor->tty))
+ return -1;
+ i = HAL_GET_INDEX_BY_CHANNEL(descriptor->tty);
+ if (descriptor != halPointDescrip[i])
+ return -1; // Channel is not opened.
+
+ halUsartControl = &halPointDescrip[i]->service;
+ ATOMIC_SECTION_ENTER
+ BEGIN_MEASURE
+ poW = halUsartControl->txPointOfWrite;
+ poR = halUsartControl->txPointOfRead;
+ END_MEASURE(HAL_USART_TX_EMPTY_LIMIT)
+ ATOMIC_SECTION_LEAVE
+ if (poW == poR)
+ return halUsartControl->usartShiftRegisterEmpty;
+ return 0;
+}
+
+/**************************************************************************//**
+\brief Checks the channel number.
+
+\param[in]
+ channel - channel to be verified.
+
+\return
+ true if channel is possible, \n
+ false otherwise.
+******************************************************************************/
+bool halIsUsartChannelCorrect(UsartChannel_t channel)
+{
+ switch (channel)
+ {
+#ifdef USART_CHANNEL_0
+ case USART_CHANNEL_0:
+#endif // USART_CHANNEL_0
+#ifdef USART_CHANNEL_1
+ case USART_CHANNEL_1:
+#endif // USART_CHANNEL_0
+#if defined(USART_CHANNEL_0) || defined(USART_CHANNEL_1)
+ return true;
+#endif
+ default:
+ return false;
+ }
+}
+
+/**************************************************************************//**
+\brief Set clock pin direction for synchronous mode.
+
+\param[in]
+ descriptor - pointer to usart channel descriptor.
+******************************************************************************/
+static void halSetUsartClockPinDirection(HAL_UsartDescriptor_t *descriptor)
+{
+ if (USART_CLK_MODE_MASTER == descriptor->syncMode)
+ {
+ switch (descriptor->tty)
+ {
+#ifdef USART_CHANNEL_0
+ case USART_CHANNEL_0:
+ GPIO_USART0_EXTCLK_make_out();
+ break;
+#endif // USART_CHANNEL_0
+#ifdef USART_CHANNEL_1
+ case USART_CHANNEL_1:
+ GPIO_USART1_EXTCLK_make_out();
+ break;
+#endif // USART_CHANNEL_1
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (descriptor->tty)
+ {
+#ifdef USART_CHANNEL_0
+ case USART_CHANNEL_0:
+ GPIO_USART0_EXTCLK_make_in();
+ GPIO_USART0_EXTCLK_make_pullup();
+ break;
+#endif // USART_CHANNEL_0
+#ifdef USART_CHANNEL_1
+ case USART_CHANNEL_1:
+ GPIO_USART1_EXTCLK_make_in();
+ GPIO_USART1_EXTCLK_make_pullup();
+ break;
+#endif // USART_CHANNEL_1
+ default:
+ break;
+ }
+ }
+}
+
+#if defined(HAL_USE_USART_CHANNEL_0)
+/**************************************************************************//**
+\brief Wrapper for data empty handler for usart channel 0
+******************************************************************************/
+static void halUsartTaskUsart0Dre(void)
+{
+ halUsartHwController(USART_CHANNEL_0);
+}
+
+/**************************************************************************//**
+\brief Wrapper for transmit complete handler for usart channel 0
+******************************************************************************/
+static void halUsartTaskUsart0Txc(void)
+{
+ halSigUsartTransmissionComplete(USART_CHANNEL_0);
+}
+
+/**************************************************************************//**
+\brief Wrapper for receive complete handler for usart channel 0
+******************************************************************************/
+static void halUsartTaskUsart0Rxc(void)
+{
+ halSigUsartReceptionComplete(USART_CHANNEL_0);
+}
+
+#if defined(_USE_USART_ERROR_EVENT_)
+/**************************************************************************//**
+\brief Wrapper for error occurred handler for usart channel 0
+******************************************************************************/
+static void halUsartTaskUsart0Err(void)
+{
+ halSigUsartErrorOccurred(USART_CHANNEL_0);
+}
+#endif // defined(_USE_USART_ERROR_EVENT_)
+#endif // defined(HAL_USE_USART_CHANNEL_0)
+
+#if defined(HAL_USE_USART_CHANNEL_1)
+/**************************************************************************//**
+\brief Wrapper for data empty handler for usart channel 1
+******************************************************************************/
+static void halUsartTaskUsart1Dre(void)
+{
+ halUsartHwController(USART_CHANNEL_1);
+}
+
+/**************************************************************************//**
+\brief Wrapper for transmit complete handler for usart channel 1
+******************************************************************************/
+static void halUsartTaskUsart1Txc(void)
+{
+ halSigUsartTransmissionComplete(USART_CHANNEL_1);
+}
+
+/**************************************************************************//**
+\brief Wrapper for receive complete handler for usart channel 0
+******************************************************************************/
+static void halUsartTaskUsart1Rxc(void)
+{
+ halSigUsartReceptionComplete(USART_CHANNEL_1);
+}
+
+#if defined(_USE_USART_ERROR_EVENT_)
+/**************************************************************************//**
+\brief Wrapper for error occurred handler for usart channel 1
+******************************************************************************/
+static void halUsartTaskUsart1Err(void)
+{
+ halSigUsartErrorOccurred(USART_CHANNEL_1);
+}
+#endif // defined(_USE_USART_ERROR_EVENT_)
+#endif // defined(HAL_USE_USART_CHANNEL_1)
+//eof usart.c