Erasing external FLASH - c

I'm working with a MCF51EM256 Freescale microcontroller and I've some problems to store data in the external flash memory to make it persistent.
I need to store this struct:
typedef struct {
ui64_s Ea_ps;
ui64_s Ea_ng;
ui64_s Er_q1;
ui64_s Er_q2;
ui64_s Er_q3;
ui64_s Er_q4;
uint16 F_ea;
uint16 F_er;
}Ws_EnergyAcc64;
Where:
typedef union{
uint64 v;
uint32 p[2];
} ui64_s;
and:
typedef unsigned long long int uint64;
typedef unsigned long int uint32;
typedef unsigned short int uint16;
In order to do this, I've implemented this function:
void Save_Flash_WsEnergyAcc(long addr, Ws_EnergyAcc64* Acc) {
// WsEnergyAcc struct needs 56 bytes in Flash
uint32 F_ea_32 = (uint32) Acc->F_ea;
uint32 F_er_32 = (uint32) Acc->F_er;
Flash_Erase(addr);
Flash_Erase(addr + 4);
Flash_Burst(addr, 2, Acc->Ea_ps.p);
Flash_Erase(addr + 8);
Flash_Erase(addr + 12);
Flash_Burst(addr + 8, 2, Acc->Ea_ng.p);
Flash_Erase(addr + 16);
Flash_Erase(addr + 20);
Flash_Burst(addr + 16, 2, Acc->Er_q1.p);
Flash_Erase(addr + 24);
Flash_Erase(addr + 28);
Flash_Burst(addr + 24, 2, Acc->Er_q2.p);
Flash_Erase(addr + 32);
Flash_Erase(addr + 36);
Flash_Burst(addr + 32, 2, Acc->Er_q3.p);
Flash_Erase(addr + 40);
Flash_Erase(addr + 44);
Flash_Burst(addr + 40, 2, Acc->Er_q4.p);
Flash_Erase(addr + 48);
Flash_Burst(addr + 48, 2, &F_ea_32);
Flash_Erase(addr + 52);
Flash_Burst(addr + 52, 2, &F_er_32);
}
Where "Flash_Burst" and "Flash_Erase":
#define FLASH_MASS_ERASE_CMD 0x41
#define FLASH_ERASE_CMD 0x40
#define FLASH_PROGRAM_CMD 0x20
#define FLASH_BURST_CMD 0x25
/* Macros to call the function using the different features */
#define Flash_Erase(Address) \
Flash_Cmd((UINT32)Address, (UINT16)1, (UINT32*)CUSTOM_ROM_ADDRESS, FLASH_ERASE_CMD)
#define Flash_Burst(Address, Size, DataPtr) \
Flash_Cmd((UINT32)Address, (UINT16)Size, (UINT32*)DataPtr, FLASH_BURST_CMD)
UINT8 /*far*/
Flash_Cmd(UINT32 FlashAddress,
UINT16 FlashDataCounter,
UINT32 *pFlashDataPtr,
UINT8 FlashCommand)
{
/* Check to see if FACCERR or PVIOL is set */
if (FSTAT &0x30)
{
/* Clear Flags if set*/
FSTAT = 0x30;
}
if (FlashDataCounter)
{
do
{
/* Wait for the Last Busrt Command to complete */
while(!(FSTAT&FSTAT_FCBEF_MASK)){};/*wait until termination*/
/* Write Data into Flash*/
(*((volatile unsigned long *)(FlashAddress))) = *pFlashDataPtr;
FlashAddress += 4;
pFlashDataPtr++;
/* Write Command */
FCMD = FlashCommand;
/* Put FCBEF at 1 */
FSTAT = FSTAT_FCBEF_MASK;
asm (NOP);
asm (NOP);
asm (NOP);
/* Check if Flash Access Error or Protection Violation Error are Set */
if (FSTAT&0x30)
{
/* If so, finish the function returning 1 to indicate error */
return (1);
}
}while (--FlashDataCounter);
}
/* wait for the last command to complete */
while ((FSTAT&FSTAT_FCCF_MASK)==0){};/*wait until termination*/
/* Return zero to indicate that the function executed OK */
return (0);
}
I also defined:
extern unsigned char __CUSTOM_ROM[];
extern unsigned char __CUSTOM_ROM_SIZE[];
#define CUSTOM_ROM_ADDRESS (unsigned long int)__CUSTOM_ROM
#define CUSTOM_ROM_SIZE (unsigned long int)__CUSTOM_ROM_SIZE
I don't understand what is CUSTOM_ROM_ADDRESS, and it causes a link error in my project:
C:/Freescale/CW MCU v10.6.4/MCU/ColdFire_Tools/Command_Line_Tools/mwldmcf|Linker|Error
>Undefined : "__CUSTOM_ROM"
I think it could be the data wich is stored in the erased address, and I tryed to do something like this (instead Flash_Erase(address)):
void EraseFlash(long addr) {
uint32 eraseData = 0xFFFFFFFF;
Flash_Cmd((uint32)addr, (uint16)1, (uint32*)&eraseData, 0x40);
}
It works in the first execution of "Save_Flash_WsEnergyAcc", but I cannot explain why it blocks the MCU the next times.
¿Can someone tell me what I'm doing wrong?
Thank you all!

The MCF51EM256 Freescale microcontroller only allows erase flash memory by 1024 bytes sectors.
If I call the Erase function each time I want to write the flash memory the MCU will be blocked.

Related

How to make an array to send the data to slave in AVR

I'm working on an AVR to learn it. my code is working properly. mean it gave me the output same as I want but I want to modify the code. I made 4 functions to send the data to the slave. like as it's in the code I want to send 61,62,63,64. but for these, I make four functions. Now I want to modify it as all the data send to the salve by one function. so my line of code will be reduced. second I want that once the 61 sends to the salve it prints something like datatransfered and once the dataexchange it's display **exchanged**. I tried to make the array and take numbers one by one but was unlucky.
#include <xc.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
void SPI0_init(void);
void LTCSelect(void);
void LTCDeselect(void);
uint8_t SPI0_exchangeData(uint8_t data);
uint8_t SPI1_exchangeData(uint8_t data1);
uint8_t SPI2_exchangeData(uint8_t data2);
uint8_t SPI3_exchangeData(uint8_t data3);
void SPI0_init(void){
PORTA.DIR |= PIN4_bm; /* Set MOSI pin direction to output (output to LTC2983) */
PORTA.DIR &= ~PIN5_bm; /* Set MISO pin direction to input (input form LTC2983) */
PORTA.DIR |= PIN6_bm; /* Set SCK pin direction to output (output to LTC2983) */
PORTA.DIR |= PIN7_bm; /* Set CS pin direction to output (output to LTC2983) */
SPI0.CTRLA = SPI_CLK2X_bm /* Enable double-speed */
| SPI_DORD_bm /* LSB is transmitted first */
| SPI_ENABLE_bm /* Enable module */
| SPI_MASTER_bm /* SPI module in Master mode */
| SPI_PRESC_DIV16_gc; /* System Clock divided by 16 */}
uint8_t SPI0_exchangeData(uint8_t data){
SPI0.DATA = data;
while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/
{
}
return SPI0.DATA;}
uint8_t SPI1_exchangeData(uint8_t data1)
{
SPI0.DATA = data1;
while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/
{
}
return SPI0.DATA;}
uint8_t SPI2_exchangeData(uint8_t data2){
SPI0.DATA = data2;
while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/
{
}
return SPI0.DATA;}
uint8_t SPI3_exchangeData(uint8_t data3){
SPI0.DATA = data3;
while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/
{
}
return SPI0.DATA;}
void LTCSelect(void){
PORTA.OUT &= ~PIN7_bm; // Set SS pin value to LOW}
void LTCDeselect(void){
PORTA.OUT |= PIN7_bm; // Set SS pin value to HIGH}
int main(void){
uint8_t data = 61;
uint8_t data1 = 62;
uint8_t data2 = 63;
uint8_t data3 = 64;
SPI0_init();
while(1){
LTCSelect();
SPI0_exchangeData(data);
SPI1_exchangeData(data1);
SPI2_exchangeData(data2);
SPI3_exchangeData(data3);
LTCDeselect();
}}
Just use the first function. The others are just a copy, are the same and unnecessary.
uint8_t SPI0_exchangeData(uint8_t data){
SPI0.DATA = data;
while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/
{
}
return SPI0.DATA;
}
and in your main loop call the same function to send all your data:
int main(void){
uint8_t data = 61;
uint8_t data1 = 62;
uint8_t data2 = 63;
uint8_t data3 = 64;
SPI0_init();
while(1){
LTCSelect();
SPI0_exchangeData(data);
SPI0_exchangeData(data1);
SPI0_exchangeData(data2);
SPI0_exchangeData(data3);
LTCDeselect();
}
}
There you shuld have your numbers respectively in your slave device.
Update for sending array
/**
* Sends an uint8_t array to SPI0
*
* Here we send an array of uint8_t (aka unsigned char) to SPI0 one by one.
* using the length parameter and an index variable.
*
* #param data a data array to send to SPI0.
* #param length the length of the given array.
* #returns nothing, but you can return any util info if you wish
*/
void sendArray(uint8_t data[], uint8_t length) {
for(uint8_t i = 0; i < length; i++) {
SPI0_exchangeData(data[i]);
}
}
// Suppose we have an array named buffer
uint8_t buffer[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
// Some where in the main loop we want to send it to the SPI0
int main(void) {
//...
while(1) {
//...
// We pass the array and its length in this way
sendArray(buffer, sizeof(buffer));
}
return 0;
}
Note that the array is defined and assigned statically. In real cases the arrays mostly used with a statically allocated memory, say 64 bytes i.e. uint8_t buffer[64];, but this does not mean that it will contain data in full capacity. Hence when the data is written to an array must be counted and stored in a variable to know the actual length of that array when needed.

Is this the right way to access function?

I am currently using "STM32F429I-DISC1" with joystick. I am trying to draw something on the LCD screen and using joystick move this object. My drawing is working fine, but I have the error: " void value not ignored as it ought to be".
This two lines have problems...
localX = Joy_ReadXY(CTRL_REG_IN3);
localY = Joy_ReadXY(CTRL_REG_IN4);
Can someone please tell me, how I can fix this error?
And why I see this error?
Main.c
#include "stm32f429i_discovery_lcd.h"
#define CTRL_REG_IN3 0b00011000
#define CTRL_REG_IN4 0b00100000
SemaphoreHandle_t xMutex;
Joystick_data xy;
void vTaskFunction1(void *pvParameters) {
uint16_t localX;
uint16_t localY;
for(;;) {
localX = Joy_ReadXY(CTRL_REG_IN3);
localY = Joy_ReadXY(CTRL_REG_IN4);
xSemaphoreTake( xMutex, portMAX_DELAY );
xy.x = localX;
xy.y = localY;
xSemaphoreGive( xMutex );
HAL_Delay(10);
}
}
void vTaskFunction2(void *pvParameters) {
uint32_t xCoord = 240/2;
uint32_t yCoord = 320/2;
uint8_t reads = 0;
uint8_t ballRadius = 5;
uint16_t xLimitMin = ballRadius+25;
uint16_t xLimitMax = 240-ballRadius-25;
uint16_t yLimitMin = ballRadius+25;
uint16_t yLimitMax = 320-ballRadius-25;
for(;;) {
xSemaphoreTake( xMutex, portMAX_DELAY );
if (xy.x > 3000 && !(xCoord < xLimitMin))
xCoord -= 5;
if (xy.x < 1000 && !(xCoord > xLimitMax))
xCoord += 5;
if (xy.y > 3000 && !(yCoord < yLimitMin))
yCoord -= 5;
if (xy.y < 1000 && !(yCoord > yLimitMax))
yCoord += 5;
reads++;
BSP_LCD_Clear(LCD_COLOR_WHITE);
BSP_LCD_DrawCircle(xCoord, yCoord, ballRadius);
BSP_LCD_FillCircle(xCoord, yCoord, ballRadius);
xSemaphoreGive(xMutex);
HAL_Delay(20);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI4_Init();
MX_TIM1_Init();
MX_USART1_UART_Init();
// LCD Things
BSP_LCD_Init();
BSP_LCD_LayerDefaultInit(1, LCD_FRAME_BUFFER);
BSP_LCD_SelectLayer(1);
BSP_LCD_SetBackColor(LCD_COLOR_WHITE); // Vali meelepärane värv
BSP_LCD_Clear(LCD_COLOR_WHITE);
BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE); // Vali meelepärane värv
MX_FREERTOS_Init();
if ( xMutex == NULL )
{
xMutex = xSemaphoreCreateMutex();
if ( ( xMutex ) != NULL )
xSemaphoreGive( ( xMutex ) );
}
xTaskCreate(vTaskFunction1, "Task 1", 100, NULL, 1, NULL);
xTaskCreate(vTaskFunction2, "Task 2", 100, NULL, 1, NULL);
vTaskStartScheduler();
osKernelStart();
while (1)
{
}
}
Read joystick function (joystick.c)
#include <stdio.h>
#include <main.h>
#include "gpio.h"
#include "spi.h"
#define READ_SLAVE_OPERATION 0b10000000
#define READ_INCR_SLAVE_OPERATION 0b11000000
#define WRITE_SLAVE_OPERATION 0b00000000
#define CTRL_REG_IN3 0b00000011
#define CTRL_REG_IN4 0b00000100
#define OUT_X_L 0x28
#define OUT_X_H 0x29
#define OUT_Y_L 0x2A
#define OUT_Y_H 0x2B
#define OUT_Z_L 0x2C
#define OUT_Z_H 0x2D
#define JOY_CS_LOW() HAL_GPIO_WritePin(JOY_CS_GPIO_PORT, JOY_CS_PIN, 0)
#define JOY_CS_HIGH() HAL_GPIO_WritePin(JOY_CS_GPIO_PORT, JOY_CS_PIN, 1)
#define JOY_CS_GPIO_PORT GPIOC
#define JOY_CS_PIN GPIO_PIN_13
int16_t Joy_ReadXY(uint8_t reg1){
uint8_t pTxData1[2] = {reg1, 0};
uint8_t pRxData1[2] = {0, 0};
JOY_CS_LOW();
HAL_SPI_TransmitReceive(&hspi4, pTxData1, pRxData1, 2, HAL_MAX_DELAY);
JOY_CS_HIGH();
return pRxData1[0] << 8 | pRxData1[1];
}
Here, in Main.c, you call the function before telling the compiler about what parameters and what return value types it has.
localX = Joy_ReadXY(CTRL_REG_IN3);
localY = Joy_ReadXY(CTRL_REG_IN4)
That confused the compiler and it starts "guessing" about them.
Guessing that it is a void-returning function, the compiler then complains that you are expecting a return value from a function which does return void i.e. nothing.
The returned void should be ignored, instead of attempting to write it to a variable. At least that is what the compiler thinks...
To fix it, you should explain to the compiler that there is a function elsewhere, with name, parameters and return value type. That is done by providing the prototype
int16_t Joy_ReadXY(uint8_t reg1);
It needs to be done before the function body in which the the extern function is first called. (And you already confirmed in comments that it fixes the described problem in your code.)
Note that for the other shown functions this is not needed, because they are defined (with head and body) before they are called.
Similar for other functions, which have their prototype provided in the header you include early on.
Actually, putting the prototype of your function into a header and including that similarily would be the best way to solve this.

Computing CRC16 with reflected / bit reversed input in C

I want to compute the reflected CRC16 of the CCITT polynomial 0x1021 starting from 0xC6C6 (no XOR at end, also known as CRC16-A on this page https://crccalc.com) in two different ways with (embedded) C.
For the two alternatives, I want to use the polynomial 0x1021 starting with 0xC6C6 as well as the reflected polynomial 0x8408 starting from 0x6363 (= reflect(0xC6C6)).
Assume I have a lookup-table for each polynomial:
static const UINT16 au16Table1021[256u]
and
static const UINT16 au16Table8408[256u]
and a reflect function that reverses the bit order of a byte (e.g. based on
In C/C++ what's the simplest way to reverse the order of bits in a byte?)
From the accepted answer of How to configure calculation of CRC table I expected that I would get the same result by reflecting the input, the starting CRC (wOldCRC = 0xC6C6), shifting the CRC calculation in the opposed direction and finally reflecting the resulting CRC. However, the second option I tried does not yield the expected result. What am I doing wrong?
Minimal (more or less) working example with incorrect CRC for option 2:
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
static const uint16_t crcTable1021[256u] = {
0x0000u, 0x17CEu, 0x0FDFu, 0x1811u, 0x1FBEu, 0x0870u, 0x1061u, 0x07AFu,
0x1F3Fu, 0x08F1u, 0x10E0u, 0x072Eu, 0x0081u, 0x174Fu, 0x0F5Eu, 0x1890u,
0x1E3Du, 0x09F3u, 0x11E2u, 0x062Cu, 0x0183u, 0x164Du, 0x0E5Cu, 0x1992u,
0x0102u, 0x16CCu, 0x0EDDu, 0x1913u, 0x1EBCu, 0x0972u, 0x1163u, 0x06ADu,
0x1C39u, 0x0BF7u, 0x13E6u, 0x0428u, 0x0387u, 0x1449u, 0x0C58u, 0x1B96u,
0x0306u, 0x14C8u, 0x0CD9u, 0x1B17u, 0x1CB8u, 0x0B76u, 0x1367u, 0x04A9u,
0x0204u, 0x15CAu, 0x0DDBu, 0x1A15u, 0x1DBAu, 0x0A74u, 0x1265u, 0x05ABu,
0x1D3Bu, 0x0AF5u, 0x12E4u, 0x052Au, 0x0285u, 0x154Bu, 0x0D5Au, 0x1A94u,
0x1831u, 0x0FFFu, 0x17EEu, 0x0020u, 0x078Fu, 0x1041u, 0x0850u, 0x1F9Eu,
0x070Eu, 0x10C0u, 0x08D1u, 0x1F1Fu, 0x18B0u, 0x0F7Eu, 0x176Fu, 0x00A1u,
0x060Cu, 0x11C2u, 0x09D3u, 0x1E1Du, 0x19B2u, 0x0E7Cu, 0x166Du, 0x01A3u,
0x1933u, 0x0EFDu, 0x16ECu, 0x0122u, 0x068Du, 0x1143u, 0x0952u, 0x1E9Cu,
0x0408u, 0x13C6u, 0x0BD7u, 0x1C19u, 0x1BB6u, 0x0C78u, 0x1469u, 0x03A7u,
0x1B37u, 0x0CF9u, 0x14E8u, 0x0326u, 0x0489u, 0x1347u, 0x0B56u, 0x1C98u,
0x1A35u, 0x0DFBu, 0x15EAu, 0x0224u, 0x058Bu, 0x1245u, 0x0A54u, 0x1D9Au,
0x050Au, 0x12C4u, 0x0AD5u, 0x1D1Bu, 0x1AB4u, 0x0D7Au, 0x156Bu, 0x02A5u,
0x1021u, 0x07EFu, 0x1FFEu, 0x0830u, 0x0F9Fu, 0x1851u, 0x0040u, 0x178Eu,
0x0F1Eu, 0x18D0u, 0x00C1u, 0x170Fu, 0x10A0u, 0x076Eu, 0x1F7Fu, 0x08B1u,
0x0E1Cu, 0x19D2u, 0x01C3u, 0x160Du, 0x11A2u, 0x066Cu, 0x1E7Du, 0x09B3u,
0x1123u, 0x06EDu, 0x1EFCu, 0x0932u, 0x0E9Du, 0x1953u, 0x0142u, 0x168Cu,
0x0C18u, 0x1BD6u, 0x03C7u, 0x1409u, 0x13A6u, 0x0468u, 0x1C79u, 0x0BB7u,
0x1327u, 0x04E9u, 0x1CF8u, 0x0B36u, 0x0C99u, 0x1B57u, 0x0346u, 0x1488u,
0x1225u, 0x05EBu, 0x1DFAu, 0x0A34u, 0x0D9Bu, 0x1A55u, 0x0244u, 0x158Au,
0x0D1Au, 0x1AD4u, 0x02C5u, 0x150Bu, 0x12A4u, 0x056Au, 0x1D7Bu, 0x0AB5u,
0x0810u, 0x1FDEu, 0x07CFu, 0x1001u, 0x17AEu, 0x0060u, 0x1871u, 0x0FBFu,
0x172Fu, 0x00E1u, 0x18F0u, 0x0F3Eu, 0x0891u, 0x1F5Fu, 0x074Eu, 0x1080u,
0x162Du, 0x01E3u, 0x19F2u, 0x0E3Cu, 0x0993u, 0x1E5Du, 0x064Cu, 0x1182u,
0x0912u, 0x1EDCu, 0x06CDu, 0x1103u, 0x16ACu, 0x0162u, 0x1973u, 0x0EBDu,
0x1429u, 0x03E7u, 0x1BF6u, 0x0C38u, 0x0B97u, 0x1C59u, 0x0448u, 0x1386u,
0x0B16u, 0x1CD8u, 0x04C9u, 0x1307u, 0x14A8u, 0x0366u, 0x1B77u, 0x0CB9u,
0x0A14u, 0x1DDAu, 0x05CBu, 0x1205u, 0x15AAu, 0x0264u, 0x1A75u, 0x0DBBu,
0x152Bu, 0x02E5u, 0x1AF4u, 0x0D3Au, 0x0A95u, 0x1D5Bu, 0x054Au, 0x1284u,
};
static const uint16_t crcTable8408[256u] = {
0x0000u, 0x1189u, 0x2312u, 0x329Bu, 0x4624u, 0x57ADu, 0x6536u, 0x74BFu,
0x8C48u, 0x9DC1u, 0xAF5Au, 0xBED3u, 0xCA6Cu, 0xDBE5u, 0xE97Eu, 0xF8F7u,
0x1081u, 0x0108u, 0x3393u, 0x221Au, 0x56A5u, 0x472Cu, 0x75B7u, 0x643Eu,
0x9CC9u, 0x8D40u, 0xBFDBu, 0xAE52u, 0xDAEDu, 0xCB64u, 0xF9FFu, 0xE876u,
0x2102u, 0x308Bu, 0x0210u, 0x1399u, 0x6726u, 0x76AFu, 0x4434u, 0x55BDu,
0xAD4Au, 0xBCC3u, 0x8E58u, 0x9FD1u, 0xEB6Eu, 0xFAE7u, 0xC87Cu, 0xD9F5u,
0x3183u, 0x200Au, 0x1291u, 0x0318u, 0x77A7u, 0x662Eu, 0x54B5u, 0x453Cu,
0xBDCBu, 0xAC42u, 0x9ED9u, 0x8F50u, 0xFBEFu, 0xEA66u, 0xD8FDu, 0xC974u,
0x4204u, 0x538Du, 0x6116u, 0x709Fu, 0x0420u, 0x15A9u, 0x2732u, 0x36BBu,
0xCE4Cu, 0xDFC5u, 0xED5Eu, 0xFCD7u, 0x8868u, 0x99E1u, 0xAB7Au, 0xBAF3u,
0x5285u, 0x430Cu, 0x7197u, 0x601Eu, 0x14A1u, 0x0528u, 0x37B3u, 0x263Au,
0xDECDu, 0xCF44u, 0xFDDFu, 0xEC56u, 0x98E9u, 0x8960u, 0xBBFBu, 0xAA72u,
0x6306u, 0x728Fu, 0x4014u, 0x519Du, 0x2522u, 0x34ABu, 0x0630u, 0x17B9u,
0xEF4Eu, 0xFEC7u, 0xCC5Cu, 0xDDD5u, 0xA96Au, 0xB8E3u, 0x8A78u, 0x9BF1u,
0x7387u, 0x620Eu, 0x5095u, 0x411Cu, 0x35A3u, 0x242Au, 0x16B1u, 0x0738u,
0xFFCFu, 0xEE46u, 0xDCDDu, 0xCD54u, 0xB9EBu, 0xA862u, 0x9AF9u, 0x8B70u,
0x8408u, 0x9581u, 0xA71Au, 0xB693u, 0xC22Cu, 0xD3A5u, 0xE13Eu, 0xF0B7u,
0x0840u, 0x19C9u, 0x2B52u, 0x3ADBu, 0x4E64u, 0x5FEDu, 0x6D76u, 0x7CFFu,
0x9489u, 0x8500u, 0xB79Bu, 0xA612u, 0xD2ADu, 0xC324u, 0xF1BFu, 0xE036u,
0x18C1u, 0x0948u, 0x3BD3u, 0x2A5Au, 0x5EE5u, 0x4F6Cu, 0x7DF7u, 0x6C7Eu,
0xA50Au, 0xB483u, 0x8618u, 0x9791u, 0xE32Eu, 0xF2A7u, 0xC03Cu, 0xD1B5u,
0x2942u, 0x38CBu, 0x0A50u, 0x1BD9u, 0x6F66u, 0x7EEFu, 0x4C74u, 0x5DFDu,
0xB58Bu, 0xA402u, 0x9699u, 0x8710u, 0xF3AFu, 0xE226u, 0xD0BDu, 0xC134u,
0x39C3u, 0x284Au, 0x1AD1u, 0x0B58u, 0x7FE7u, 0x6E6Eu, 0x5CF5u, 0x4D7Cu,
0xC60Cu, 0xD785u, 0xE51Eu, 0xF497u, 0x8028u, 0x91A1u, 0xA33Au, 0xB2B3u,
0x4A44u, 0x5BCDu, 0x6956u, 0x78DFu, 0x0C60u, 0x1DE9u, 0x2F72u, 0x3EFBu,
0xD68Du, 0xC704u, 0xF59Fu, 0xE416u, 0x90A9u, 0x8120u, 0xB3BBu, 0xA232u,
0x5AC5u, 0x4B4Cu, 0x79D7u, 0x685Eu, 0x1CE1u, 0x0D68u, 0x3FF3u, 0x2E7Au,
0xE70Eu, 0xF687u, 0xC41Cu, 0xD595u, 0xA12Au, 0xB0A3u, 0x8238u, 0x93B1u,
0x6B46u, 0x7ACFu, 0x4854u, 0x59DDu, 0x2D62u, 0x3CEBu, 0x0E70u, 0x1FF9u,
0xF78Fu, 0xE606u, 0xD49Du, 0xC514u, 0xB1ABu, 0xA022u, 0x92B9u, 0x8330u,
0x7BC7u, 0x6A4Eu, 0x58D5u, 0x495Cu, 0x3DE3u, 0x2C6Au, 0x1EF1u, 0x0F78u,
};
static uint8_t reverse(uint8_t n) {
static uint8_t lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };
uint8_t result;
result = lookup[n & 0xF] << 4 | lookup[n>>4];
return result;
}
static uint16_t reverse16(uint16_t n) {
return reverse(n & 0xFF) << 8 | reverse(n >> 8);
}
uint16_t Calculate(const uint8_t *message, int nBytes, uint16_t wOldCRC) {
uint8_t data;
uint16_t remainder = wOldCRC;
for (int byte = 0; byte < nBytes; ++byte) {
data = message[byte] ^ remainder;
remainder = crcTable8408[data] ^ (remainder >> 8);
}
return remainder;
}
uint16_t CalculateInv(const uint8_t *message, int nBytes, uint16_t wOldCRC) {
uint8_t data;
uint16_t remainder = wOldCRC; //already reversed in function call
for (int byte = nBytes; byte > 0; --byte) {
data = reverse(message[byte-1]) ^ remainder;
remainder = crcTable1021[data] ^ (remainder << 8);
}
return reverse16(remainder);
}
int main(void) {
uint16_t expected = 0x4167;
uint8_t pattern[] = "Hello World!";
uint16_t result = Calculate(pattern, 12, 0x6363);
printf("CRC option 1: 0x%04x, expected 0x%04x\n", result, expected);
result = CalculateInv(pattern, 12, 0xC6C6);
printf("CRC option 2: 0x%04X, expected 0x%04X\n", result, expected);
return EXIT_SUCCESS;
}
Output:
CRC option 1: 0x4167, expected 0x4167
CRC option 2: 0x62FD, expected 0x4167
Edit: I created the tables by slightly adapting the code from the accepted answer from How to configure calculation of CRC table as follows:
uint16_t crcTable[256];
void Init(uint16_t polynomial) {
uint16_t remainder;
for (int dividend = 0; dividend < 256; ++dividend) {
remainder = dividend;
for (uint8_t bit = 8; bit > 0; --bit) {
if (remainder & 1)
remainder = (remainder >> 1) ^ polynomial;
else
remainder = (remainder >> 1);
}
crcTable[dividend] = remainder;
}
printf("static const uint_t crcTable[256u] = {");
for (int i = 0; i<32; ++i) {
printf("\n ");
for (int j=0; j<8; ++j) {
printf("0x%04Xu, ",crcTable[i*8+j]);
}
}
printf("\n};\n");
}
For a reflected CRC16, only the bits of each byte of a message are reversed, the message itself is not reversed. The other issue is that crcTable1021 needs to be based on a left shifting algorithm, or it can be a copy of crcTable8408 with the index and values reflected. (Comment - the 8408 CRC is a reflected CRC, while the 1021 is normally a non-reflected CRC, but in this case the input and output is being reflected to match the 8408 CRC). Example code that appears to be working:
static uint16_t crcTable8408[256u]; // could use table from question
static uint16_t crcTable1021[256u]; // could use table from automationwiki
// ... no changes ... //
uint16_t CalculateInv(const uint8_t *message, int nBytes, uint16_t wOldCRC) {
uint8_t data;
uint16_t remainder = wOldCRC; //already reversed in function call
for (int byte = 0; byte < nBytes; ++byte) { // fix
data = reverse(message[byte]) ^ (remainder >> 8); // fix
remainder = crcTable1021[data] ^ (remainder << 8); // fix
}
return reverse16(remainder);
}
void InitTables(void) { // generate tables
uint16_t polynomial = 0x8408;
uint16_t remainder;
for (int dividend = 0; dividend < 256; ++dividend) {
remainder = dividend;
for (uint8_t bit = 8; bit > 0; --bit) {
if (remainder & 1)
remainder = (remainder >> 1) ^ polynomial;
else
remainder = (remainder >> 1);
}
crcTable8408[dividend] = remainder;
crcTable1021[reverse(dividend)] = reverse16(remainder);
}
}
int main(void) {
uint16_t expected = 0x4167;
uint8_t pattern[] = "Hello World!";
InitTables(); // generate tables (or use constant tables)
uint16_t result = Calculate(pattern, 12, 0x6363);
printf("CRC option 1: 0x%04X, expected 0x%04x\n", result, expected);
result = CalculateInv(pattern, 12, 0xC6C6);
printf("CRC option 2: 0x%04X, expected 0x%04X\n", result, expected);
return 0;
}
You can use crcany to generate the code (in C) for any CRC you specify. As it happens, the 16-bit CRC reflected with polynomial 0x1021, initial value 0xc6c6, and final xor 0 is already in the list of standard CRCs. This is the code generated, and it produces 0x4167 for the 12 bytes "Hello, World!":
crc16iso_iec_14443_3_a.h:
// The _bit, _byte, and _word routines return the CRC of the len bytes at mem,
// applied to the previous CRC value, crc. If mem is NULL, then the other
// arguments are ignored, and the initial CRC, i.e. the CRC of zero bytes, is
// returned. Those routines will all return the same result, differing only in
// speed and code complexity. The _rem routine returns the CRC of the remaining
// bits in the last byte, for when the number of bits in the message is not a
// multiple of eight. The low bits bits of the low byte of val are applied to
// crc. bits must be in 0..8.
#include <stddef.h>
// Compute the CRC a bit at a time.
unsigned crc16iso_iec_14443_3_a_bit(unsigned crc, void const *mem, size_t len);
// Compute the CRC of the low bits bits in val.
unsigned crc16iso_iec_14443_3_a_rem(unsigned crc, unsigned val, unsigned bits);
// Compute the CRC a byte at a time.
unsigned crc16iso_iec_14443_3_a_byte(unsigned crc, void const *mem, size_t len);
// Compute the CRC a word at a time.
unsigned crc16iso_iec_14443_3_a_word(unsigned crc, void const *mem, size_t len);
crc16iso_iec_14443_3_a.c:
#include <stdint.h>
#include "crc16iso_iec_14443_3_a.h"
// This code assumes that unsigned is 4 bytes.
unsigned crc16iso_iec_14443_3_a_bit(unsigned crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0x6363;
crc &= 0xffff;
while (len--) {
crc ^= *data++;
for (unsigned k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0x8408 : crc >> 1;
}
return crc;
}
unsigned crc16iso_iec_14443_3_a_rem(unsigned crc, unsigned val, unsigned bits) {
crc &= 0xffff;
val &= (1U << bits) - 1;
crc ^= val;
while (bits--)
crc = crc & 1 ? (crc >> 1) ^ 0x8408 : crc >> 1;
return crc;
}
#define table_byte table_word[0]
static unsigned short const table_word[][256] = {
{0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1,
0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a,
0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64,
0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a,
0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50,
0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9,
0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44,
0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d,
0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3,
0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581,
0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb,
0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324,
0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb,
0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710,
0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e,
0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704,
0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e,
0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3,
0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e,
0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78},
{0x0000, 0x19d8, 0x33b0, 0x2a68, 0x6760, 0x7eb8, 0x54d0, 0x4d08, 0xcec0, 0xd718,
0xfd70, 0xe4a8, 0xa9a0, 0xb078, 0x9a10, 0x83c8, 0x9591, 0x8c49, 0xa621, 0xbff9,
0xf2f1, 0xeb29, 0xc141, 0xd899, 0x5b51, 0x4289, 0x68e1, 0x7139, 0x3c31, 0x25e9,
0x0f81, 0x1659, 0x2333, 0x3aeb, 0x1083, 0x095b, 0x4453, 0x5d8b, 0x77e3, 0x6e3b,
0xedf3, 0xf42b, 0xde43, 0xc79b, 0x8a93, 0x934b, 0xb923, 0xa0fb, 0xb6a2, 0xaf7a,
0x8512, 0x9cca, 0xd1c2, 0xc81a, 0xe272, 0xfbaa, 0x7862, 0x61ba, 0x4bd2, 0x520a,
0x1f02, 0x06da, 0x2cb2, 0x356a, 0x4666, 0x5fbe, 0x75d6, 0x6c0e, 0x2106, 0x38de,
0x12b6, 0x0b6e, 0x88a6, 0x917e, 0xbb16, 0xa2ce, 0xefc6, 0xf61e, 0xdc76, 0xc5ae,
0xd3f7, 0xca2f, 0xe047, 0xf99f, 0xb497, 0xad4f, 0x8727, 0x9eff, 0x1d37, 0x04ef,
0x2e87, 0x375f, 0x7a57, 0x638f, 0x49e7, 0x503f, 0x6555, 0x7c8d, 0x56e5, 0x4f3d,
0x0235, 0x1bed, 0x3185, 0x285d, 0xab95, 0xb24d, 0x9825, 0x81fd, 0xccf5, 0xd52d,
0xff45, 0xe69d, 0xf0c4, 0xe91c, 0xc374, 0xdaac, 0x97a4, 0x8e7c, 0xa414, 0xbdcc,
0x3e04, 0x27dc, 0x0db4, 0x146c, 0x5964, 0x40bc, 0x6ad4, 0x730c, 0x8ccc, 0x9514,
0xbf7c, 0xa6a4, 0xebac, 0xf274, 0xd81c, 0xc1c4, 0x420c, 0x5bd4, 0x71bc, 0x6864,
0x256c, 0x3cb4, 0x16dc, 0x0f04, 0x195d, 0x0085, 0x2aed, 0x3335, 0x7e3d, 0x67e5,
0x4d8d, 0x5455, 0xd79d, 0xce45, 0xe42d, 0xfdf5, 0xb0fd, 0xa925, 0x834d, 0x9a95,
0xafff, 0xb627, 0x9c4f, 0x8597, 0xc89f, 0xd147, 0xfb2f, 0xe2f7, 0x613f, 0x78e7,
0x528f, 0x4b57, 0x065f, 0x1f87, 0x35ef, 0x2c37, 0x3a6e, 0x23b6, 0x09de, 0x1006,
0x5d0e, 0x44d6, 0x6ebe, 0x7766, 0xf4ae, 0xed76, 0xc71e, 0xdec6, 0x93ce, 0x8a16,
0xa07e, 0xb9a6, 0xcaaa, 0xd372, 0xf91a, 0xe0c2, 0xadca, 0xb412, 0x9e7a, 0x87a2,
0x046a, 0x1db2, 0x37da, 0x2e02, 0x630a, 0x7ad2, 0x50ba, 0x4962, 0x5f3b, 0x46e3,
0x6c8b, 0x7553, 0x385b, 0x2183, 0x0beb, 0x1233, 0x91fb, 0x8823, 0xa24b, 0xbb93,
0xf69b, 0xef43, 0xc52b, 0xdcf3, 0xe999, 0xf041, 0xda29, 0xc3f1, 0x8ef9, 0x9721,
0xbd49, 0xa491, 0x2759, 0x3e81, 0x14e9, 0x0d31, 0x4039, 0x59e1, 0x7389, 0x6a51,
0x7c08, 0x65d0, 0x4fb8, 0x5660, 0x1b68, 0x02b0, 0x28d8, 0x3100, 0xb2c8, 0xab10,
0x8178, 0x98a0, 0xd5a8, 0xcc70, 0xe618, 0xffc0},
{0x0000, 0x5adc, 0xb5b8, 0xef64, 0x6361, 0x39bd, 0xd6d9, 0x8c05, 0xc6c2, 0x9c1e,
0x737a, 0x29a6, 0xa5a3, 0xff7f, 0x101b, 0x4ac7, 0x8595, 0xdf49, 0x302d, 0x6af1,
0xe6f4, 0xbc28, 0x534c, 0x0990, 0x4357, 0x198b, 0xf6ef, 0xac33, 0x2036, 0x7aea,
0x958e, 0xcf52, 0x033b, 0x59e7, 0xb683, 0xec5f, 0x605a, 0x3a86, 0xd5e2, 0x8f3e,
0xc5f9, 0x9f25, 0x7041, 0x2a9d, 0xa698, 0xfc44, 0x1320, 0x49fc, 0x86ae, 0xdc72,
0x3316, 0x69ca, 0xe5cf, 0xbf13, 0x5077, 0x0aab, 0x406c, 0x1ab0, 0xf5d4, 0xaf08,
0x230d, 0x79d1, 0x96b5, 0xcc69, 0x0676, 0x5caa, 0xb3ce, 0xe912, 0x6517, 0x3fcb,
0xd0af, 0x8a73, 0xc0b4, 0x9a68, 0x750c, 0x2fd0, 0xa3d5, 0xf909, 0x166d, 0x4cb1,
0x83e3, 0xd93f, 0x365b, 0x6c87, 0xe082, 0xba5e, 0x553a, 0x0fe6, 0x4521, 0x1ffd,
0xf099, 0xaa45, 0x2640, 0x7c9c, 0x93f8, 0xc924, 0x054d, 0x5f91, 0xb0f5, 0xea29,
0x662c, 0x3cf0, 0xd394, 0x8948, 0xc38f, 0x9953, 0x7637, 0x2ceb, 0xa0ee, 0xfa32,
0x1556, 0x4f8a, 0x80d8, 0xda04, 0x3560, 0x6fbc, 0xe3b9, 0xb965, 0x5601, 0x0cdd,
0x461a, 0x1cc6, 0xf3a2, 0xa97e, 0x257b, 0x7fa7, 0x90c3, 0xca1f, 0x0cec, 0x5630,
0xb954, 0xe388, 0x6f8d, 0x3551, 0xda35, 0x80e9, 0xca2e, 0x90f2, 0x7f96, 0x254a,
0xa94f, 0xf393, 0x1cf7, 0x462b, 0x8979, 0xd3a5, 0x3cc1, 0x661d, 0xea18, 0xb0c4,
0x5fa0, 0x057c, 0x4fbb, 0x1567, 0xfa03, 0xa0df, 0x2cda, 0x7606, 0x9962, 0xc3be,
0x0fd7, 0x550b, 0xba6f, 0xe0b3, 0x6cb6, 0x366a, 0xd90e, 0x83d2, 0xc915, 0x93c9,
0x7cad, 0x2671, 0xaa74, 0xf0a8, 0x1fcc, 0x4510, 0x8a42, 0xd09e, 0x3ffa, 0x6526,
0xe923, 0xb3ff, 0x5c9b, 0x0647, 0x4c80, 0x165c, 0xf938, 0xa3e4, 0x2fe1, 0x753d,
0x9a59, 0xc085, 0x0a9a, 0x5046, 0xbf22, 0xe5fe, 0x69fb, 0x3327, 0xdc43, 0x869f,
0xcc58, 0x9684, 0x79e0, 0x233c, 0xaf39, 0xf5e5, 0x1a81, 0x405d, 0x8f0f, 0xd5d3,
0x3ab7, 0x606b, 0xec6e, 0xb6b2, 0x59d6, 0x030a, 0x49cd, 0x1311, 0xfc75, 0xa6a9,
0x2aac, 0x7070, 0x9f14, 0xc5c8, 0x09a1, 0x537d, 0xbc19, 0xe6c5, 0x6ac0, 0x301c,
0xdf78, 0x85a4, 0xcf63, 0x95bf, 0x7adb, 0x2007, 0xac02, 0xf6de, 0x19ba, 0x4366,
0x8c34, 0xd6e8, 0x398c, 0x6350, 0xef55, 0xb589, 0x5aed, 0x0031, 0x4af6, 0x102a,
0xff4e, 0xa592, 0x2997, 0x734b, 0x9c2f, 0xc6f3},
{0x0000, 0x1cbb, 0x3976, 0x25cd, 0x72ec, 0x6e57, 0x4b9a, 0x5721, 0xe5d8, 0xf963,
0xdcae, 0xc015, 0x9734, 0x8b8f, 0xae42, 0xb2f9, 0xc3a1, 0xdf1a, 0xfad7, 0xe66c,
0xb14d, 0xadf6, 0x883b, 0x9480, 0x2679, 0x3ac2, 0x1f0f, 0x03b4, 0x5495, 0x482e,
0x6de3, 0x7158, 0x8f53, 0x93e8, 0xb625, 0xaa9e, 0xfdbf, 0xe104, 0xc4c9, 0xd872,
0x6a8b, 0x7630, 0x53fd, 0x4f46, 0x1867, 0x04dc, 0x2111, 0x3daa, 0x4cf2, 0x5049,
0x7584, 0x693f, 0x3e1e, 0x22a5, 0x0768, 0x1bd3, 0xa92a, 0xb591, 0x905c, 0x8ce7,
0xdbc6, 0xc77d, 0xe2b0, 0xfe0b, 0x16b7, 0x0a0c, 0x2fc1, 0x337a, 0x645b, 0x78e0,
0x5d2d, 0x4196, 0xf36f, 0xefd4, 0xca19, 0xd6a2, 0x8183, 0x9d38, 0xb8f5, 0xa44e,
0xd516, 0xc9ad, 0xec60, 0xf0db, 0xa7fa, 0xbb41, 0x9e8c, 0x8237, 0x30ce, 0x2c75,
0x09b8, 0x1503, 0x4222, 0x5e99, 0x7b54, 0x67ef, 0x99e4, 0x855f, 0xa092, 0xbc29,
0xeb08, 0xf7b3, 0xd27e, 0xcec5, 0x7c3c, 0x6087, 0x454a, 0x59f1, 0x0ed0, 0x126b,
0x37a6, 0x2b1d, 0x5a45, 0x46fe, 0x6333, 0x7f88, 0x28a9, 0x3412, 0x11df, 0x0d64,
0xbf9d, 0xa326, 0x86eb, 0x9a50, 0xcd71, 0xd1ca, 0xf407, 0xe8bc, 0x2d6e, 0x31d5,
0x1418, 0x08a3, 0x5f82, 0x4339, 0x66f4, 0x7a4f, 0xc8b6, 0xd40d, 0xf1c0, 0xed7b,
0xba5a, 0xa6e1, 0x832c, 0x9f97, 0xeecf, 0xf274, 0xd7b9, 0xcb02, 0x9c23, 0x8098,
0xa555, 0xb9ee, 0x0b17, 0x17ac, 0x3261, 0x2eda, 0x79fb, 0x6540, 0x408d, 0x5c36,
0xa23d, 0xbe86, 0x9b4b, 0x87f0, 0xd0d1, 0xcc6a, 0xe9a7, 0xf51c, 0x47e5, 0x5b5e,
0x7e93, 0x6228, 0x3509, 0x29b2, 0x0c7f, 0x10c4, 0x619c, 0x7d27, 0x58ea, 0x4451,
0x1370, 0x0fcb, 0x2a06, 0x36bd, 0x8444, 0x98ff, 0xbd32, 0xa189, 0xf6a8, 0xea13,
0xcfde, 0xd365, 0x3bd9, 0x2762, 0x02af, 0x1e14, 0x4935, 0x558e, 0x7043, 0x6cf8,
0xde01, 0xc2ba, 0xe777, 0xfbcc, 0xaced, 0xb056, 0x959b, 0x8920, 0xf878, 0xe4c3,
0xc10e, 0xddb5, 0x8a94, 0x962f, 0xb3e2, 0xaf59, 0x1da0, 0x011b, 0x24d6, 0x386d,
0x6f4c, 0x73f7, 0x563a, 0x4a81, 0xb48a, 0xa831, 0x8dfc, 0x9147, 0xc666, 0xdadd,
0xff10, 0xe3ab, 0x5152, 0x4de9, 0x6824, 0x749f, 0x23be, 0x3f05, 0x1ac8, 0x0673,
0x772b, 0x6b90, 0x4e5d, 0x52e6, 0x05c7, 0x197c, 0x3cb1, 0x200a, 0x92f3, 0x8e48,
0xab85, 0xb73e, 0xe01f, 0xfca4, 0xd969, 0xc5d2},
{0x0000, 0x0b44, 0x1688, 0x1dcc, 0x2d10, 0x2654, 0x3b98, 0x30dc, 0x5a20, 0x5164,
0x4ca8, 0x47ec, 0x7730, 0x7c74, 0x61b8, 0x6afc, 0xb440, 0xbf04, 0xa2c8, 0xa98c,
0x9950, 0x9214, 0x8fd8, 0x849c, 0xee60, 0xe524, 0xf8e8, 0xf3ac, 0xc370, 0xc834,
0xd5f8, 0xdebc, 0x6091, 0x6bd5, 0x7619, 0x7d5d, 0x4d81, 0x46c5, 0x5b09, 0x504d,
0x3ab1, 0x31f5, 0x2c39, 0x277d, 0x17a1, 0x1ce5, 0x0129, 0x0a6d, 0xd4d1, 0xdf95,
0xc259, 0xc91d, 0xf9c1, 0xf285, 0xef49, 0xe40d, 0x8ef1, 0x85b5, 0x9879, 0x933d,
0xa3e1, 0xa8a5, 0xb569, 0xbe2d, 0xc122, 0xca66, 0xd7aa, 0xdcee, 0xec32, 0xe776,
0xfaba, 0xf1fe, 0x9b02, 0x9046, 0x8d8a, 0x86ce, 0xb612, 0xbd56, 0xa09a, 0xabde,
0x7562, 0x7e26, 0x63ea, 0x68ae, 0x5872, 0x5336, 0x4efa, 0x45be, 0x2f42, 0x2406,
0x39ca, 0x328e, 0x0252, 0x0916, 0x14da, 0x1f9e, 0xa1b3, 0xaaf7, 0xb73b, 0xbc7f,
0x8ca3, 0x87e7, 0x9a2b, 0x916f, 0xfb93, 0xf0d7, 0xed1b, 0xe65f, 0xd683, 0xddc7,
0xc00b, 0xcb4f, 0x15f3, 0x1eb7, 0x037b, 0x083f, 0x38e3, 0x33a7, 0x2e6b, 0x252f,
0x4fd3, 0x4497, 0x595b, 0x521f, 0x62c3, 0x6987, 0x744b, 0x7f0f, 0x8a55, 0x8111,
0x9cdd, 0x9799, 0xa745, 0xac01, 0xb1cd, 0xba89, 0xd075, 0xdb31, 0xc6fd, 0xcdb9,
0xfd65, 0xf621, 0xebed, 0xe0a9, 0x3e15, 0x3551, 0x289d, 0x23d9, 0x1305, 0x1841,
0x058d, 0x0ec9, 0x6435, 0x6f71, 0x72bd, 0x79f9, 0x4925, 0x4261, 0x5fad, 0x54e9,
0xeac4, 0xe180, 0xfc4c, 0xf708, 0xc7d4, 0xcc90, 0xd15c, 0xda18, 0xb0e4, 0xbba0,
0xa66c, 0xad28, 0x9df4, 0x96b0, 0x8b7c, 0x8038, 0x5e84, 0x55c0, 0x480c, 0x4348,
0x7394, 0x78d0, 0x651c, 0x6e58, 0x04a4, 0x0fe0, 0x122c, 0x1968, 0x29b4, 0x22f0,
0x3f3c, 0x3478, 0x4b77, 0x4033, 0x5dff, 0x56bb, 0x6667, 0x6d23, 0x70ef, 0x7bab,
0x1157, 0x1a13, 0x07df, 0x0c9b, 0x3c47, 0x3703, 0x2acf, 0x218b, 0xff37, 0xf473,
0xe9bf, 0xe2fb, 0xd227, 0xd963, 0xc4af, 0xcfeb, 0xa517, 0xae53, 0xb39f, 0xb8db,
0x8807, 0x8343, 0x9e8f, 0x95cb, 0x2be6, 0x20a2, 0x3d6e, 0x362a, 0x06f6, 0x0db2,
0x107e, 0x1b3a, 0x71c6, 0x7a82, 0x674e, 0x6c0a, 0x5cd6, 0x5792, 0x4a5e, 0x411a,
0x9fa6, 0x94e2, 0x892e, 0x826a, 0xb2b6, 0xb9f2, 0xa43e, 0xaf7a, 0xc586, 0xcec2,
0xd30e, 0xd84a, 0xe896, 0xe3d2, 0xfe1e, 0xf55a},
{0x0000, 0x042b, 0x0856, 0x0c7d, 0x10ac, 0x1487, 0x18fa, 0x1cd1, 0x2158, 0x2573,
0x290e, 0x2d25, 0x31f4, 0x35df, 0x39a2, 0x3d89, 0x42b0, 0x469b, 0x4ae6, 0x4ecd,
0x521c, 0x5637, 0x5a4a, 0x5e61, 0x63e8, 0x67c3, 0x6bbe, 0x6f95, 0x7344, 0x776f,
0x7b12, 0x7f39, 0x8560, 0x814b, 0x8d36, 0x891d, 0x95cc, 0x91e7, 0x9d9a, 0x99b1,
0xa438, 0xa013, 0xac6e, 0xa845, 0xb494, 0xb0bf, 0xbcc2, 0xb8e9, 0xc7d0, 0xc3fb,
0xcf86, 0xcbad, 0xd77c, 0xd357, 0xdf2a, 0xdb01, 0xe688, 0xe2a3, 0xeede, 0xeaf5,
0xf624, 0xf20f, 0xfe72, 0xfa59, 0x02d1, 0x06fa, 0x0a87, 0x0eac, 0x127d, 0x1656,
0x1a2b, 0x1e00, 0x2389, 0x27a2, 0x2bdf, 0x2ff4, 0x3325, 0x370e, 0x3b73, 0x3f58,
0x4061, 0x444a, 0x4837, 0x4c1c, 0x50cd, 0x54e6, 0x589b, 0x5cb0, 0x6139, 0x6512,
0x696f, 0x6d44, 0x7195, 0x75be, 0x79c3, 0x7de8, 0x87b1, 0x839a, 0x8fe7, 0x8bcc,
0x971d, 0x9336, 0x9f4b, 0x9b60, 0xa6e9, 0xa2c2, 0xaebf, 0xaa94, 0xb645, 0xb26e,
0xbe13, 0xba38, 0xc501, 0xc12a, 0xcd57, 0xc97c, 0xd5ad, 0xd186, 0xddfb, 0xd9d0,
0xe459, 0xe072, 0xec0f, 0xe824, 0xf4f5, 0xf0de, 0xfca3, 0xf888, 0x05a2, 0x0189,
0x0df4, 0x09df, 0x150e, 0x1125, 0x1d58, 0x1973, 0x24fa, 0x20d1, 0x2cac, 0x2887,
0x3456, 0x307d, 0x3c00, 0x382b, 0x4712, 0x4339, 0x4f44, 0x4b6f, 0x57be, 0x5395,
0x5fe8, 0x5bc3, 0x664a, 0x6261, 0x6e1c, 0x6a37, 0x76e6, 0x72cd, 0x7eb0, 0x7a9b,
0x80c2, 0x84e9, 0x8894, 0x8cbf, 0x906e, 0x9445, 0x9838, 0x9c13, 0xa19a, 0xa5b1,
0xa9cc, 0xade7, 0xb136, 0xb51d, 0xb960, 0xbd4b, 0xc272, 0xc659, 0xca24, 0xce0f,
0xd2de, 0xd6f5, 0xda88, 0xdea3, 0xe32a, 0xe701, 0xeb7c, 0xef57, 0xf386, 0xf7ad,
0xfbd0, 0xfffb, 0x0773, 0x0358, 0x0f25, 0x0b0e, 0x17df, 0x13f4, 0x1f89, 0x1ba2,
0x262b, 0x2200, 0x2e7d, 0x2a56, 0x3687, 0x32ac, 0x3ed1, 0x3afa, 0x45c3, 0x41e8,
0x4d95, 0x49be, 0x556f, 0x5144, 0x5d39, 0x5912, 0x649b, 0x60b0, 0x6ccd, 0x68e6,
0x7437, 0x701c, 0x7c61, 0x784a, 0x8213, 0x8638, 0x8a45, 0x8e6e, 0x92bf, 0x9694,
0x9ae9, 0x9ec2, 0xa34b, 0xa760, 0xab1d, 0xaf36, 0xb3e7, 0xb7cc, 0xbbb1, 0xbf9a,
0xc0a3, 0xc488, 0xc8f5, 0xccde, 0xd00f, 0xd424, 0xd859, 0xdc72, 0xe1fb, 0xe5d0,
0xe9ad, 0xed86, 0xf157, 0xf57c, 0xf901, 0xfd2a},
{0x0000, 0x9fd5, 0x37bb, 0xa86e, 0x6f76, 0xf0a3, 0x58cd, 0xc718, 0xdeec, 0x4139,
0xe957, 0x7682, 0xb19a, 0x2e4f, 0x8621, 0x19f4, 0xb5c9, 0x2a1c, 0x8272, 0x1da7,
0xdabf, 0x456a, 0xed04, 0x72d1, 0x6b25, 0xf4f0, 0x5c9e, 0xc34b, 0x0453, 0x9b86,
0x33e8, 0xac3d, 0x6383, 0xfc56, 0x5438, 0xcbed, 0x0cf5, 0x9320, 0x3b4e, 0xa49b,
0xbd6f, 0x22ba, 0x8ad4, 0x1501, 0xd219, 0x4dcc, 0xe5a2, 0x7a77, 0xd64a, 0x499f,
0xe1f1, 0x7e24, 0xb93c, 0x26e9, 0x8e87, 0x1152, 0x08a6, 0x9773, 0x3f1d, 0xa0c8,
0x67d0, 0xf805, 0x506b, 0xcfbe, 0xc706, 0x58d3, 0xf0bd, 0x6f68, 0xa870, 0x37a5,
0x9fcb, 0x001e, 0x19ea, 0x863f, 0x2e51, 0xb184, 0x769c, 0xe949, 0x4127, 0xdef2,
0x72cf, 0xed1a, 0x4574, 0xdaa1, 0x1db9, 0x826c, 0x2a02, 0xb5d7, 0xac23, 0x33f6,
0x9b98, 0x044d, 0xc355, 0x5c80, 0xf4ee, 0x6b3b, 0xa485, 0x3b50, 0x933e, 0x0ceb,
0xcbf3, 0x5426, 0xfc48, 0x639d, 0x7a69, 0xe5bc, 0x4dd2, 0xd207, 0x151f, 0x8aca,
0x22a4, 0xbd71, 0x114c, 0x8e99, 0x26f7, 0xb922, 0x7e3a, 0xe1ef, 0x4981, 0xd654,
0xcfa0, 0x5075, 0xf81b, 0x67ce, 0xa0d6, 0x3f03, 0x976d, 0x08b8, 0x861d, 0x19c8,
0xb1a6, 0x2e73, 0xe96b, 0x76be, 0xded0, 0x4105, 0x58f1, 0xc724, 0x6f4a, 0xf09f,
0x3787, 0xa852, 0x003c, 0x9fe9, 0x33d4, 0xac01, 0x046f, 0x9bba, 0x5ca2, 0xc377,
0x6b19, 0xf4cc, 0xed38, 0x72ed, 0xda83, 0x4556, 0x824e, 0x1d9b, 0xb5f5, 0x2a20,
0xe59e, 0x7a4b, 0xd225, 0x4df0, 0x8ae8, 0x153d, 0xbd53, 0x2286, 0x3b72, 0xa4a7,
0x0cc9, 0x931c, 0x5404, 0xcbd1, 0x63bf, 0xfc6a, 0x5057, 0xcf82, 0x67ec, 0xf839,
0x3f21, 0xa0f4, 0x089a, 0x974f, 0x8ebb, 0x116e, 0xb900, 0x26d5, 0xe1cd, 0x7e18,
0xd676, 0x49a3, 0x411b, 0xdece, 0x76a0, 0xe975, 0x2e6d, 0xb1b8, 0x19d6, 0x8603,
0x9ff7, 0x0022, 0xa84c, 0x3799, 0xf081, 0x6f54, 0xc73a, 0x58ef, 0xf4d2, 0x6b07,
0xc369, 0x5cbc, 0x9ba4, 0x0471, 0xac1f, 0x33ca, 0x2a3e, 0xb5eb, 0x1d85, 0x8250,
0x4548, 0xda9d, 0x72f3, 0xed26, 0x2298, 0xbd4d, 0x1523, 0x8af6, 0x4dee, 0xd23b,
0x7a55, 0xe580, 0xfc74, 0x63a1, 0xcbcf, 0x541a, 0x9302, 0x0cd7, 0xa4b9, 0x3b6c,
0x9751, 0x0884, 0xa0ea, 0x3f3f, 0xf827, 0x67f2, 0xcf9c, 0x5049, 0x49bd, 0xd668,
0x7e06, 0xe1d3, 0x26cb, 0xb91e, 0x1170, 0x8ea5},
{0x0000, 0x81bf, 0x0b6f, 0x8ad0, 0x16de, 0x9761, 0x1db1, 0x9c0e, 0x2dbc, 0xac03,
0x26d3, 0xa76c, 0x3b62, 0xbadd, 0x300d, 0xb1b2, 0x5b78, 0xdac7, 0x5017, 0xd1a8,
0x4da6, 0xcc19, 0x46c9, 0xc776, 0x76c4, 0xf77b, 0x7dab, 0xfc14, 0x601a, 0xe1a5,
0x6b75, 0xeaca, 0xb6f0, 0x374f, 0xbd9f, 0x3c20, 0xa02e, 0x2191, 0xab41, 0x2afe,
0x9b4c, 0x1af3, 0x9023, 0x119c, 0x8d92, 0x0c2d, 0x86fd, 0x0742, 0xed88, 0x6c37,
0xe6e7, 0x6758, 0xfb56, 0x7ae9, 0xf039, 0x7186, 0xc034, 0x418b, 0xcb5b, 0x4ae4,
0xd6ea, 0x5755, 0xdd85, 0x5c3a, 0x65f1, 0xe44e, 0x6e9e, 0xef21, 0x732f, 0xf290,
0x7840, 0xf9ff, 0x484d, 0xc9f2, 0x4322, 0xc29d, 0x5e93, 0xdf2c, 0x55fc, 0xd443,
0x3e89, 0xbf36, 0x35e6, 0xb459, 0x2857, 0xa9e8, 0x2338, 0xa287, 0x1335, 0x928a,
0x185a, 0x99e5, 0x05eb, 0x8454, 0x0e84, 0x8f3b, 0xd301, 0x52be, 0xd86e, 0x59d1,
0xc5df, 0x4460, 0xceb0, 0x4f0f, 0xfebd, 0x7f02, 0xf5d2, 0x746d, 0xe863, 0x69dc,
0xe30c, 0x62b3, 0x8879, 0x09c6, 0x8316, 0x02a9, 0x9ea7, 0x1f18, 0x95c8, 0x1477,
0xa5c5, 0x247a, 0xaeaa, 0x2f15, 0xb31b, 0x32a4, 0xb874, 0x39cb, 0xcbe2, 0x4a5d,
0xc08d, 0x4132, 0xdd3c, 0x5c83, 0xd653, 0x57ec, 0xe65e, 0x67e1, 0xed31, 0x6c8e,
0xf080, 0x713f, 0xfbef, 0x7a50, 0x909a, 0x1125, 0x9bf5, 0x1a4a, 0x8644, 0x07fb,
0x8d2b, 0x0c94, 0xbd26, 0x3c99, 0xb649, 0x37f6, 0xabf8, 0x2a47, 0xa097, 0x2128,
0x7d12, 0xfcad, 0x767d, 0xf7c2, 0x6bcc, 0xea73, 0x60a3, 0xe11c, 0x50ae, 0xd111,
0x5bc1, 0xda7e, 0x4670, 0xc7cf, 0x4d1f, 0xcca0, 0x266a, 0xa7d5, 0x2d05, 0xacba,
0x30b4, 0xb10b, 0x3bdb, 0xba64, 0x0bd6, 0x8a69, 0x00b9, 0x8106, 0x1d08, 0x9cb7,
0x1667, 0x97d8, 0xae13, 0x2fac, 0xa57c, 0x24c3, 0xb8cd, 0x3972, 0xb3a2, 0x321d,
0x83af, 0x0210, 0x88c0, 0x097f, 0x9571, 0x14ce, 0x9e1e, 0x1fa1, 0xf56b, 0x74d4,
0xfe04, 0x7fbb, 0xe3b5, 0x620a, 0xe8da, 0x6965, 0xd8d7, 0x5968, 0xd3b8, 0x5207,
0xce09, 0x4fb6, 0xc566, 0x44d9, 0x18e3, 0x995c, 0x138c, 0x9233, 0x0e3d, 0x8f82,
0x0552, 0x84ed, 0x355f, 0xb4e0, 0x3e30, 0xbf8f, 0x2381, 0xa23e, 0x28ee, 0xa951,
0x439b, 0xc224, 0x48f4, 0xc94b, 0x5545, 0xd4fa, 0x5e2a, 0xdf95, 0x6e27, 0xef98,
0x6548, 0xe4f7, 0x78f9, 0xf946, 0x7396, 0xf229}
};
unsigned crc16iso_iec_14443_3_a_byte(unsigned crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0x6363;
crc &= 0xffff;
while (len--)
crc = (crc >> 8) ^
table_byte[(crc ^ *data++) & 0xff];
return crc;
}
// This code assumes that integers are stored little-endian.
unsigned crc16iso_iec_14443_3_a_word(unsigned crc, void const *mem, size_t len) {
unsigned char const *data = mem;
if (data == NULL)
return 0x6363;
crc &= 0xffff;
while (len && ((ptrdiff_t)data & 0x7)) {
crc = (crc >> 8) ^
table_byte[(crc ^ *data++) & 0xff];
len--;
}
if (len >= 8) {
do {
uintmax_t word = crc ^ *(uintmax_t const *)data;
crc = table_word[7][word & 0xff] ^
table_word[6][(word >> 8) & 0xff] ^
table_word[5][(word >> 16) & 0xff] ^
table_word[4][(word >> 24) & 0xff] ^
table_word[3][(word >> 32) & 0xff] ^
table_word[2][(word >> 40) & 0xff] ^
table_word[1][(word >> 48) & 0xff] ^
table_word[0][word >> 56];
data += 8;
len -= 8;
} while (len >= 8);
}
while (len--)
crc = (crc >> 8) ^
table_byte[(crc ^ *data++) & 0xff];
return crc;
}

errors encountered while interfacing eeprom with microcontroller

I am not an expert c programmers and in the c code I m getting these kinds of errors. I got many and tried to sort them out but can not solve these. The code is as follows:
/*
* EEPROM.c
* interfacing microchip 24aa64f IC with atmel sam4e
*/
#include <asf.h>
#include "EEPROM_I2C.h"
#define DEVICE_ADDRESS 0x50 // 7-bit device identifier 0101000, (refer datasheet)
//#define EEPROM_NAME 24AA6F
#define I2C_FAST_MODE_SPEED 400000//TWI_BUS_CLOCK 400KHz
#define TWI_CLK_DIVIDER 2
#define TWI_CLK_DIV_MIN 7
#define TWI_CLK_CALC_ARGU 4
#define TWI_CLK_DIV_MAX 0xFF
/*************************** Main function ******************************/
int eeprom_main( void )
{
struct micro24 ptMicro24 ;
typedef struct twi_options twi_options_t;
typedef struct Twi_registers Twi;
char TxBuffer[128] ;
char RxBuffer[128] ;
int BufferIndex;
unsigned int PageCount;
unsigned int error = 0 ;
unsigned int i;
ptMicro24.PageSize = 32;
ptMicro24.NumOfPage = 128;
ptMicro24.EepromSize = 128*32;
ptMicro24.SlaveAddress = DEVICE_ADDRESS;
ptMicro24.EepromName = 64;
/***************************** CLOCK SETTINGS TO GET 400KHz **********************
* Set the I2C bus speed in conjunction with the clock frequency.
* param p_twi Pointer to a TWI instance.
* return value PASS\Fail New speed setting is accepted\rejected
**********************************************************************************/
uint32_t twi_set_speed(struct Twi_registers *Twi, uint32_t ul_speed, uint32_t ul_mck)
//uint32_t twi_set_speed(Twi *p_twi, uint32_t ul_speed, uint32_t ul_mck)
{
uint32_t ckdiv = 0; //clock divider is used to increase both TWCK high and low periods (16-18)
uint32_t c_lh_div; //CHDIV (0-7) and CLDIV (8-15)
if (ul_speed > I2C_FAST_MODE_SPEED) { //ul_speed is the desired I2C bus speed
return FAIL;
}
c_lh_div = ul_mck / (ul_speed * TWI_CLK_DIVIDER) - TWI_CLK_CALC_ARGU; //ul_mck main clock of the device
/* cldiv must fit in 8 bits, ckdiv must fit in 3 bits */
while ((c_lh_div > TWI_CLK_DIV_MAX) && (ckdiv < TWI_CLK_DIV_MIN))
{
ckdiv++; // Increase clock divider
c_lh_div /= TWI_CLK_DIVIDER; //Divide cldiv value
}
/* set clock waveform generator register */
Twi->TWI_CWGR =
TWI_CWGR_CLDIV(c_lh_div) | TWI_CWGR_CHDIV(c_lh_div) |
TWI_CWGR_CKDIV(ckdiv);
return PASS;
}
/************************************ Initialize TWI master mode ************************
* Set the control register TWI_CR by MSEN and SVDIS
* param p_opt Options for initializing the TWI module
* return TWI_SUCCESS if initialization is complete
* twi_options... structure contains clock speed, master clock, chip and smbus
*****************************************************************************************/
uint32_t twi_master_start(struct Twi_registers *Twi, struct twi_options_t *twi_options_t)
//uint32_t twi_master_start(Twi *p_twi, const twi_options_t *p_opt)
{
uint32_t status = TWI_SUCCESS; // status success return code is 0
// Enable master mode and disable slave mode in TWI_CR
Twi -> TWI_CR_START = TWI_CR_START;
Twi->TWI_CR_MSEN = TWI_CR_MSEN; // Set Master Enable bit
Twi->TWI_CR_SVDIS = TWI_CR_SVDIS; // Set Slave Disable bit
/* Select the speed */
//new//if (twi_set_speed(Twi->TWI_SR, twi_options_t->speed, twi_options_t->master_clk) == FAIL)
//if (twi_set_speed(Twi, twi_options_t->speed, twi_options_t->master_clk) == FAIL)
//{
//status = TWI_INVALID_ARGUMENT; /* The desired speed setting is rejected */
//}
if (twi_options_t->smbus == 0)
{
Twi->TWI_CR_QUICK == 0;
status = TWI_INVALID_ARGUMENT;
}
else
if (twi_options_t->smbus == 1)
{
Twi->TWI_CR_QUICK == 1;
status = TWI_SUCCESS;
}
return status;
}
/***************************** WriteByte Function ********************************
This function uses a two bytes internal address (IADR) along with
Internal word address of eeprom.
Return Value: None
***********************************************************************************/
void WriteByte (struct micro24 *ptMicro24, char Data2Write,
unsigned int Address)
//Data2Write is the data to be written n the eeprom
//struct <micro24 *ptMicro24> : Structure of Microchip 24AA Two-wire Eeprom
//unsigned int Address>: Address where to write
{
unsigned int WordAddress;
unsigned int SlaveAddress;
unsigned char p0=0;
TWI_CR_START ==1;
if (ptMicro24->EepromName == 64 )
{
if ( Address > 0xFFFF)
{
p0 = 1;
/* Mask the 17th bit to get the 16th LSB */
WordAddress = Address & 0xFFFF ;
SlaveAddress = ptMicro24->SlaveAddress + (p0<<16) ;
}
else {
SlaveAddress = ptMicro24->SlaveAddress ;
WordAddress = Address ;
}
}
TWI_CR_STOP ==1;
//TWI_WriteSingleIadr(TWI_IADR_IADR,SlaveAddress, WordAddress,
// TWI_MMR_IADRSZ_2_BYTE, &Data2Write); // declared as extern
// to write to internal address, utilizing internal address and master mode register
//}
/******************** Increase Speed Function *****************************
* TWI is accessed without calling TWI functions
/***************************************************************************/
int NumOfBytes, Count;
int status;
uint32_t Buffer;
/* Enable Master Mode of the TWI */
TWI_CR_MSEN == 1;
// Twi.TWI_CR_MSEN ==1;
//TWI_CR->TWI_CR_MSEN = TWI_CR_MSEN ;
/* Set the TWI Master Mode Register */
Twi->TWI_MMR = (SlaveAddress & (~TWI_MMR_MREAD) | (TWI_MMR_IADRSZ_2_BYTE));
/* Set the internal address to access the wanted page */
Twi -> TWI_IADR = WordAddress ;
/* Wait until TXRDY is high to transmit the next data */
status = TWI_SR_TXRDY;
while (!(status & TWI_SR_TXRDY))
status = TWI_SR_TXRDY;
/* Send the buffer to the page */
for (Count=0; Count < NumOfBytes ;Count++ )
{
Twi ->TWI_THR_TXDATA = Buffer++;
/* Wait until TXRDY is high to transmit the next data */
status = TWI_SR_TXRDY;
while (!(status & TWI_SR_TXRDY))
status = TWI_SR_TXRDY;
}
/* Wait for the Transmit complete is set */
status = TWI_SR_TXCOMP;
while (!(status & TWI_SR_TXCOMP))
status = TWI_SR_TXCOMP;
// add some wait function according to datasheet before sending the next data
// e.g: 10ms
// e.g: WaitMiliSecond (10);
}
/****************************** ReadByte Function **************************
This function uses a two bytes internal address (IADR) along with
Internal word address of eeprom.
Return Value: None
****************************************************************************/
char ReadByte (struct micro24 *ptMicro24,
unsigned int Address) //int Address to read
{
unsigned int WordAddress;
unsigned int SlaveAddress;
char Data2Read ;
unsigned char p0=0;
TWI_CR_START == 1;
//p_twi -> TWI_CR_START = TWI_CR_START;
if (ptMicro24->EepromName == 64)
{
if ( Address > 0xFFFF) {
p0 = 1;
// Mask the 17th bit to get the 16th LSB
WordAddress = Address & 0xFFFF ;
SlaveAddress = ptMicro24->SlaveAddress + (p0<<16) ;
}
else {
SlaveAddress = ptMicro24->SlaveAddress ;
WordAddress = Address ;
}
}
//TWI_ReadSingleIadr(TWI_IADR_IADR,SlaveAddress,WordAddress,
// TWI_MMR_IADRSZ_2_BYTE,&Data2Read);
// declared as extern
// to write to internal address, utilizing internal address and master mode register
return (Data2Read);
}
}
errors are:
(24,19): error: storage size of 'ptMicro24' isn't known
67,5): error: dereferencing pointer to incomplete type
Twi->TWI_CWGR =
error: expected identifier before '(' token
#define TWI_CR_START (0x1u << 0) /**< \brief (TWI_CR) Send a START Condition */
error: expected identifier before '(' token
#define TWI_CR_MSEN (0x1u << 2) /**< \brief (TWI_CR) TWI Master Mode Enabled */
error: expected identifier before '(' token
#define TWI_CR_SVDIS (0x1u << 5) /**< \brief (TWI_CR) TWI Slave Mode Disabled */
error: dereferencing pointer to incomplete type
if (twi_options_t->smbus == 0)
It seems missing the declaration of struct micro24, this may be the cause of first error: error: storage size of 'ptMicro24' isn't known.
The same for declaration of Twi_registers, that is causing other errors.
Either you forgot to declare these structs or to include an header file declaring them.

Combine 2 enums with math operators

I have this enums:
enum bus {
MEDIA_BUS_UNKNOWN,
MEDIA_BUS_VIRTUAL = 1 << 1,
MEDIA_BUS_PCI = 1 << 2,
MEDIA_BUS_USB = 1 << 3,
};
and:
enum bus get_bus( char *sys )
{
FILE *fd;
char file[PATH_MAX];
char s[1024];
if(!strcmp(sys, "/sys/devices/virtual"))
return MEDIA_BUS_VIRTUAL;
snprintf(file, PATH_MAX, "%s/modalias", sys);
fd = fopen(file, "r");
if(!fd)
return MEDIA_BUS_UNKNOWN;
if(!fgets(s, sizeof(s), fd)) {
fclose(fd);
return MEDIA_BUS_UNKNOWN;
}
fclose(fd);
if(!strncmp(s, "pci", 3))
return MEDIA_BUS_PCI;
if(!strncmp(s, "usb", 3))
return MEDIA_BUS_USB;
return MEDIA_BUS_UNKNOWN;
}
I want to create a function to return device(s) with pci or usb bus:
const char *get_device(const enum bus desired_bus)
{
enum bus bus;
...................................................
for( i = 0; i < md->md_size; i++, md_ptr++ ) {
bus = get_bus( md_ptr->sys );
if( ( bus & desired_bus ) == desired_bus )
return md_ptr->node;
}
and call this function to return device(s):
get_device(const enum bus desired_bus)
if request is for devices with pci or usb bus type:
get_device(MEDIA_BUS_PCI | MEDIA_BUS_USB);
It is possible to use math operators for enum?
Sure you can use math operators, but I believe you're looking for bitwise operations, right?. In this case, you enum members values need to be power of two, sou you will be able to do test like this: if(desired_bus & MEDIA_BUS_PCI) if a previously desired_bus |= MEDIA_BUS_PCI was done the if will have MEDIA_BUS_PCI value, so if is true meaning the bit is set.
code example:
enum bus {
MEDIA_BUS_UNKNOWN,
MEDIA_BUS_VIRTUAL = 1 << 1,
MEDIA_BUS_PCI = 1 << 2,
MEDIA_BUS_USB = 1 << 3,
};
/* set flags */
desired_bus |= (MEDIA_BUS_PCI | MEDIA_BUS_USB);
and then:
/* test if flag MEDIA_BUS_PCI was requested.. */
if(desired_bus & MEDIA_BUS_PCI)
In case of it is not set, we get a 0 value that match to our MEDIA_BUS_UNKNOWN value that I think that is a nice to mean error.
EDIT A more complete working C example:
enum bus {
MEDIA_BUS_UNKNOWN,
MEDIA_BUS_VIRTUAL = 1 << 1,
MEDIA_BUS_PCI = 1 << 2,
MEDIA_BUS_USB = 1 << 3,
};
enum bus get_bus( const char *sys );
int main(int argc, char *argv[])
{
const char *sym = argv[1];
enum bus b = get_bus(sym);
if(b & MEDIA_BUS_VIRTUAL)
printf("MEDIA_BUS_VIRTUAL requested\n");
if(b & MEDIA_BUS_USB)
printf("MEDIA_BUS_USB requested\n");
return 0;
}
enum bus get_bus( const char *sys )
{
if(!strcmp("pci", sys))
return MEDIA_BUS_VIRTUAL;
if(!strcmp("usb", sys))
return MEDIA_BUS_USB;
if(!strcmp("pci&usb", sys))
return MEDIA_BUS_VIRTUAL | MEDIA_BUS_USB;
return MEDIA_BUS_UNKNOWN;
}
If you invoke the compiled program with:
a.exe usb: will output:
MEDIA_BUS_USB requested
a.exe "pci&usb" will output:
MEDIA_BUS_VIRTUAL requested
MEDIA_BUS_USB requested
NOTE: You might need to use a type like unsigned instead of enum bus (that highest size is int) to hold a set of enum bus values.
Yes, but for your case, you'll want to make sure that each combination of enum-values is unique, and easily decomposed. To do this, you should make each one a distinct power of two:
enum bus {
MEDIA_BUS_UNKNOWN = 1,
MEDIA_BUS_VIRTUAL = 2,
MEDIA_BUS_PCI = 4,
MEDIA_BUS_USB = 8,
};
(You can then test for a match by writing e.g. desired_bus & MEDIA_BUS_PCI.)
It's a matter of personal taste, but I find using enums to hold bitmasks rather misleading.
I would rather do it with #defines, to be able to define mask combinations easily. For instance:
#define MEDIA_BUS_UNKNOWN 0x00
#define MEDIA_BUS_GPU 0x10
#define MEDIA_BUS_CPU 0x20
#define MEDIA_BUS_VIRTUAL (0x1 | MEDIA_BUS_CPU)
#define MEDIA_BUS_PCI (0x2 | MEDIA_BUS_CPU)
#define MEDIA_BUS_USB (0x3 | MEDIA_BUS_CPU)
#define MEDIA_BUS_AGP (0x4 | MEDIA_BUS_GPU)
#define MEDIA_BUS_PCIE (0x5 | MEDIA_BUS_GPU)
#define MEDIA_BUS_PU_MASK 0x30 // to isolate the PU type
#define MEDIA_BUS_TYPE_MASK 0x0F // to isolate the bus type
typedef int bus_type;
(a rather silly example, but I could not find better without straying too far from the OP's question)

Resources