USART: put parity LUT in header so others can use it
This commit is contained in:
parent
62cc65d954
commit
8dd5b89944
|
@ -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
|
|||
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)
|
|||
{
|
||||
/* 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)
|
|||
// 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)
|
|||
{
|
||||
/* 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)
|
|||
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)
|
|||
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];
|
||||
|
|
|
@ -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…
Reference in New Issue