4.2.1 rf_fec_flash.c

/*---------------------------------------------------------------------------*/
/* 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;
}