View previous topic :: View next topic |
Author |
Message |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
Pointer Assistance |
Posted: Wed Mar 14, 2007 11:36 am |
|
|
Hello All,
I'm trying to write a driver for the FM25L256. I would like to take advantage of the ability to sequentially write and read from the part. I'm using UNITRANT's I2C code as a go-by, but I would like to be able to read and write int16's. Could somebody give me a reading on the following and see if it makes sense. This is what I'd like to do....
Pass the starting address where the data is to be written, a pointer to where the data is to come from, and the total number of bytes to be written.
Can I pass the function a pointer to an array of int16 values and just double the count? In other words, the total number of bytes to be written would be 2 * the total int16 values in the array.
So really the pointer that is passed is just the address of the first byte of the array, I can do anything I want after that with pointer math?
Code: |
void write_seq_fram(int16 start_addr, int8 *pntr, int16 count)
{
if(start_addr + count <= FRAM_SIZE)
{
setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_1);
output_low(FRAM_CS); //select FRAM
spi_write(WREN); //enable writes, required prior to WRITE cmd
output_high(FRAM_CS); //de-select FRAM, required between each op-code
delay_cycles(1); //ensure compiler doesn't remove the pin toggle
output_low(FRAM_CS); //re-select the FRAM
spi_write(WRITE); // send the WRITE op-code
spi_write(start_addr>>8); //send the high byte of the address
spi_write(start_addr); //send the low byte of the address
do
{
//restart_wdt(); //uncomment if slow speeds
spi_write(*pntr++);
} while(--count);
output_high(FRAM_CS); //de-select FRAM
}
}
|
Thanks,
John |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Mar 14, 2007 6:34 pm |
|
|
OK. So I'm trying to blunder my way through this and my understanding of pointers is causing major headaches. I have the following test function that I can get to work just fine in one circumstance, but when I use pointers in one part of it I get an odd result....
Code: |
void fram_test(void)
{
int16 i;
int8 result[256];
int8 *pntr = result;
int16 start_addr = 0;
//preload the array to write to FRAM
for(i = 0; i < 256; i++)
{
result[i] = i;
}
setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_4);
fprintf(XBEE,"SPI set-up complete\n\r");
output_low(FRAM_CS); //select FRAM
spi_write(WREN); //enable writes, required prior to WRITE cmd
output_high(FRAM_CS); //de-select FRAM, required between each op-code
fprintf(XBEE,"FRAM WREN complete\n\r");
output_low(FRAM_CS); //re-select the FRAM
spi_write(WRITE); // send the WRITE op-code
spi_write(start_addr>>8); //send the high byte of the address
spi_write(start_addr); //send the low byte of the address
for(i = 0; i < 256; i++)
{
spi_write(*pntr++);
}
output_high(FRAM_CS); //de-select FRAM
fprintf(XBEE,"FRAM write complete\n\r");
//clear the holding array prior to reading from FRAM
for(i = 0; i < 256; i++)
{
result[i] = 0;
}
output_low(FRAM_CS); //re-select the FRAM
spi_write(READ); // send the WRITE op-code
spi_write(start_addr>>8); //send the high byte of the address
spi_write(start_addr); //send the low byte of the address
//read from FRAM and put in holding array
for(i = 0; i < 256; i++)
{
*pntr++ = spi_read(0); //ODD OUTPUT, SEE BELOW
//result[i] = spi_read(0); //This one Works!
}
output_high(FRAM_CS); //de-select FRAM
for(i = 0; i < 255; i++)
{
fprintf(XBEE,"%u\n\r", result[i]);
}
}
|
The odd output is this....
Code: |
0
0
.
. (I suspect 129 or so zeroes?)
.
0
0
1
2
3
.
. (sequential from 0 to 126)
.
125
126
|
Any help or pointers would be greatly appreciated,
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 14, 2007 7:00 pm |
|
|
You're using 'pntr' in two places in your routine, but you only
initialize it at the start of the routine. It's not initialized prior
to the 2nd usage. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Mar 14, 2007 7:23 pm |
|
|
PCM,
Thanks for looking. I caught that and i is an int16. I've fixed both of those but still get the same result. I re-initialize pntr before I re-use it with:
But I still get the same results.
When I changed i to an int8 I also changed all of the for loops to i < 255 so they wouldn't infinite loop.
Any other ideas?
Thanks for the help, I'm running out of places to look.
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 14, 2007 7:29 pm |
|
|
That's not correct.
To set the pointer to the address of the array, you do this:
In my opinion, it's better not to initialize pointers in the declaration
statement. Do it with an explicit line of code, every time you're
going to use the pointer. Then you won't run into this type of problem. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Mar 14, 2007 7:38 pm |
|
|
Arghhhhhhhh....
OK. It works when I do that. But why, when you initialize pntr is it done with the *?
I think I just figured it out as I was typing the question. In the
Code: |
int8 *pntr = result;
|
statement, the * is actually part of the declaration, not the initialization?
So the correct way to break that line into two lines would be to...
Code: |
int8 *pntr;
pntr = result;
|
No?
Thanks for helping with something that should have been obvious.
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 14, 2007 8:12 pm |
|
|
The '*' has two meanings. When it's used in a declaration, it means
that you're declaring a pointer. When it's used in a statement, it
means to access the contents of the address pointed to by the pointer.
Or, in C jargon, it means to "dereference" the pointer.
You can initialize the pointer in the declaration in the way that you
did it. It's just that for me, I don't think it's a safe way to do it,
in terms of being careful in your coding practices. In other words,
because you had the initialization up in the declarations, you overlooked
that it had to be initialized again later in the code. If you had explicitly
initialized it in the code (as you did in your latest post), then it would
have been more obvious that you needed to do it again for the 2nd
loop. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Mar 14, 2007 8:41 pm |
|
|
Thanks a bunch. That makes all the sense in the world.
John |
|
|
|