tags:

views:

248

answers:

5

Hello.

I'm a complete novice in everything except maybe breathing, so sorry if I'm not being clear, but here goes:

I have a function in C which writes bytes to a circuit via an I2C bus, and in the header file it looks like this:

BOOL WINAPI JidaI2CWrite(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes, DWORD dwLen);
  • hJida: Board handle.
  • dwType: Zero-based number of the I2C bus.
  • bAddr: Address of the device on the I2C bus, the full 8 bits as it is written to the bus.
  • pBytes: Pointer to location that contains the bytes.
  • dwLen: Number of bytes to write.

If I wanted to write just one byte to a circuit with the address 0x98, I would do something like this:

unsigned char writing[1];
writing[0]=0x10;

unsigned char *pointer;
pointer = &writing[0];


JidaI2CWrite(hJida,0,0x98,pointer,1);

which seems to work, but if I wanted to write two bytes, say 0x10FF, it doesn't. So how do I make a pointer that points to two bytes instead of just one?

Thanks

+10  A: 

You want something like this:

unsigned char writing[2];
writing[0] = 0x01;
writing[1] = 0x02;

JidaI2CWrite(hJida, 0, 0x98, writing, 2);

Notice that an array in C can be usually be used just like a pointer. The variable writing can be thought of as just a pointer to a chunk of memory that in this case has a size of 2 bytes. Creating another pointer to point to that location is redundant (in this case).

Note you could make it point to any number of bytes:

unsigned char writing[12];

//fill the array with data

JidaI2CWrite(hJida, 0, 0x98, writing, 12);
Gabe
"Notice that arrays in C are actually just pointers" not quite...see "http://www.lysator.liu.se/c/c-faq/c-2.html"
SDX2000
@SDX2000 excellent point and reference, I oversimplified, hopefully my edit is more accurate
Gabe
@SDX2000 That link gives a 404
Edward Amsden
@eamsden if you remove the erroneous double-quotes at the end of the link it works
Gabe
Of course, it's even better to use sizeof, and not repeat the size. The call would then look like JidaI2CWrite(hJida, 0, 0x98, writing, sizeof writing);. You could also use "sizeof writing / sizeof *writing" if you suspect the type of writing is likely to change from a char type.
unwind
+6  A: 

Try this...

//A buffer containing the bytes to be written
unsigned char writeBuffer[] = {0x10, 0xFF}; 

//writeBuffer itself points to the start of the write buffer
//you dont need an extra pointer variable
//Indicate the size of the buffer in the call to the function
//pointers do not carry array size information with them (in C/C++)
JidaI2CWrite(hJida,0,0x98,writeBuffer,2);

or better yet

unsigned char writeBuffer[] = {0x10, 0xFF};

JidaI2CWrite(hJida,0,0x98,writeBuffer
              ,sizeof(writeBuffer)/sizeof(unsigned char));

Note: sizeof(writeBuffer)/sizeof(writeBuffer[0]) automatically calculates the size of the array in bytes for you

SDX2000
dividing by `sizeof(unsigned char)` is pointless, since `sizeof(char)` is defined to be 1 in the standard and `sizeof(unsigned char) == sizeof(char)`
Evan Teran
+1  A: 

It appears as though the dwLen parameter is the number of bytes to write. So:

unsigned char writing[2];
writing[0] = 0x10;
writing[1] = 0xff;
JidaI2CWrite(hJida, 0, 0x98, writing, 2);

Note that your use of pointer pointing to writing[1] probably shouldn't work as written, because that sets pointer to point to the byte after the byte you really want to write. I'm suspecting this is a typo, but if not you may wish to review your existing code before proceeding.

Greg Hewgill
@Greg: it might work or it might not. The point is that the behavior of the program is *undefined* according to the language spec.
Stephen C
@StephenC: "undefined" in what way? Actually accessing Writing[1] may be undefined, but taking it's address should work, surely?
Roddy
A: 

I see 2 choices:

1) write them separately:

writing[0] = 0x10; writing[1] = 0xFF;

2) check if short on your system is 2Bytes and use a short.

probably as ((short*)writing)[0] = 0x10FF;

Also, you need to declaire writing is char writing[2];

and then, as others have said, write the 2 bytes...

Brian Postow
"((short*)writing)[0] = 0x10FF;" is calling for troubles due to endianness issues. e.g. on x86 and sparc it would give different results, and it's a pain to hunt the bugs of such kind.
Andrew Y
having recently done such fixes in some mac code, moving from powerpc to intel, you are very very correct.
Brian Postow
+1  A: 

writing is already the pointer that you want.

Get rid of pointer.

The final parameter to JidaI2CWrite is the number of bytes you want to to write.

The pointer pBytes points to the start of the block you want to write.

Douglas Leeder