Browse Source

USART: put parity LUT in header so others can use it

spark_strober
King Kévin 4 years ago
parent
commit
8e710f21c4
  1. 43
      lib/usart_enhanced.c
  2. 6
      lib/usart_enhanced.h

43
lib/usart_enhanced.c

@ -38,11 +38,7 @@ static enum usart_enhanced_parity_t usart_enhanced_parity[USART_PERIPHERALS_NB]; @@ -38,11 +38,7 @@ static enum usart_enhanced_parity_t usart_enhanced_parity[USART_PERIPHERALS_NB];
/** last enhanced USART parity error status */
static bool usart_enhanced_parity_errors[USART_PERIPHERALS_NB];
/** know if there is an even number of 1's in a integer
* @remark a look-up is a lot faster than making the calculation and doesn't does a lot of (flash) space
*/
static const bool even_parity_lut[256] = { true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, };
const bool usart_enhanced_even_parity_lut[256] = { true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, };
/** get index of corresponding enhanced USART configurations
* @param[in] usart USART peripheral base address
@ -87,7 +83,7 @@ bool usart_enhanced_config(uint32_t usart, uint8_t databits, enum usart_enhanced @@ -87,7 +83,7 @@ bool usart_enhanced_config(uint32_t usart, uint8_t databits, enum usart_enhanced
usart_enhanced_databits[id] = databits;
usart_enhanced_parity[id] = parity;
// configure USART peripheral
if (8==databits && USART_ENHANCED_PARITY_NONE!=parity) { // the parity bit is additional to the data bits
if (8 == databits && USART_ENHANCED_PARITY_NONE != parity) { // the parity bit is additional to the data bits
usart_set_databits(usart, 9);
} else {
usart_set_databits(usart, 8);
@ -101,26 +97,26 @@ void usart_enhanced_send(uint32_t usart, uint8_t data) @@ -101,26 +97,26 @@ void usart_enhanced_send(uint32_t usart, uint8_t data)
{
/* sanity check */
uint8_t id = usart_enhanced_id(usart);
if (id>=USART_PERIPHERALS_NB) {
if (id >= USART_PERIPHERALS_NB) {
return;
}
data &= ~(0xff<<usart_enhanced_databits[id]); // only keep the data bits
data &= ~(0xff << usart_enhanced_databits[id]); // only keep the data bits
uint16_t output = data; // put value in output buffer
switch (usart_enhanced_parity[id]) {
case USART_ENHANCED_PARITY_NONE: // a mark is also decoded as idle/stop
case USART_ENHANCED_PARITY_MARK:
output |= (1<<usart_enhanced_databits[id]); // add idle state
output |= (1 << usart_enhanced_databits[id]); // add idle state
break;
case USART_ENHANCED_PARITY_EVEN:
if (!even_parity_lut[data]) {
output |= (1<<usart_enhanced_databits[id]);
if (!usart_enhanced_even_parity_lut[data]) {
output |= (1 << usart_enhanced_databits[id]);
}
// no need to clear a bit if the parity is even
break;
case USART_ENHANCED_PARITY_ODD:
if (even_parity_lut[data]) {
output |= (1<<usart_enhanced_databits[id]);
if (usart_enhanced_even_parity_lut[data]) {
output |= (1 << usart_enhanced_databits[id]);
}
// no need to clear a bit if the parity is odd
break;
@ -128,7 +124,7 @@ void usart_enhanced_send(uint32_t usart, uint8_t data) @@ -128,7 +124,7 @@ void usart_enhanced_send(uint32_t usart, uint8_t data)
// no need to clear the bit
break;
}
output |= (0xffff<<(usart_enhanced_databits[id]+1)); // set additional bits to idle (high)
output |= (0xffff << (usart_enhanced_databits[id] + 1)); // set additional bits to idle (high)
usart_send(usart, output); // transmit character
}
@ -136,14 +132,14 @@ uint8_t usart_enhanced_recv(uint32_t usart) @@ -136,14 +132,14 @@ uint8_t usart_enhanced_recv(uint32_t usart)
{
/* sanity check */
uint8_t id = usart_enhanced_id(usart);
if (id>=USART_PERIPHERALS_NB) {
if (id >= USART_PERIPHERALS_NB) {
return 0xff;
}
uint16_t input = usart_recv(usart); // read received character (also clears the error flags)
input &= ~(0xffff<<(usart_enhanced_databits[id]+1)); // only keep the data bits + parity bit
uint8_t data = input & ~(0xffff << usart_enhanced_databits[id]); // only keep the data bits
// check the parity
uint16_t parity = input&(1<<usart_enhanced_databits[id]); // only keep the parity bit
uint16_t parity = input & (1 << usart_enhanced_databits[id]); // only keep the parity bit
usart_enhanced_parity_errors[id] = false;
switch (usart_enhanced_parity[id]) {
case USART_ENHANCED_PARITY_NONE:
@ -151,16 +147,16 @@ uint8_t usart_enhanced_recv(uint32_t usart) @@ -151,16 +147,16 @@ uint8_t usart_enhanced_recv(uint32_t usart)
break;
case USART_ENHANCED_PARITY_EVEN:
if (parity) {
usart_enhanced_parity_errors[id] = !even_parity_lut[input&0xff];
usart_enhanced_parity_errors[id] = !usart_enhanced_even_parity_lut[data];
} else {
usart_enhanced_parity_errors[id] = even_parity_lut[input&0xff];
usart_enhanced_parity_errors[id] = usart_enhanced_even_parity_lut[data];
}
break;
case USART_ENHANCED_PARITY_ODD:
if (parity) {
usart_enhanced_parity_errors[id] = even_parity_lut[input&0xff];
usart_enhanced_parity_errors[id] = usart_enhanced_even_parity_lut[data];
} else {
usart_enhanced_parity_errors[id] = !even_parity_lut[input&0xff];
usart_enhanced_parity_errors[id] = !usart_enhanced_even_parity_lut[data];
}
break;
case USART_ENHANCED_PARITY_MARK:
@ -170,15 +166,14 @@ uint8_t usart_enhanced_recv(uint32_t usart) @@ -170,15 +166,14 @@ uint8_t usart_enhanced_recv(uint32_t usart)
usart_enhanced_parity_errors[id] = parity;
break;
}
input &= ~(0xffff<<(usart_enhanced_databits[id])); // only keep the data bits
return input;
return data;
}
bool usart_enhanced_parity_error(uint32_t usart)
{
/* sanity check */
uint8_t id = usart_enhanced_id(usart);
if (id>=USART_PERIPHERALS_NB) {
if (id >= USART_PERIPHERALS_NB) {
return false;
}
return usart_enhanced_parity_errors[id];

6
lib/usart_enhanced.h

@ -44,6 +44,12 @@ enum usart_enhanced_parity_t { @@ -44,6 +44,12 @@ enum usart_enhanced_parity_t {
USART_ENHANCED_PARITY_SPACE,
};
/** know if there is an even number of 1's in a integer
* @note this look up table is only useful for up to 8-bit words, else use __builtin_parity
* @remark a look-up is a lot faster than making the calculation and doesn't use a lot of (flash) memory
*/
extern const bool usart_enhanced_even_parity_lut[256];
/** configure enhanced USART
* @param[in] usart USART peripheral base address
* @param[in] databits word size in bits (5 to 8)

Loading…
Cancel
Save