How to convert a monochrome bmp image file (in my case 16*16 pixels) into binary format? This code reads the bitmap information. I have to store the pixel information into an array & it's not stored properly. I have shared the code
#pragma pack(push, 1)
typedef struct BitMap
{
short Signature;
long Reserved1;
long Reserved2;
long DataOffSet;
long Size;
long Width;
long Height;
short Planes;
short BitsPerPixel;
long Compression;
long SizeImage;
long XPixelsPreMeter;
long YPixelsPreMeter;
long ColorsUsed;
long ColorsImportant;
long data[16];
}BitMap;
#pragma pack(pop)
reading image file:
struct BitMap source_info;
struct Pix source_pix;
FILE *fp;
FILE *Dfp;
Dfp=fopen("filename.bin","wb")
if(!(fp=fopen("filename.bmp","rb")))
{
printf(" can not open file");
exit(-1);
}
fread(&source_info, sizeof(source_info),1,fp);
printf("%d\n",source_info.DataOffSet);
printf("%d\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
fprintf(Dfp,"%d\t",source_info.data[i]);
Observed output using hex editor is
Highlighted data i want to get stored in data array so that i can use it further in the code.
However output in filename.bin is
0 16777215 63 63 63 95 95 95
31 31 31 31 31 31 31 31
I'm new to this field. Can someone help me out where i'm going wrong?
There's actually no problem with the data.
The problem is you're using the wrong way to print them.
Try replacing your code:
printf("%d\n",source_info.DataOffSet);
printf("%d\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
fprintf(Dfp,"%d\t",source_info.data[i]);
with this:
printf("%x\n",source_info.DataOffSet);
printf("%x\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
fprintf(Dfp,"%x\t",source_info.data[i]);
As %d is for signed decimals while %x is for hexadecimals. See the section of The conversion specifier in the manual page of printf
EDITED:
As you've posted your new questions in the comments:
output in hex is 0x00 0xffffff 0x3f 0x3f 0x3f 0x5f 0x5f 0x5f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f Can u explain how the output is getting stored? I'm unable to get the same output – user2967899 7 mins ago
here's my edited answer.
Assumptions: your working platform is just as normal, on which size of short is 2 bytes and of long it's 4.
From definition of struct BitMap we know the field data is at its offset of 0x36. Comparing of the image we know the data shall be (in hexadecimal):
data[0]: 0000 0000
data[1]: ffff ff00
......
Then the result you got seems strange since data[1] is 0x00ffffffff instead of 0xffffff00. However that's correct. This is cause by endianess, for which please read this wiki page first: http://en.wikipedia.org/wiki/Endianness
As the hex-editor represents data in the real order of bytes, and I assume you're working with a little-endian machine (which most PC on this planet has), this order is just reversed of the real order of your data in long:
/* data in C */
unsigned long x = 305419896; /* 305419896 == 0x12345678 */
/* arithmetically the four bytes in x: */
/* 0x12 0x34 0x56 0x78 */
/* the real order to be observed in a hex-editor due to endianess: */
/* 0x78 0x56 0x34 0x12 */
/* so this holds true in C: */
unsigned char *a = &x;
assert(a[0] == 0x78);
assert(a[1] == 0x56);
assert(a[2] == 0x34);
assert(a[3] == 0x12);
Related
I try to create a code that would read data from RFID reader module. In order to do this I need to do CRC16 CCITT calculation.
I have found C source code for the CRC16 checksum calculation in the reader manufacturer application technical datasheet http://www.card-sys.com/manuals/framer_eng.pdf
Unfortunately this is just a part of code not a full working example.
When the RFID reader is put in automatic mode, it automatically sends 11 bytes every time it reads a tag. CRC - this value is calculated using all of the bytes except the last two bytes which are the CRCH (CRC high byte) and CRCL (CRC low byte).
When I read RFID tag from a reader I got 11 bytes transferred... i.e. (hex) 01 0B 03 01 06 87 DB C7 FF E5 68. Last two bytes E5 68 are the CRC16 checksum for the message. In order to confirm the data is OK I need to calculate the same CRC16 against 01 0B 03 01 06 87 DB C7 FF at the destination point.
I tried putting everything together in one piece, but I do not have much experience with C programing and my code does not work.
Here is the source code:
#include <stdio.h>
#include <stdlib.h>
// CRC16 from Netronix datasheet
void CRC16(unsigned char * Data, unsigned short * CRC, unsigned char Bytes)
{
int i, byte;
unsigned short C;
*CRC = 0;
for (byte = 1; byte <= Bytes; byte ++, Data ++)
{
C = ((*CRC >> 8) ^ *Data) << 8;
for (i = 0; i < 8; i ++)
{
if (C & 0x8000)
C = (C << 1) ^ 0x1021;
else
C = C << 1;
}
*CRC = C ^ (*CRC << 8);
}
}
int main(void)
{
puts("Test...");
unsigned char * Data16="10ac0501ff";
unsigned short * CRC=0;
unsigned char Bytes16=4;
CRC16(Data16,CRC,Bytes16);
puts(CRC);
return EXIT_SUCCESS;
}
What I would like to do is learn how to use manufacturer code in working example - means how to get crc16 calculated.
Could you please help me with this? Thanks.
Using your source code I created the following program.
#include <stdio.h>
#include <stdlib.h>
// CRC16 from Netronix datasheet
void CRC16(unsigned char * Data, unsigned short * CRC, unsigned char Bytes)
{
int i, byte;
unsigned short C;
*CRC = 0;
for (byte = 1; byte <= Bytes; byte++, Data++)
{
C = ((*CRC >> 8) ^ *Data) << 8;
for (i = 0; i < 8; i++)
{
if (C & 0x8000)
C = (C << 1) ^ 0x1021;
else
C = C << 1;
}
*CRC = C ^ (*CRC << 8);
}
}
int main(void)
{
// When I read RFID tag from a reader I got 11 bytes transferred... i.e.
// (hex)01 0B 03 01 06 87 DB C7 FF E5 68.
// Last two bytes E5 68 are crc16.
// In order to confirm the data is OK I need to calculate the same crc16
// against 01 0B 03 01 06 87 DB C7 FF at the destination point.
unsigned char Data16[] = { 0x01, 0x0B, 0x03, 0x01, 0x06, 0x87, 0xDB, 0xC7, 0xFF };
unsigned short CRC = 0;
unsigned char Bytes16 = 9;
CRC16(Data16, &CRC, Bytes16);
printf(" CRC calculated is %x\n", CRC);
return EXIT_SUCCESS;
}
The output is CRC calculated is e568.
There are a couple of changes I made.
First is the data I used which is from your comment on the RFID tag reader output.
When I read RFID tag from a reader I got 11 bytes transferred... i.e.
(hex) 01 0B 03 01 06 87 DB C7 FF E5 68. Last two bytes E5 68 are
crc16. In order to confirm the data is OK I need to calculate the same
crc16 against 01 0B 03 01 06 87 DB C7 FF at the destination point. You
are probably right about the Data16[]... I will change this later
today and let you know what current status is. Thanks for helping :)
I used a length of the data that excludes the checksum. So the length in the frame data is 0x0B or 11 and since the checksum is 2 bytes, I used 11 - 2 or 9 for the length.
Finally I changed the definition of the variable CRC to unsigned short CRC = 0; and when calling the CRC function, I used the address of operator as in CRC16(Data16, &CRC, Bytes16);.
Frame format for serial transmission
From the documentation you referenced there are two types of frames or messages whose formats are as follows:
Command frame:
module address (1 byte) unique address of each module in network
frame length (1 byte) full length of frame (includes 2 byte checksum)
command (1 byte) command code which is an even value
parameters (variable length) optional parameters depending on command
CRCH (1 byte) upper byte of the CRC16
CRCL (1 byte) lower byte of the CRC16
Answer frame:
module address (1 byte) unique address of each module in network
frame length (1 byte) full length of frame (includes 2 byte checksum)
answer(1 byte) answer code which is an odd value
parameters (variable length) optional parameters depending on command
operation code (1 byte) command execution status
CRCH (1 byte) upper byte of the CRC16
CRCL (1 byte) lower byte of the CRC16
I have a sensor in which I wish to get some data from. I want to ask it the date or ask it for data.
The sensor uses RS-232; 9600 8N1 to communicate.
The communication packet is composed with a header, payload and CRC. The manual provides the header and payload for whatever you want to do. Each communication packet is composed as follows:
<SOH> header <STX> payload <ETB> CRC16 <ETX>
<SOH>: 0x01
<STX>: 0x02
<ETB>: 0x17
<ETX>: 0X03
The manual gives an example if you want to ask for the date, it tells you the header is 0x31 and the payload is 0x41.
Thus the command to send the sensor is: \x01\x31\x02\x41\x17\CRC16\x03
Now as an example, the manual also calculates the CRC16 for you, and is A0D5 in ASCII. CRC16 needs to be transmitted little endian.
So the full command is now:
\x01\x31\x02\x41\x17\x44\x35\x41\x30\x03
The manual doesn't provide any other CRC16 calculations, and it expects the user to do it which is fine :)
From the manual: Each packet is validated by a 16-bit CRC transferred in hexademiical ASCII coded (four chars). CRC is calculated from the header+payload concatenated
WORD CRC16_Compute( BYTE *pBuffer, WORD length )
{
BYTE i;
BOOL bs;
WORD crc=0;
while( length-- )
{
crc ^= *pBuffer++;
for( i = 0; i < 8; i++ )
{
bs = crc & 1;
crc >>= 1;
if( bs )
{
crc ^= 0xA001;
}
}
}
return crc;
}
That is the CRC calculator in C, I am not too savvy with but this code snippet is all they provide and no context.
In ASCII, they are using 1+A (0x31+0x41) to get 2 byte, A0D5. Could someone explain to me what the CRC code is doing, thanks!
#include <stdio.h>
typedef unsigned char BYTE;
typedef unsigned int BOOL;
typedef unsigned int WORD;
WORD CRC16_Compute( BYTE *pBuffer, WORD length )
{
BYTE i;
BOOL bs;
WORD crc=0;
while( length-- )
{
crc ^= *pBuffer++;
for( i = 0; i < 8; i++ )
{
bs = crc & 1;
crc >>= 1;
if( bs )
{
crc ^= 0xA001;
}
}
}
return crc;
}
int main ( void )
{
unsigned char data[2];
unsigned char sdata[9];
unsigned int x;
unsigned int z;
unsigned int i;
data[0]=0x31;
data[1]=0x41;
x = CRC16_Compute(data,2);
x&=0xFFFF;
printf("0x%X\n",x);
z=0;
sdata[z++]=0x01;
sdata[z++]=data[0];
sdata[z++]=0x02;
sdata[z++]=data[1];
sdata[z++]=0x17;
sdata[z ]=((x>> 4)&0xF)+0x30; if(sdata[4]>0x39) sdata[4]+=7; z++;
sdata[z ]=((x>> 0)&0xF)+0x30; if(sdata[5]>0x39) sdata[5]+=7; z++;
sdata[z ]=((x>>12)&0xF)+0x30; if(sdata[6]>0x39) sdata[6]+=7; z++;
sdata[z ]=((x>> 8)&0xF)+0x30; if(sdata[7]>0x39) sdata[7]+=7; z++;
sdata[z++]=0x03;
for(i=0;i<z;i++) printf("%02X ",sdata[i]); printf("\n");
return(0);
}
Run it
gcc so.c -o so
./so
0xA0D5
01 31 02 41 17 44 35 41 30 03
How about that the right answer....
Everything you need to know is in your question, just do what it says. A few minutes of crudely putting it together.
CRC is calculated from the header+payload concatenated
data[0]=0x31;
data[1]=0x41;
That is header and payload and it gives the right answer based on the CRC code provided.
Then you build the packet with the other items. If you google ASCII table you can see the values for 'D' 'A' '0' '5' and can figure out how to get from 0xD to 0x44 and 0xA to 0x41 but first look at 0x0 to 0x30 and 0x5 to 0x35, 0-9 is easy but 0x0A gives 0x3A but needs to be 0x41, so you adjust.
So the code works as described based on the comments as described, I don't know this sensor, seems goofy the way they did it but good for them for providing an example and the details on the crc16 as there are multiple standard variations including the initial value, so again good for them for saving tons of time trying to figure it out...
I want to read a specific 128 bit value in memory that equals the following:
128 bit val = 0171EC07F2E6C383FFFFFFFFFFFFFFFF
This id is visible when flashing a binary
Read Intel HEX application image with 608 bytes.
Received autobaud response:
Product ID: xxxxxx
Revision: xxx
Serial number: 0171EC07F2E6C383FFFFFFFFFFFFFFFF
User code present.
User code checksum failed.
Write protection disabled.
Read protection disabled.
Download completed.
Run command sent.
Programming flash image.
Read Intel HEX flash image with 189248 bytes.
Autobaud succeeded.
Flash completed.
This is the code I am using to read that address
uint8_t *address = (uint8_t *)0x34576;
uint8_t reg[16] = {0};
for (int i = 0; i < 16; i++) {
reg[i] = *address;
printf("reg[%d]= 0x%x\r\n", i, reg[i]);
*address++;
}
This is the output I'm getting:
reg[0]= 0x10
reg[1]= 0x17
reg[2]= 0xce
reg[3]= 0x70
reg[4]= 0x2f
reg[5]= 0x6e
reg[6]= 0x3c
reg[7]= 0x38
reg[8]= 0xff
reg[9]= 0xff
reg[10]= 0xff
reg[11]= 0xff
reg[12]= 0xff
reg[13]= 0xff
reg[14]= 0xff
reg[15]= 0xff
As can be seen from the output the byte order is mixed up. Is this because of little/big endian. How do I convert the value to be equal to 128 bit val
I am working on a Motorola HCS08 µCU in CodeWarrior V10.6, I am trying to create an extern bitfield which has bits from existing registers. The way the bitfields are created in the µCU header is like
typedef unsigned char byte;
typedef union {
byte Byte;
struct {
byte PTAD0 :1;
byte PTAD1 :1;
byte PTAD2 :1;
byte PTAD3 :1;
byte PTAD4 :1;
byte PTAD5 :1;
byte PTAD6 :1;
byte PTAD7 :1;
} Bits;
} PTADSTR;
extern volatile PTADSTR _PTAD #0x00000000;
#define PTAD _PTAD.Byte
#define PTAD_PTAD0 _PTAD.Bits.PTAD0
#define PTAD_PTAD1 _PTAD.Bits.PTAD1
#define PTAD_PTAD2 _PTAD.Bits.PTAD2
#define PTAD_PTAD3 _PTAD.Bits.PTAD3
#define PTAD_PTAD4 _PTAD.Bits.PTAD4
#define PTAD_PTAD5 _PTAD.Bits.PTAD5
#define PTAD_PTAD6 _PTAD.Bits.PTAD6
#define PTAD_PTAD7 _PTAD.Bits.PTAD7
Which will let the register value be changed either by PTAD = 0x01, or PTAD_PTAD0 = 1, for example. This definition is basically the same for PTAD, PTBD, PTCD, ... PTGD, the only thing changing is the address.
My attemp to create a custom bitfield out of the previous existing variables is
typedef union {
byte Byte;
struct {
byte *DB0;
byte *DB1;
byte *DB2;
byte *DB3;
byte *DB4;
byte *DB5;
byte *DB6;
byte *DB7;
} Bits;
} LCDDSTR;
I would create and initialize the bitfield as LCDDSTR lcd = {{&PTGD_PTGD6, &PTBD_PTBD5, ...}}, because by some reason, the initialization like LCDSTR lcd = {*.Bits.DB0 = &PTGD_PTGD6, *.Bits.DB1 = &PTBD_PTBD5, ...} (treating it as a struct, please correct me again) advice in How to initialize a struct in accordance with C programming language standards does not work with this compiler (it does work on an online compiler).
However, as you may see I am sort of grouping the bits, and (if it would work) I would be able to change the values of the actual register by doing *lcd.Bits.DB0 = 1, or something like that, but if I do lcd.Byte = 0x00, I would be changing the last (I think) byte of the memory address contained in lcd.Bits.DB0, you know, because the struct doesn't actually contains the data, but the pointers instead.
How would I go on achieving a struct that is able to contain and modify bits from several registers? (I guess the problem here is that in memory the bits are not one next to the other, which I guess would make it easier). Is it even possible? I hope it is.
How would I go on achieving a struct that is able to contain and modify bits from several registers? (I guess the problem here is that in memory the bits are not one next to the other..
I don't think you can do it with a struct. That is because bitfields by definition have to occupy the same or contiguous addresses.
However macros may be useful here
#define DB0 PTGD_PTGD6
#define DB1 PTBD_PTBD5
....
And to clear the bits to all 0's or set to all 1's you can use a multiline macro
#define SET_DB(x) do { \
PTGD_PTGD6 = x; \
PTBD_PTBD5 = x; \
...... \
} while(0)
How would I go on achieving a struct that is able to contain and modify bits from several registers?
You can't.
A structure must represent a single, continuous block of memory -- otherwise, operations like taking the sizeof the structure, or performing operations on a pointer to one would make no sense.
If you want to permute the bits of a value, you will need to find some way of doing so explicitly. If the order of your bits is relatively simple, this may be possible with a few bitwise operations; if it's weirder, you may need to use a lookup table.
Beyond that: bitfields in C are pretty limited. The language does not make a lot of guarantees about how a structure containing bitfields will end up laid out in memory; they are generally best avoided for portable code. (Which doesn't apply here, as you're writing code for a specific compiler/microcontroller combination, but it's worth keeping in mind in general.)
Your union does unfortunately not make any sense, because it forms a union of one byte and 8 byte*. Since a pointer is 16 bit on HCS08, this ends up as 8*2 = 16 bytes of data, which can't be used in any meaningful way.
Please note that the C structure called bit-fields is very poorly specified by the standard and therefore should be avoided in any program. See this.
Please note that the Codewarrior register maps aren't remotely close to following the C standard (nor MISRA-C).
Please note that structs in general are problematic for hardware register mapping, since structs can contain padding. You don't have that problem on HCS08 specifically, since it doesn't require alignment of data. But most MCUs do require that.
It is therefore better to roll out your own register map in standard C if you have that option. The port A data register could simply be defined like this:
#define PTAD (*(volatile uint8_t*)0x0000U)
#define PTAD7 (1U << 7)
#define PTAD6 (1U << 6)
#define PTAD5 (1U << 5)
#define PTAD4 (1U << 4)
#define PTAD3 (1U << 3)
#define PTAD2 (1U << 2)
#define PTAD1 (1U << 1)
#define PTAD0 (1U << 0)
As we can tell, defining the bit masks is mostly superfluous anyway, as PTAD |= 1 << 7; is equally readable to PTAD |= PTAD7;. This is because this was a pure I/O port. Defining textual bit masks for status and control registers on the other hand, increases the readability of the code significantly.
If you want to modify bits from several registers, you'd do something like the following:
Assume we have a RGB (red-green-blue) LED, common cathode, with 3 colors connected to 3 different pins on 3 different ports. Instead of beating up the PCB designer, you could do this:
#define RGB_RED_PTD PTAD
#define RGB_RED_PTDD PTADD
...
#define RGB_BLUE_PTD PTBD
#define RGB_BLUE_PTDD PTBDD
...
#define RGB_GREEN_PTD PTDD
#define RGB_GREEN PTDD PTDDD
#define RGB_RED_PIN 1
#define RGB_BLUE_PIN 5
#define RGB_GREEN_PIN 3
You can now set these independently of where they happen to be located on the hardware:
void rgb_init (void)
{
RGB_RED_PTDD |= (1 << RGB_RED_PIN);
RGB_BLUE_PTDD |= (1 << RGB_BLUE_PIN);
RGB_GREEN_PTDD |= (1 << RGB_GREEN_PIN);
}
void rgb_yellow (void)
{
RGB_RED_PTD |= (1 << RGB_RED_PIN);
RGB_BLUE_PTD &= ~(1 << RGB_BLUE_PIN);
RGB_GREEN_PTD |= (1 << RGB_GREEN_PIN);
}
And so on. Examples were for HCS08 but the same can of course be used universally on any MCU with direct port I/O.
It sounds like an approach such as the following is along the lines of where you would like to go with a solution.
I have not tested this as I do not have the hardware however this should provide an alternative to look at.
This assumes that you want to turn on particular pins or turn off particular pins but there will not be a case where you will want to turn on some pins and turn off other pins for a particular device in a single operation. If that should be the case I would consider making the type of RegPinNo be an unsigned short to include an op code for each register/pin number combination.
This also assumes that timing of operations is not a critical constraint and that the hardware has sufficient horsepower such that small loops are not much of a burden on throughput and hogging CPU time needed for other things. So this code may need changes to improve optimization if that is a consideration.
I assume that you want some kind of a easily readable way of expressing a command that will turn on and off a series of bits scattered across several areas of memory.
The first thing is to come up with a representation of what such a command would look like and it seems to me that borrowing from a char array to represent a string would suffice.
typedef byte RegPinNo; // upper nibble indicates register number 0 - 7, lower nibble indicates pin number 0 - 7
const byte REGPINNOEOS = 0xff; // the end of string for a RegPinNo array.
And these would be used to define an array of register/pin numbers as in the following.
RegPinNo myLed[] = { 0x01, 0x12, REGPINNOEOS }; // LED is addressed through Register 0, Pin 0 and Register 1, Pin 1 (zero based)
So at this point we have a way to describe that a particular device, an LED in this case, is addressed through a series of register/pin number items.
Next lets create a small library of functions that will use this representation to actually modify the specific pins in specific registers by traversing this array of register/pin numbers and performing an operation on it such as setting the bit in the register or clearing the bit in the register.
typedef unsigned char byte;
typedef union {
byte Byte;
struct {
byte PTAD0 : 1;
byte PTAD1 : 1;
byte PTAD2 : 1;
byte PTAD3 : 1;
byte PTAD4 : 1;
byte PTAD5 : 1;
byte PTAD6 : 1;
byte PTAD7 : 1;
} Bits;
} PTADSTR;
// Define a pointer to the beginning of the register area. This area is composed of
// 8 different registers each of which is one byte in size.
// We will address these registers as Register 0, Register 1, ... Register 7 which just happens
// to be how C does its zero based indexing.
// The bits representing pins on the PCB we will address as Pin 0, Pin 1, ... Pin 7.
extern volatile PTADSTR (* const _PTAD) = 0x00000000;
void SetRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte |= pins[bPinNo];
}
}
void ClearRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte &= ~pins[bPinNo];
}
}
void ToggleRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte ^= pins[bPinNo];
}
}
You would use the above something like the following. Not sure what a time delay function would look like in your environment so I am using a function Sleep() which takes an argument as to the number of milliseconds to delay or sleep.
void LightLed (int nMilliSeconds)
{
RegPinNo myLed[] = { 0x01, 0x12, REGPINNOEOS }; // LED is addressed through Register 0, Pin 0 and Register 1, Pin 1 (zero based)
SetRegPins(myLed); // turn on the LED
Sleep(nMilliSeconds); // delay for a time with the LED lit
ClearRegPins(myLed); // turn the LED back off
}
Edit - A Refinement
A more efficient implementation that would allow multiple pins to be set in a particular register at the same time would be to define the use of RegPinNo as being an unsigned short` with the upper byte being the register number and the lower byte being the pins to manipulate as a bit mask for the byte.
With this approach you would have a SetRegPins() function that would look like the following. A similar change would be needed for the other functions.
void SetRegPins(RegPinNo *x)
{
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 8) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0xFF; // get the pin mask
_PTAD[bRegNo].Byte |= bPinNo;
}
}
And the typedefs would look like:
typedef unsigned short RegPinNo; // upper byte indicates register number 0 - 7, lower byte provides pin mask
const byte REGPINNOEOS = 0xffff; // the end of string for a RegPinNo array.
And these elements would be used like:
void LightLed (int nMilliSeconds)
{
RegPinNo myLed[] = { 0x0002, 0x0103, REGPINNOEOS }; // LED is addressed through Register 0, Pin 1 and Register 1, Pin 0 and Pin 1 (zero based)
SetRegPins(myLed); // turn on the LED
Sleep(nMilliSeconds); // delay for a time with the LED lit
ClearRegPins(myLed); // turn the LED back off
}
First, I'm a student still. So I am not very experienced.
I'm working with a piece of bluetooth hardware and I am using its protocol to send it commands. The protocol requires packets to be sent with LSB first for each packet field.
I was getting error packets back to me indicating my CRC values were wrong so I did some investigating. I found the problem, but I became confused in the process.
Here is Some GDB output and other information elucidating my confusion.
I'm sending a packet that should look like this:
|Start Flag| Packet Num | Command | Payload | CRC | End Flag|
0xfc 0x1 0x0 0x8 0x0 0x5 0x59 0x42 0xfd
Here is some GDB output:
print /x reqId_ep
$1 = {start_flag = 0xfc, data = {packet_num = 0x1, command = {0x0, 0x8}, payload = {
0x0, 0x5}}, crc = 0x5942, end_flag = 0xfd}
reqId_ep is the variable name of the packet I'm sending. It looks all good there, but I am receiving the CRC error codes from it so something must be wrong.
Here I examine 9 bytes in hex starting from the address of my packet to send:
x/9bx 0x7fffffffdee0
0xfc 0x01 0x00 0x08 0x00 0x05 0x42 0x59 0xfd
And here the problem becomes apparent. The CRC is not LSB first. (0x42 0x59)
To fix my problem I removed the htons() that I set my CRC value equal with.
And here is the same output above without htons():
p/x reqId_ep
$1 = {start_flag = 0xfc, data = {packet_num = 0x1, command = {0x0, 0x8}, payload = {
0x0, 0x5}}, crc = 0x4259, end_flag = 0xfd}
Here the CRC value is not LSB.
But then:
x/9bx 0x7fffffffdee0
0xfc 0x01 0x00 0x08 0x00 0x05 0x59 0x42 0xfd
Here the CRC value is LSB first.
So apparently the storing of C is LSB first? Can someone please cast a light of knowledge upon me for this situation? Thank you kindly.
This has to do with Endianness in computing:
http://en.wikipedia.org/wiki/Endianness#Endianness_and_operating_systems_on_architectures
For example, the value 4660 (base-ten) is 0x1234 in hex. On a Big Endian system, it would be stored in memory as 1234 while on a Little Endian system it would be stored as 3412
If you want to avoid this sort of issue in the future, it might just be easiest to create a large array or struct of unsigned char, and store individual values in it.
eg:
|Start Flag| Packet Num | Command | Payload | CRC | End Flag|
0xfc 0x1 0x0 0x8 0x0 0x5 0x59 0x42 0xfd
typedef struct packet {
unsigned char startFlag;
unsigned char packetNum;
unsigned char commandMSB;
unsigned char commandLSB;
unsigned char payloadMSB;
unsigned char payloadLSB;
unsigned char crcMSB;
unsigned char crcLSB;
unsigned char endFlag;
} packet_t;
You could then create a function that you compile differently based on the type of system you are building for using preprocessor macros.
eg:
/* Uncomment the line below if you are using a little endian system;
/* otherwise, leave it commented
*/
//#define LITTLE_ENDIAN_SYSTEM
// Function protocol
void writeCommand(int cmd);
//Function definition
void writeCommand(int cmd, packet_t* pkt)
{
if(!pkt)
{
printf("Error, invalid pointer!");
return;
}
#if LITTLE_ENDIAN_SYSTEM
pkt->commandMSB = (cmd && 0xFF00) >> 8;
pkt->commandLSB = (cmd && 0x00FF);
# else // Big Endian system
pkt->commandMSB = (cmd && 0x00FF);
pkt->commandLSB = (cmd && 0xFF00) >> 8;
#endif
// Done
}
int main void()
{
packet_t myPacket = {0}; //Initialize so it is zeroed out
writeCommand(0x1234,&myPacket);
return 0;
}
One final note: avoid sending structs as a stream of data, send it's individual elements one-at-a-time instead! ie: don't assume that the struct is stored internally in this case like a giant array of unsigned characters. There are things that the compiler and system put in place like packing and allignment, and the struct could actually be larger than 9 x sizeof(unsigned char).
Good luck!
This is architecture dependent based on which processor you're targeting. There are what is known as "Big Endian" systems, which store the most significant byte of a word first, and "Little Endian" systems that store the least significant byte first. It looks like you're looking at a Little Endian system there.