basic work on uart

This commit is contained in:
2018-01-13 19:49:12 +01:00
parent 8852f9f8b4
commit d49081b190
13 changed files with 275 additions and 140 deletions
@@ -2,12 +2,11 @@
// Created by MightyPork on 2018/01/02.
//
#include <stm32f072xb.h>
#include "platform.h"
#include "comm/messages.h"
#include "unit_base.h"
#include "utils/avrlibc.h"
#include "unit_uart.h"
#include "unit_usart.h"
// SPI master
@@ -229,12 +228,11 @@ static void UUSART_writeIni(Unit *unit, IniWriter *iw)
iw_comment(iw, "Peripheral number (UARTx 1-4)");
iw_entry(iw, "device", "%d", (int)priv->periph_num);
iw_comment(iw, "Pin mappings (TX,RX,CK,CTS,RTS)");
iw_comment(iw, "Pin mappings (TX,RX,CK,CTS,RTS/DE)");
#if GEX_PLAT_F072_DISCOVERY
// TODO
iw_comment(iw, " USART1: (0) A9,A10,A8,A11,A12 (1) B6,B7,A8,A11,A12");
iw_comment(iw, " USART2: (0) A2,A3,A4,A0,A1 (1) D5,D6,D7,D3,D4");
iw_comment(iw, " USART3: (0) B10,B11,B12,B13,B14 (1) D8,D9,D10,D11,D12");
iw_comment(iw, " USART2: (0) A2,A3,A4,A0,A1 (1) A14,A15,A4,A0,A1");
iw_comment(iw, " USART3: (0) B10,B11,B12,B13,B14");
iw_comment(iw, " USART4: (0) A0,A1,C12,B7,A15 (1) C10,C11,C12,B7,A15");
#elif GEX_PLAT_F103_BLUEPILL
#error "NO IMPL"
@@ -306,19 +304,12 @@ static void UUSART_writeIni(Unit *unit, IniWriter *iw)
// ------------------------------------------------------------------------
struct paf {
char port;
uint8_t pin;
uint8_t af;
};
/** Finalize unit set-up */
static error_t UUSART_init(Unit *unit)
/** Claim the peripheral and assign priv->periph */
static error_t UUSART_ClaimPeripheral(Unit *unit)
{
bool suc = true;
struct priv *priv = unit->data;
if (!(priv->periph_num >= 1 && priv->periph_num <= 4)) {
if (!(priv->periph_num >= 1 && priv->periph_num <= 5)) {
dbg("!! Bad USART periph");
return E_BAD_CONFIG;
}
@@ -328,52 +319,78 @@ static error_t UUSART_init(Unit *unit)
TRY(rsc_claim(unit, R_USART1));
priv->periph = USART1;
}
#if defined(USART2)
else if (priv->periph_num == 2) {
TRY(rsc_claim(unit, R_USART2));
priv->periph = USART2;
}
#endif
#if defined(USART3)
else if (priv->periph_num == 3) {
TRY(rsc_claim(unit, R_USART3));
priv->periph = USART3;
}
#endif
#if defined(USART4)
else if (priv->periph_num == 4) {
TRY(rsc_claim(unit, R_USART4));
priv->periph = USART4;
}
#endif
#if defined(USART5)
else if (priv->periph_num == 5) {
TRY(rsc_claim(unit, R_USART5));
priv->periph = USART5;
}
#endif
else return E_BAD_CONFIG;
return E_SUCCESS;
}
/** Claim and configure GPIOs used */
static error_t UUSART_ConfigurePins(Unit *unit)
{
struct priv *priv = unit->data;
// This is written for F072, other platforms will need adjustments
// Configure UART pins (AF)
const struct paf *mappings = NULL;
#define want_ck_pin(priv) ((priv)->clock_output)
#define want_tx_pin(priv) (bool)((priv)->direction & 2)
#define want_rx_pin(priv) (bool)((priv)->direction & 1)
#define want_cts_pin(priv) ((priv)->hw_flow_control==2 || (priv)->hw_flow_control==3)
#define want_rts_pin(priv) ((priv)->de_output || (priv)->hw_flow_control==1 || (priv)->hw_flow_control==3)
/* List of required pins based on the user config */
bool pins_wanted[5] = {
want_ck_pin(priv),
want_tx_pin(priv),
want_rx_pin(priv),
want_cts_pin(priv),
want_rts_pin(priv)
};
// TODO
#if GEX_PLAT_F072_DISCOVERY
const struct paf mapping_1_0[5] = {
const struct PinAF *mappings = NULL;
// TODO adjust this, possibly remove / split to individual pin config for ..
// the final board
const struct PinAF mapping_1_0[5] = {
{'A', 8, LL_GPIO_AF_1}, // CK
{'A', 9, LL_GPIO_AF_1}, // TX
{'A', 10, LL_GPIO_AF_1}, // RX
{'A', 11, LL_GPIO_AF_1}, // CTS
{'A', 12, LL_GPIO_AF_1}, // RTS
{'A', 11, LL_GPIO_AF_1}, // CTS - collides with USB
{'A', 12, LL_GPIO_AF_1}, // RTS - collides with USB
};
const struct paf mapping_1_1[5] = {
{'A', 8, LL_GPIO_AF_1}, // CK
const struct PinAF mapping_1_1[5] = {
{'A', 8, LL_GPIO_AF_1}, // CK*
{'B', 6, LL_GPIO_AF_1}, // TX
{'B', 7, LL_GPIO_AF_1}, // RX
{'A', 11, LL_GPIO_AF_1}, // CTS
{'A', 12, LL_GPIO_AF_1}, // RTS
{'A', 11, LL_GPIO_AF_1}, // CTS* - collides with USB
{'A', 12, LL_GPIO_AF_1}, // RTS* - collides with USB
};
const struct paf mapping_2_0[5] = {
const struct PinAF mapping_2_0[5] = {
{'A', 4, LL_GPIO_AF_1}, // CK
{'A', 2, LL_GPIO_AF_1}, // TX
{'A', 3, LL_GPIO_AF_1}, // RX
@@ -381,15 +398,15 @@ static error_t UUSART_init(Unit *unit)
{'A', 1, LL_GPIO_AF_1}, // RTS
};
const struct paf mapping_2_1[5] = {
{'D', 7, LL_GPIO_AF_0}, // CK
{'D', 5, LL_GPIO_AF_0}, // TX
{'D', 6, LL_GPIO_AF_0}, // RX
{'D', 3, LL_GPIO_AF_0}, // CTS
{'D', 4, LL_GPIO_AF_0}, // RTS
const struct PinAF mapping_2_1[5] = {
{'A', 4, LL_GPIO_AF_1}, // CK*
{'A', 14, LL_GPIO_AF_1}, // TX
{'A', 15, LL_GPIO_AF_1}, // RX
{'A', 0, LL_GPIO_AF_1}, // CTS*
{'A', 1, LL_GPIO_AF_1}, // RTS*
};
const struct paf mapping_3_0[5] = {
const struct PinAF mapping_3_0[5] = {
{'B', 12, LL_GPIO_AF_4}, // CK
{'B', 10, LL_GPIO_AF_4}, // TX
{'B', 11, LL_GPIO_AF_4}, // RX
@@ -397,15 +414,7 @@ static error_t UUSART_init(Unit *unit)
{'B', 14, LL_GPIO_AF_4}, // RTS
};
const struct paf mapping_3_1[5] = {
{'D', 10, LL_GPIO_AF_0}, // CK
{'D', 8, LL_GPIO_AF_0}, // TX
{'D', 9, LL_GPIO_AF_0}, // RX
{'D', 11, LL_GPIO_AF_0}, // CTS
{'D', 12, LL_GPIO_AF_0}, // RTS
};
const struct paf mapping_4_0[5] = {
const struct PinAF mapping_4_0[5] = {
{'C', 12, LL_GPIO_AF_0}, // CK
{'A', 0, LL_GPIO_AF_4}, // TX
{'A', 1, LL_GPIO_AF_4}, // RX
@@ -413,12 +422,12 @@ static error_t UUSART_init(Unit *unit)
{'A', 15, LL_GPIO_AF_4}, // RTS
};
const struct paf mapping_4_1[5] = {
{'C', 12, LL_GPIO_AF_0}, // CK
const struct PinAF mapping_4_1[5] = {
{'C', 12, LL_GPIO_AF_0}, // CK*
{'C', 10, LL_GPIO_AF_0}, // TX
{'C', 11, LL_GPIO_AF_0}, // RX
{'B', 7, LL_GPIO_AF_4}, // CTS
{'A', 15, LL_GPIO_AF_4}, // RTS
{'B', 7, LL_GPIO_AF_4}, // CTS*
{'A', 15, LL_GPIO_AF_4}, // RTS*
};
if (priv->periph_num == 1) {
@@ -436,7 +445,6 @@ static error_t UUSART_init(Unit *unit)
else if (priv->periph_num == 3) {
// USART3
if (priv->remap == 0) mappings = &mapping_3_0[0];
else if (priv->remap == 1) mappings = &mapping_3_1[0];
else return E_BAD_CONFIG;
}
else if (priv->periph_num == 4) {
@@ -446,7 +454,15 @@ static error_t UUSART_init(Unit *unit)
else return E_BAD_CONFIG;
}
else return E_BAD_CONFIG;
// TODO other periphs
// Apply mappings based on the 'wanted' table
for (int i = 0; i < 5; i++) {
if (pins_wanted[i]) {
if (mappings[i].port == 0) return E_BAD_CONFIG;
TRY(rsc_claim_pin(unit, mappings[i].port, mappings[i].pin));
configure_gpio_alternate(mappings[i].port, mappings[i].pin, mappings[i].af);
}
}
#elif GEX_PLAT_F103_BLUEPILL
#error "NO IMPL"
@@ -458,39 +474,45 @@ static error_t UUSART_init(Unit *unit)
#error "BAD PLATFORM!"
#endif
// CK
if (priv->clock_output) {
TRY(rsc_claim_pin(unit, mappings[0].port, mappings[0].pin));
configure_gpio_alternate( mappings[0].port, mappings[0].pin, mappings[0].af);
return E_SUCCESS;
}
/** Finalize unit set-up */
static error_t UUSART_init(Unit *unit)
{
bool suc = true;
struct priv *priv = unit->data;
TRY(UUSART_ClaimPeripheral(unit));
TRY(UUSART_ConfigurePins(unit));
// --- Configure the peripheral ---
// Enable clock for the peripheral used
if (priv->periph_num == 1) {
__HAL_RCC_USART1_CLK_ENABLE();
}
// TX
if (priv->direction & 2) {
TRY(rsc_claim_pin(unit, mappings[1].port, mappings[1].pin));
configure_gpio_alternate( mappings[1].port, mappings[1].pin, mappings[1].af);
else if (priv->periph_num == 2) {
__HAL_RCC_USART2_CLK_ENABLE();
}
// RX
if (priv->direction & 1) {
TRY(rsc_claim_pin(unit, mappings[2].port, mappings[2].pin));
configure_gpio_alternate( mappings[2].port, mappings[2].pin, mappings[2].af);
else if (priv->periph_num == 3) {
__HAL_RCC_USART3_CLK_ENABLE();
}
// CTS
if (priv->hw_flow_control==2 || priv->hw_flow_control==3) {
TRY(rsc_claim_pin(unit, mappings[4].port, mappings[4].pin));
configure_gpio_alternate( mappings[4].port, mappings[4].pin, mappings[4].af);
#ifdef USART4
else if (priv->periph_num == 4) {
__HAL_RCC_USART4_CLK_ENABLE();
}
// RTS
if (priv->de_output || priv->hw_flow_control==1 || priv->hw_flow_control==3) {
TRY(rsc_claim_pin(unit, mappings[5].port, mappings[5].pin));
configure_gpio_alternate( mappings[5].port, mappings[5].pin, mappings[5].af);
#endif
#ifdef USART5
else if (priv->periph_num == 5) {
__HAL_RCC_USART5_CLK_ENABLE();
}
#endif
LL_USART_Disable(priv->periph);
{
LL_USART_DeInit(priv->periph);
LL_USART_SetBaudRate(priv->periph,
PLAT_AHB_MHZ*1000000,//FIXME this isn't great ...
LL_USART_OVERSAMPLING_16,
priv->baudrate);
LL_USART_SetBaudRate(priv->periph, PLAT_APB1_HZ, LL_USART_OVERSAMPLING_16, priv->baudrate);
LL_USART_SetParity(priv->periph,
priv->parity == 0 ? LL_USART_PARITY_NONE :
@@ -515,10 +537,8 @@ static error_t UUSART_init(Unit *unit)
: LL_USART_HWCONTROL_RTS_CTS);
LL_USART_ConfigClock(priv->periph,
priv->cpha ? LL_USART_PHASE_2EDGE
: LL_USART_PHASE_1EDGE,
priv->cpol ? LL_USART_POLARITY_HIGH
: LL_USART_POLARITY_LOW,
priv->cpha ? LL_USART_PHASE_2EDGE : LL_USART_PHASE_1EDGE,
priv->cpol ? LL_USART_POLARITY_HIGH : LL_USART_POLARITY_LOW,
true); // clock on last bit - TODO configurable?
if (priv->clock_output)
@@ -571,6 +591,27 @@ static void UUSART_deInit(Unit *unit)
if (unit->status == E_SUCCESS) {
assert_param(priv->periph);
LL_USART_DeInit(priv->periph);
// Disable clock
if (priv->periph_num == 1) {
__HAL_RCC_USART1_CLK_DISABLE();
}
else if (priv->periph_num == 2) {
__HAL_RCC_USART2_CLK_DISABLE();
}
else if (priv->periph_num == 3) {
__HAL_RCC_USART3_CLK_DISABLE();
}
#ifdef USART4
else if (priv->periph_num == 4) {
__HAL_RCC_USART4_CLK_DISABLE();
}
#endif
#ifdef USART5
else if (priv->periph_num == 5) {
__HAL_RCC_USART5_CLK_DISABLE();
}
#endif
}
// Release all resources
@@ -588,7 +629,6 @@ static error_t usart_wait_until_flag(struct priv *priv, uint32_t flag, bool stop
uint32_t t_start = HAL_GetTick();
while (((priv->periph->ISR & flag) != 0) != stop_state) {
if (HAL_GetTick() - t_start > 10) {
dbg("ERR waiting for ISR flag 0x%p = %d", (void*)flag, (int)stop_state);
return E_HW_TIMEOUT;
}
}
@@ -617,13 +657,7 @@ static error_t UUSART_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command,
struct priv *priv = unit->data;
switch (command) {
case CMD_WRITE:
dbg("Tx req. CR1 0x%p, CR2 0x%p, CR3 0x%p, BRR 0x%p",
(void*)priv->periph->CR1,
(void*)priv->periph->CR2,
(void*)priv->periph->CR3,
(void*)priv->periph->BRR);
case CMD_WRITE:;
uint32_t len;
const uint8_t *pld = pp_tail(pp, &len);