633 lines
19 KiB
C
633 lines
19 KiB
C
/*!
|
|
* \file
|
|
* thermostat_shield.c
|
|
* \brief
|
|
* Nucleo thermostat shield port file. This file contain the implementation of driver
|
|
* calls for the shield.
|
|
*
|
|
* Author: Christos Choutouridis AEM: 8997
|
|
* email : <cchoutou@ece.auth.gr>
|
|
*/
|
|
#include "thermostat_shield.h"
|
|
|
|
|
|
/*
|
|
* =============== Digital I/O ===============
|
|
*/
|
|
static void SHIELD_LCD_Port_Init (void);
|
|
static void SHIELD_LED_Port_Init (void);
|
|
static void SHIELD_BRIDGE_Port_Init (void);
|
|
static void SHIELD_SR04_Port_Init (void);
|
|
|
|
/*
|
|
* =============== LCD ===============
|
|
* LCD_BD4 -- D8 -- PA9
|
|
* LCD_BD5 -- D7 -- PA8
|
|
* LCD_BD6 -- D6 -- PB10
|
|
* LCD_BD7 -- D5 -- PB4
|
|
* LCD_RS -- D15 -- PB8
|
|
* LCD_EN -- D14 -- PB9
|
|
* LCD_BL -- D2 -- PA10
|
|
*/
|
|
static void SHIELD_LCD_Port_Init (void) {
|
|
GPIO_InitTypeDef GPIO_InitType;
|
|
|
|
__HAL_RCC_GPIOA_CLK_ENABLE ();
|
|
__HAL_RCC_GPIOB_CLK_ENABLE ();
|
|
|
|
GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
|
|
GPIO_InitType.Speed = GPIO_SPEED_LOW;
|
|
GPIO_InitType.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
|
|
HAL_GPIO_Init(GPIOA, &GPIO_InitType);
|
|
|
|
GPIO_InitType.Pin = GPIO_PIN_4 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
|
|
HAL_GPIO_Init(GPIOB, &GPIO_InitType);
|
|
}
|
|
void SHIELD_LCD_DB4 (uint8_t en) { _DOUTx(GPIOA, GPIO_PIN_9, en); }
|
|
void SHIELD_LCD_DB5 (uint8_t en) { _DOUTx(GPIOA, GPIO_PIN_8, en); }
|
|
void SHIELD_LCD_DB6 (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_10, en); }
|
|
void SHIELD_LCD_DB7 (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_4, en); }
|
|
void SHIELD_LCD_RS (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_8, en); }
|
|
void SHIELD_LCD_EN (uint8_t en) { _DOUTx(GPIOB, GPIO_PIN_9, en); }
|
|
void SHIELD_LCD_BL (uint8_t en) { _DOUTx(GPIOA, GPIO_PIN_10, en); }
|
|
|
|
/*
|
|
* =============== LED ===============
|
|
* LED0 -- D4 -- PB5
|
|
* LED1 -- D3 -- PB3
|
|
*/
|
|
static void SHIELD_LED_Port_Init (void) {
|
|
GPIO_InitTypeDef GPIO_InitType;
|
|
|
|
__HAL_RCC_GPIOB_CLK_ENABLE ();
|
|
|
|
GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
|
|
GPIO_InitType.Speed = GPIO_SPEED_LOW;
|
|
GPIO_InitType.Pin = GPIO_PIN_3 | GPIO_PIN_5;
|
|
HAL_GPIO_Init(GPIOB, &GPIO_InitType);
|
|
}
|
|
void SHIELD_LED0 (uint8_t on) { _DOUTx(GPIOB, GPIO_PIN_5, on); }
|
|
void SHIELD_LED1 (uint8_t on) { _DOUTx(GPIOB, GPIO_PIN_3, on); }
|
|
|
|
/*
|
|
* =============== BRIDGE ===============
|
|
* BR1 -- D10 -- PB6
|
|
* BR2 -- D9 -- PC7
|
|
*/
|
|
static void SHIELD_BRIDGE_Port_Init (void) {
|
|
GPIO_InitTypeDef GPIO_InitType;
|
|
|
|
__HAL_RCC_GPIOB_CLK_ENABLE ();
|
|
__HAL_RCC_GPIOC_CLK_ENABLE ();
|
|
|
|
GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
|
|
GPIO_InitType.Speed = GPIO_SPEED_LOW;
|
|
GPIO_InitType.Pin = GPIO_PIN_6;
|
|
HAL_GPIO_Init(GPIOB, &GPIO_InitType);
|
|
GPIO_InitType.Pin = GPIO_PIN_7;
|
|
HAL_GPIO_Init(GPIOC, &GPIO_InitType);
|
|
}
|
|
void SHIELD_BR1 (uint8_t on) { _DOUTx(GPIOB, GPIO_PIN_6, on); }
|
|
void SHIELD_BR2 (uint8_t on) { _DOUTx(GPIOC, GPIO_PIN_7, on); }
|
|
|
|
/*
|
|
* =============== SR04 ===============
|
|
* TRIG -- D11 -- PA7
|
|
* ECHO -- D12 -- PA6
|
|
*/
|
|
static void SHIELD_SR04_Port_Init (void) {
|
|
GPIO_InitTypeDef GPIO_InitType;
|
|
|
|
__HAL_RCC_GPIOA_CLK_ENABLE ();
|
|
|
|
GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
|
|
GPIO_InitType.Speed = GPIO_SPEED_LOW;
|
|
GPIO_InitType.Pin = GPIO_PIN_7;
|
|
HAL_GPIO_Init(GPIOA, &GPIO_InitType);
|
|
|
|
GPIO_InitType.Mode = GPIO_MODE_INPUT;
|
|
GPIO_InitType.Pull = GPIO_NOPULL;
|
|
GPIO_InitType.Pin = GPIO_PIN_6;
|
|
HAL_GPIO_Init(GPIOA, &GPIO_InitType);
|
|
}
|
|
void SHIELD_TRIG (uint8_t on) { _DOUTx(GPIOA, GPIO_PIN_7, on); }
|
|
uint8_t SHIELD_ECHO (void) { return _DINx (GPIOA, GPIO_PIN_6); }
|
|
|
|
/*
|
|
* ============= 1 Wire UART6 (AF08)===============
|
|
* 1W_Tx -- PA11 (OD+PU)
|
|
* 1W_Rx -- PA12 (I)
|
|
*/
|
|
static UART_HandleTypeDef h1w_uart;
|
|
|
|
/*!
|
|
* \brief
|
|
* This function handles UART Communication Timeout.
|
|
* \param huart: Pointer to a UART_HandleTypeDef structure that contains
|
|
* the configuration information for the specified UART module.
|
|
* \param Flag: specifies the UART flag to check.
|
|
* \param Status: The new Flag status (SET or RESET).
|
|
* \param Timeout: Timeout duration
|
|
* \return HAL status
|
|
*/
|
|
static HAL_StatusTypeDef _WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) {
|
|
uint32_t tickstart = HAL_GetTick();
|
|
|
|
if (Status != RESET) Status = SET; /* Catch wrong Status */
|
|
|
|
/* Wait until flag is on FlagStatus Status */
|
|
while (__HAL_UART_GET_FLAG (huart, Flag) == Status) {
|
|
if ((Timeout == 0) || ((HAL_GetTick() - tickstart ) > Timeout)) {
|
|
/* Give up */
|
|
huart->gState= HAL_UART_STATE_READY; /* Mark Timeout as ready */
|
|
__HAL_UNLOCK (huart); /* Process Unlocked */
|
|
return HAL_TIMEOUT; /* Return the TIMEOUT */
|
|
}
|
|
}
|
|
return HAL_OK;
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Initialize 1-Wire UART to 8bits, no parity, 1 stop, so it can
|
|
* be used for 1-Wire communication
|
|
* \return The status of the operation
|
|
* \arg LLD_OK Success
|
|
* \arg LLD_ERROR The Init failed.
|
|
*/
|
|
static LLD_Status_en _1W_UART_Init (void) {
|
|
_1WIRE_UART_CLK_ENABLE (); // Enable 1-wire's USART clock
|
|
|
|
/*
|
|
* USART configured as follows:
|
|
* - Word Length = 8 Bits
|
|
* - Stop Bit = One Stop bit
|
|
* - Parity = No parity
|
|
* - BaudRate = _1WIRE_UART_INIT_BR baud
|
|
* - Hardware flow control disabled (RTS and CTS signals)
|
|
*/
|
|
h1w_uart.Instance = _1WIRE_UART_INSTANCE;
|
|
h1w_uart.Init.BaudRate = _1WIRE_UART_INIT_BR;
|
|
h1w_uart.Init.WordLength = UART_WORDLENGTH_8B;
|
|
h1w_uart.Init.StopBits = UART_STOPBITS_1;
|
|
h1w_uart.Init.Parity = UART_PARITY_NONE;
|
|
h1w_uart.Init.Mode = UART_MODE_TX_RX;
|
|
|
|
if (HAL_UART_Init(&h1w_uart) != HAL_OK)
|
|
return LLD_ERROR;
|
|
return LLD_OK;
|
|
}
|
|
|
|
|
|
/*!
|
|
* Init the KEY 1wire interface and allocate all resources for it
|
|
* \return The status of the operation
|
|
* \arg LLD_OK Success
|
|
* \arg LLD_ERROR The Init failed.
|
|
*/
|
|
LLD_Status_en SHIELD_1W_Init (void) {
|
|
GPIO_InitTypeDef GPIO_InitStruct;
|
|
|
|
__HAL_RCC_GPIOA_CLK_ENABLE ();
|
|
|
|
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
|
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
|
|
HAL_GPIO_WritePin (GPIOA, GPIO_InitStruct.Pin, GPIO_PIN_SET);
|
|
HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);
|
|
|
|
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
|
//GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
|
/*^
|
|
* Mark as alternate because HAL_GPIO_Init ()
|
|
* can not configure Input + alternate
|
|
*/
|
|
HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);
|
|
|
|
return _1W_UART_Init ();
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Set a Baudrate to the UART, to use for 1-Wire communication
|
|
* \param br The desired baudrate
|
|
* \return The status of the operation (part of toolbox)
|
|
* \arg DRV_ERROR Fail
|
|
* \arg DRV_READY Success
|
|
*/
|
|
drv_status_en SHIELD_1W_UART_BR (uint32_t br) {
|
|
/*
|
|
* Keep USART configured as already set by Init:
|
|
* - Word Length = 8 Bits
|
|
* - Stop Bit = One Stop bit
|
|
* - Parity = No parity
|
|
* - Hardware flow control disabled (RTS and CTS signals)
|
|
*/
|
|
if (! IS_UART_BAUDRATE (br) )
|
|
return DRV_ERROR;
|
|
h1w_uart.Init.BaudRate = br;
|
|
|
|
/* Check the Over Sampling */
|
|
if(h1w_uart.Init.OverSampling == UART_OVERSAMPLING_8) {
|
|
/*------- UART-associated USART registers setting : BRR Configuration ------*/
|
|
if((h1w_uart.Instance == USART1)){
|
|
h1w_uart.Instance->BRR = UART_BRR_SAMPLING8 (HAL_RCC_GetPCLK2Freq(), h1w_uart.Init.BaudRate);
|
|
}
|
|
else {
|
|
h1w_uart.Instance->BRR = UART_BRR_SAMPLING8 (HAL_RCC_GetPCLK1Freq(), h1w_uart.Init.BaudRate);
|
|
}
|
|
}
|
|
else {
|
|
/*------- UART-associated USART registers setting : BRR Configuration ------*/
|
|
if((h1w_uart.Instance == USART1)) {
|
|
h1w_uart.Instance->BRR = UART_BRR_SAMPLING16 (HAL_RCC_GetPCLK2Freq(), h1w_uart.Init.BaudRate);
|
|
}
|
|
else {
|
|
h1w_uart.Instance->BRR = UART_BRR_SAMPLING16 (HAL_RCC_GetPCLK1Freq(), h1w_uart.Init.BaudRate);
|
|
}
|
|
}
|
|
return DRV_READY;
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Read-Write functionality. We use the following USART configuration.
|
|
* - Word Length = 8 Bits
|
|
* - Stop Bit = One Stop bit
|
|
* - Parity = No parity
|
|
* \return The byte received. On failure return 0xFFFF (bus released state)
|
|
* \note
|
|
* Due to the nature of the PCB, the received byte is the actual bus
|
|
* condition during the communication frame (time slot)
|
|
*/
|
|
uint16_t SHIELD_1W_RW (uint8_t byte)
|
|
{
|
|
if (h1w_uart.Init.WordLength != UART_WORDLENGTH_8B) return (uint8_t)0xFFFF;
|
|
if (h1w_uart.Init.Parity != UART_PARITY_NONE) return (uint8_t)0xFFFF;
|
|
|
|
if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_TXE, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK)
|
|
return 0x1FF;
|
|
WRITE_REG (h1w_uart.Instance->DR, (byte & (uint8_t)0xFF));
|
|
if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_TC, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK)
|
|
return 0x2FF;
|
|
//if (_WaitOnFlagUntilTimeout (&h1w_uart, UART_FLAG_RXNE, RESET, _1WIRE_UART_TIMEOUT) != HAL_OK)
|
|
// return 0xFFFF;
|
|
return (uint8_t)(h1w_uart.Instance->DR & (uint8_t)0x00FF);
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Receive functionality. We use USART blocking mode.
|
|
* \return The byte received. On failure return 0xFF (bus released state)
|
|
* \note
|
|
* Due to the nature of the PCB, the received byte is the actual bus
|
|
* condition during the communication frame (time slot)
|
|
*/
|
|
uint8_t SHIELD_1W_Rx (void) {
|
|
uint8_t rx;
|
|
if (HAL_UART_Receive (&h1w_uart, &rx, sizeof (uint8_t), _1WIRE_UART_TIMEOUT) != HAL_OK)
|
|
rx = 0xFF;
|
|
return rx;
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Transmit functionality. We use USART blocking mode.
|
|
* \return The status of transition
|
|
* \arg 0 Success
|
|
* \arg 1 Fail
|
|
*/
|
|
uint8_t SHIELD_1W_Tx (uint8_t byte) {
|
|
if (HAL_UART_Transmit (&h1w_uart, &byte, sizeof (uint8_t), _1WIRE_UART_TIMEOUT) != HAL_OK)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
LLD_Status_en SHIELD_Init (void) {
|
|
SHIELD_LCD_Port_Init ();
|
|
SHIELD_LED_Port_Init ();
|
|
SHIELD_BRIDGE_Port_Init ();
|
|
SHIELD_SR04_Port_Init ();
|
|
|
|
SHIELD_1W_Init ();
|
|
COM_Init ();
|
|
return LLD_OK;
|
|
}
|
|
|
|
/*
|
|
* ============= Serial console UART2 (AF07)===============
|
|
* COM_Tx -- PA2 (PP)
|
|
* COM_Rx -- PA3 (I)
|
|
*/
|
|
static UART_HandleTypeDef com_huart;
|
|
static deque08_t _com_rxq;
|
|
static byte_t _com_rxbuffer[COM_BUFFER_SIZE];
|
|
|
|
/*!
|
|
* \brief
|
|
* Called from USART IRQ to put the read character to queue
|
|
* \param Pointer to a UART_HandleTypeDef structure that contains
|
|
* the configuration information for the specified UART module.
|
|
*
|
|
* \return The status of the operation
|
|
* \arg HAL_ERROR Fail
|
|
* \arg HAL_OK Success
|
|
*/
|
|
static HAL_StatusTypeDef _UART_read_data (UART_HandleTypeDef *huart, deque08_t *q) {
|
|
uint8_t r;
|
|
|
|
__HAL_LOCK(huart); /*
|
|
* We don't try to receive valid data while the USART is
|
|
* locked from transmitter. It's OK ;)
|
|
*/
|
|
|
|
/* Receive data based on Word length and parity */
|
|
switch (huart->Init.WordLength) {
|
|
default:
|
|
case UART_WORDLENGTH_8B:
|
|
if(huart->Init.Parity == UART_PARITY_NONE)
|
|
r = (uint8_t)(huart->Instance->DR & (uint16_t)0x00FF);
|
|
else
|
|
r = (uint8_t)(huart->Instance->DR & (uint16_t)0x007F);
|
|
break;
|
|
case UART_WORDLENGTH_9B:
|
|
if(huart->Init.Parity == UART_PARITY_NONE) {
|
|
r = (uint8_t)(huart->Instance->DR & (uint16_t)0x01FF);
|
|
__HAL_UNLOCK(huart);
|
|
return HAL_ERROR;
|
|
/* Not supported Configuration */
|
|
} else
|
|
r = (uint8_t)(huart->Instance->DR & (uint16_t)0x00FF);
|
|
break;
|
|
}
|
|
deque08_push_back (q, r);
|
|
/*!<
|
|
* \note
|
|
* We queue the received bytes. The user application MUST
|
|
* read the queue in a regular basis, or else this IRQ will
|
|
* find queue full and we will have data loss.
|
|
*/
|
|
|
|
__HAL_UNLOCK(huart);
|
|
return HAL_OK;
|
|
}
|
|
|
|
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
|
{
|
|
__HAL_UART_CLEAR_PEFLAG (huart);
|
|
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
|
huart->gState = HAL_UART_STATE_READY;
|
|
/*
|
|
* Clear all the error flag at once,
|
|
* Set USART READY for re-start,
|
|
* Error Callback
|
|
*/
|
|
}
|
|
/*!
|
|
* \brief
|
|
* USART serial handler. Pushes every received character to a queue.
|
|
*
|
|
* In the IRQ handler there is only Rx functionality provided by this driver.
|
|
* The Error handling call the HAL's callback (which are empty)
|
|
* The Tx part, is not implemented
|
|
*/
|
|
void USART2_IRQHandler (void) {
|
|
uint32_t tmp_flag = 0, tmp_it_source = 0;
|
|
|
|
// ======= Error handler =========
|
|
if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_PE)) != RESET) &&
|
|
((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_PE)) != RESET)) {
|
|
/* UART parity error interrupt occurred */
|
|
com_huart.ErrorCode |= HAL_UART_ERROR_PE;
|
|
}
|
|
if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_FE)) != RESET) &&
|
|
((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_ERR)) != RESET)) {
|
|
/* UART frame error interrupt occurred */
|
|
com_huart.ErrorCode |= HAL_UART_ERROR_FE;
|
|
}
|
|
if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_NE)) != RESET) &&
|
|
(tmp_it_source != RESET)){
|
|
/* UART noise error interrupt occurred */
|
|
com_huart.ErrorCode |= HAL_UART_ERROR_NE;
|
|
}
|
|
if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_ORE)) != RESET) &&
|
|
(tmp_it_source != RESET)){
|
|
/* USART Over-Run interrupt occurred */
|
|
com_huart.ErrorCode |= HAL_UART_ERROR_ORE;
|
|
}
|
|
|
|
if(com_huart.ErrorCode != HAL_UART_ERROR_NONE) {
|
|
HAL_UART_ErrorCallback (&com_huart);
|
|
}
|
|
|
|
// ====== Get Data =========
|
|
if(((tmp_flag = __HAL_UART_GET_FLAG(&com_huart, UART_FLAG_RXNE)) != RESET) &&
|
|
((tmp_it_source = __HAL_UART_GET_IT_SOURCE(&com_huart, UART_IT_RXNE)) != RESET)) {
|
|
// Read byte
|
|
_UART_read_data (&com_huart, &_com_rxq); // Don't check return status
|
|
}
|
|
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Initialize the UART and UART IRQ handler
|
|
* \return The status of the operation
|
|
* \arg LLD_ERROR Fail
|
|
* \arg LLD_OK Success
|
|
*/
|
|
static LLD_Status_en _COM_UART_Init (void) {
|
|
/*
|
|
* Enable UART clock
|
|
*/
|
|
_COM_CLK_ENABLE();
|
|
|
|
deque08_link_buffer (&_com_rxq, _com_rxbuffer);
|
|
deque08_set_capacity (&_com_rxq, COM_BUFFER_SIZE);
|
|
deque08_init (&_com_rxq);
|
|
|
|
/*
|
|
* USART configured as follows:
|
|
* - Word Length = 8 Bits
|
|
* - Stop Bit = One Stop bit
|
|
* - Parity = No parity
|
|
* - BaudRate = COM_BAUDRATE baud
|
|
* - Hardware flow control disabled (RTS and CTS signals)
|
|
*/
|
|
com_huart.Instance = COM_UART_INSTANCE;
|
|
com_huart.Init.BaudRate = COM_UART_BAUDRATE;
|
|
com_huart.Init.WordLength = UART_WORDLENGTH_8B;
|
|
com_huart.Init.StopBits = UART_STOPBITS_1;
|
|
com_huart.Init.Parity = UART_PARITY_NONE;
|
|
com_huart.Init.Mode = UART_MODE_TX_RX;
|
|
|
|
if (HAL_UART_Init(&com_huart) != HAL_OK)
|
|
return LLD_ERROR;
|
|
|
|
/*
|
|
* Enable IRQ for Rx
|
|
* Tx IRQ enabled by COM_transmit ()
|
|
*/
|
|
HAL_NVIC_SetPriority (COM_UART_IRQ, 0x0D, 0);
|
|
HAL_NVIC_EnableIRQ (COM_UART_IRQ);
|
|
|
|
/* Enable the UART Data Register not empty Interrupt */
|
|
__HAL_UART_ENABLE_IT(&com_huart, UART_IT_RXNE);
|
|
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
|
|
//__HAL_UART_ENABLE_IT(&com_huart, UART_IT_ERR);
|
|
|
|
return LLD_OK;
|
|
}
|
|
|
|
|
|
/*!
|
|
* Initialize the COM dedicated I/O and allocate resources
|
|
* \return The status of the operation
|
|
*/
|
|
LLD_Status_en COM_Init (void) {
|
|
GPIO_InitTypeDef GPIO_InitStruct;
|
|
|
|
__HAL_RCC_GPIOA_CLK_ENABLE ();
|
|
|
|
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
|
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
|
|
HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);
|
|
|
|
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
|
// GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
// GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
|
|
HAL_GPIO_Init (GPIOA, &GPIO_InitStruct);
|
|
|
|
return _COM_UART_Init();
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Set UART baudrate
|
|
* \param br The desired baudrate
|
|
* \return The status of the operation
|
|
* \arg LLD_ERROR Fail
|
|
* \arg LLD_OK Success
|
|
*/
|
|
LLD_Status_en COM_baudrate (uint32_t br) {
|
|
// Change only the Baudrate
|
|
com_huart.Init.BaudRate = br;
|
|
if (HAL_UART_Init(&com_huart) != HAL_OK)
|
|
return LLD_ERROR;
|
|
return LLD_OK;
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* USART's putchar functionality to link with io system
|
|
* This function is compatible with putchar() in "stdio.h"
|
|
*/
|
|
int COM_putchar (char c) {
|
|
if (_WaitOnFlagUntilTimeout (&com_huart, UART_FLAG_TC, RESET, COM_UART_PUTCHAR_TIMEOUT) != HAL_OK)
|
|
return 0xFFFF;
|
|
WRITE_REG (COM_UART_INSTANCE->DR, (c & (uint8_t)0xFF));
|
|
/*!<
|
|
* \note
|
|
* The sequence:
|
|
* - Read operation to USART_SR register [USART_GetFlagStatus()]
|
|
* - Write operation to USART_DR register [USART_SendData()]
|
|
* clears the TC Flag
|
|
*
|
|
* The TXE Flag is cleared by the write operation to USART_DR register
|
|
* [USART_SendData()]
|
|
*/
|
|
return (int)c;
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* USART's getchar functionality to link with io system
|
|
* This function is compatible with getchar() in "stdio.h"
|
|
*/
|
|
int COM_getchar (void) {
|
|
clock_t mark = clock ();
|
|
clock_t to = COM_UART_GETCHAR_TIMEOUT*get_freq();
|
|
clock_t now;
|
|
byte_t r=0;
|
|
|
|
while (deque08_pop_front (&_com_rxq, &r) == 0) {
|
|
now = clock ();
|
|
if (_CLOCK_DIFF(now, mark) >= to)
|
|
return 0;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Transmit functionality to link with io system
|
|
* This function is compatible with htp tx functionality
|
|
*
|
|
* \param data Pointer to data buffer
|
|
* \param size Size of buffer (number of bytes)
|
|
* \return The number of bytes to transmit
|
|
*/
|
|
int COM_Transmit (uint8_t *data, int size) {
|
|
int r = size;
|
|
|
|
while (size--) {
|
|
//queue08_push (&_com_txq, (byte_t)*data);
|
|
COM_putchar(*data++);
|
|
}
|
|
_WaitOnFlagUntilTimeout (&com_huart, UART_FLAG_TC, SET, COM_UART_PUTCHAR_TIMEOUT);
|
|
return r;
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Check receive functionality synchronized to IRQ
|
|
* This function is compatible with htp rx functionality
|
|
*
|
|
* \return The number of bytes on queue (<package_size> indicates done)
|
|
*/
|
|
int COM_CheckReceive (void) {
|
|
return deque08_size (&_com_rxq);
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Receive flush functionality to link with io system
|
|
* This function is compatible with htp rx functionality
|
|
*
|
|
* \param data Pointer to data buffer
|
|
* \param size Size of buffer (number of bytes)
|
|
* \return The number of received bytes
|
|
*/
|
|
void COM_ReceiveFlush (void) {
|
|
deque08_flush (&_com_rxq);
|
|
}
|
|
|
|
/*!
|
|
* \brief
|
|
* Receive functionality to link with io system
|
|
* This function is compatible with htp rx functionality
|
|
*
|
|
* \param data Pointer to data buffer
|
|
* \param size Size of buffer (number of bytes)
|
|
* \return The number of received bytes
|
|
*/
|
|
int COM_Receive (uint8_t *data, int size) {
|
|
int i;
|
|
uint8_t r=1, b;
|
|
|
|
for (i=0 ; r !=0 && i<size ; ++i) {
|
|
r = deque08_pop_front (&_com_rxq, &b);
|
|
data[i] = b;
|
|
}
|
|
return i;
|
|
}
|