/*---------------------------------------------------------------------------*/
/* INCLUDES */
/*---------------------------------------------------------------------------*/
#include "globals/globals.h"
#include "rf/rf_fec_flash.h"
/*---------------------------------------------------------------------------*/
/* DEFINES */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* VARIABLES */
/*---------------------------------------------------------------------------*/
#pragma location = ".sram_g_fecCr"
__root __no_init uFecCr_t g_fecCr;
#pragma location = ".sram_g_fecSr"
__root __no_init uFecSr_t g_fecSr;
#pragma location = ".sram_g_fecTxDb"
__root __no_init uint8_t g_fecTxDb[21];
#pragma location = ".sram_g_fecRxDb"
__root __no_init uint8_t g_fecRxDb[21];
/*---------------------------------------------------------------------------*/
/* IMPLEMENTATION */
/*---------------------------------------------------------------------------*/
__root uint8_t ATA_fecEncryptDataByte_flash_C(uint8_t data)
{
uint8_t p1, p2, p4, p8, p_data;
p1 = ((data & 0x80) >> 7) ^ ((data & 0x40) >> 6) ^ ((data & 0x10) >> 4) ^ ((data & 0x08) >> 3) ^ ((data & 0x02) >> 1);
p2 = ((data & 0x80) >> 7) ^ ((data & 0x20) >> 5) ^ ((data & 0x10) >> 4) ^ ((data & 0x04) >> 2) ^ ((data & 0x02) >> 1);
p4 = ((data & 0x40) >> 6) ^ ((data & 0x20) >> 5) ^ ((data & 0x10) >> 4) ^ ((data & 0x01) >> 0);
p8 = ((data & 0x08) >> 3) ^ ((data & 0x04) >> 2) ^ ((data & 0x02) >> 1) ^ ((data & 0x01) >> 0);
p_data = (p8 << 3) | (p4 << 2) | (p2 << 1) | p1;
return p_data;
}
__root void ATA_fecEncryptSramBuffer_flash_C(void)
{
uint8_t i, p_data, p_dataLast, length;
DFC |= BM_DFDRA; /* AVR write access to FIFO */
length = g_fecCr.bfCNTE;
if(length > 21)
{ /* limit length to 21 bytes */
length = 21;
}
for(i = 0; i < length; i++)
{
p_data = ATA_fecEncryptDataByte_flash_C(g_fecTxDb[i]);
/* fill TX buffer */
if((i % 2) == 0)
{
DFD = g_fecTxDb[i]; /* data */
p_dataLast = p_data; /* parity bits */
}
else
{
DFD = (p_dataLast << 4) | (g_fecTxDb[i] >> 4); /* last parity + data[7:4] */
DFD = (g_fecTxDb[i] << 4) | p_data; /* data[3:0] + parity */
}
}
if((i % 2) == 1)
{
DFD = (p_dataLast << 4); /* add last parity if incomplete */
}
DFC &= (~BM_DFDRA); /* AVR read access to FIFO */
/* clear flag */
g_fecCr.bfSE = 0;
}
__root void ATA_fecDecryptRxBuffer_flash_C(void)
{
uint8_t length = DFL;
uint8_t encrData[32];
uint8_t p_calc, p_rec, data, failedBit;
uint8_t j = 0;
uint8_t errCorrected = 0;
/* clear decoder status bits */
g_fecSr.bValue = 0x00;
/* remove first two bytes in case second sync pattern on path B is activated */
if(g_uGlobalsTrxStatus.bfRxSotA && g_fecCr.bfPBA)
{
encrData[0] = DFD;
length--;
encrData[0] = DFD;
length--;
}
/* read RX data */
for(uint8_t i = 0; i < (length); i++)
{
encrData[i] = DFD;
if((i % 3) == 0)
{
continue;
}
else if((i % 3) == 1)
{
data = encrData[i - 1];
p_calc = ATA_fecEncryptDataByte_flash_C(data);
p_rec = encrData[i] >> 4;
}
else if((i % 3) == 2)
{
data = (encrData[i - 1] << 4) | (encrData[i] >> 4);
p_calc = ATA_fecEncryptDataByte_flash_C(data);
p_rec = encrData[i] & 0x0F;
}
if(p_calc != p_rec)
{ /* reception error */
failedBit = p_calc ^ p_rec;
/* hamming position to data byte index */
if (failedBit == 3) { failedBit = 7; }
else if(failedBit == 5) { failedBit = 6; }
else if(failedBit == 6) { failedBit = 5; }
else if(failedBit == 7) { failedBit = 4; }
else if(failedBit == 9) { failedBit = 3; }
else if(failedBit == 10) { failedBit = 2; }
else if(failedBit == 11) { failedBit = 1; }
else if(failedBit == 12) { failedBit = 0; }
else if(failedBit > 12)
{ /* uncorrectable error */
g_fecSr.bfNC = 1;
}
else
{ /* parity error - nothing to correct */
failedBit = 8;
g_fecSr.bfPE = 1;
}
/* correct swapped bit */
if(g_fecSr.bfNC)
{
/* nothing to do – not correctable error */
}
else if(failedBit < 8)
{
g_fecSr.bfEC = 1;
errCorrected += 1;
if((data & (1 << failedBit)) != 0)
{
data &= ~(1 << failedBit);
}
else
{
data |= (1 << failedBit);
}
}
}
g_fecRxDb[j++] = data;
}
/* add count of corrected errors to global SRAM variable */
/* limited to 15 bytes global counter range */
if(errCorrected > 0x0F)
{
g_fecSr.bfCE = 0x0F;
}
else
{
g_fecSr.bfCE = errCorrected;
}
/* fill remaining decryption buffer with zeros */
while(j < 21)
{
g_fecRxDb[j++] = 0x00;
}
/* clear flag */
g_fecCr.bfSD = 0;
}