// Read User Zone
uchar cm_ReadLargeZone(uint uiCryptoAddr, puchar pucBuffer, uchar ucCount)
{
    uchar ucReturn;

    ucCM_InsBuff[0] = 0xb2;
    ucCM_InsBuff[1] = (uchar)(uiCryptoAddr>>8);
    ucCM_InsBuff[2] = (uchar)uiCryptoAddr;
    ucCM_InsBuff[3] = ucCount;

    // Three bytes of the command must be included in the polynominals
    cm_GPAcmd3(ucCM_InsBuff);

    // Read the data
    if ((ucReturn = cm_ReadCommand(ucCM_InsBuff, pucBuffer, ucCount)) != SUCCESS) return ucReturn;

    // Include the data in the polynominals and decrypt if required
    cm_GPAdecrypt(ucCM_Encrypt, pucBuffer, ucCount);

    return SUCCESS;
}
// Read Checksum
uchar cm_ReadChecksum(uchar ucChipAddr, puchar pucChkSum)
{
    uchar ucDCR[1];
    uchar ucReturn;

    ucCmdRdChk[0] = (0x6 | ((ucChipAddr & 0xf) << 4));
    // 20 0x00s (10 0x00s, ignore first byte, 5 0x00s, ignore second byte, 5 0x00s  
    cm_GPAGenN(20);

    // Read the checksum                  
    if ((ucReturn = cm_ReadCommand(ucCmdRdChk, pucChkSum, 2)) != SUCCESS)
        return ucReturn;

    // Check if unlimited reads allowed
    if ((ucReturn = cm_ReadConfigZone(ucChipAddr, DCR_ADDR, ucDCR, 1)) != SUCCESS)
        return ucReturn;
    if ((ucDCR[0] & DCR_UCR))
        cm_ResetCrypto();

    return SUCCESS;
}