cdecodendefnxp-microcontroller

How to decode major and minor version nibble in C?


I am currently working on an I2C communication between an i.MX6 (Android BSP) and a NTAG 5 boost component.

I would like to decode the Capability Container at block 0 of the NTAG 5 EEPROM. I have written a C function that decodes the major and minor version of CC byte 1, as described in this table.

enter image description here

And here is my function:

static char CH_version[4] = "0.0";

bool F_decodeVersion(NTAG_HANDLE_T ntag) {
    uint8_t UI_localVersionAccessCondition;
    bool B_status = false;

    /* Reads byte 1 */
    if (!F_readCCByte(ntag, VERSION_ACCESS_COND_BYTE, &UI_localVersionAccessCondition)) {
        B_status = false;
    }

    /* To get the high nibble corresponding to version, we shift the value
       four bits to the right */
    UI_localVersionAccessCondition = UI_localVersionAccessCondition >> 4;

    /* Decode */
    switch(UI_localVersionAccessCondition) {
        case 0x00:
            memcpy(CH_version, "0.0", 4);
            break;
        case 0x01:
            memcpy(CH_version, "0.1", 4);
            break;
        case 0x02:
            memcpy(CH_version, "0.2", 4);
            break;
        case 0x03:
            memcpy(CH_version, "0.3", 4);
            break;
        case 0x04:
            memcpy(CH_version, "1.0", 4);
            break;
        case 0x05:
            memcpy(CH_version, "1.1", 4);
            break;
        case 0x06:
            memcpy(CH_version, "1.2", 4);
            break;
        case 0x07:
            memcpy(CH_version, "1.3", 4);
            break;
        case 0x08:
            memcpy(CH_version, "2.0", 4);
            break;
        case 0x09:
            memcpy(CH_version, "2.1", 4);
            break;
        case 0x0A:
            memcpy(CH_version, "2.2", 4);
            break;
        case 0x0B:
            memcpy(CH_version, "2.3", 4);
            break;
        case 0x0C:
            memcpy(CH_version, "3.0", 4);
            break;
        case 0x0D:
            memcpy(CH_version, "3.1", 4);
            break;
        case 0x0E:
            memcpy(CH_version, "3.2", 4);
            break;
        case 0x0F:
            memcpy(CH_version, "3.3", 4);
            break;
    }
    return true;
}

I'm sure that's not the best way to decode this nibble. I guess I should use the modulo operator.

How can I do it more efficiently?


Solution

  • You could try using just bitshifts and masking.

    CH_version[0] = (UI_localVersionAccessCondition >> 6) & 0x3 + '0';
    CH_version[1] = '.';
    CH_version[2] = (UI_localVersionAccessCondition >> 4) & 0x3 + '0';
    CH_version[3] = '\0';
    

    Consider not using global variables and doing bool F_decodeVersion(NTAG_HANDLE_T ntag, char *CH_version);