|
|
View previous topic :: View next topic |
Author |
Message |
newguy
Joined: 24 Jun 2004 Posts: 1909
|
spi_transfer() question - SOLVED |
Posted: Fri Jun 09, 2023 12:06 pm |
|
|
Normally I'd simply cut code & test on hardware, but my PCB isn't due to arrive for a few days. I'd like to get this code done and move on.
I've never used the relatively new #use spi() implementation; in the past I've always used the old spi_write() and spi_read() functions. On a high level I get how spi_transfer() works but I'm just looking for some clarification.
Compiler version 5.108.
The compiler's EX_SPI.c and the 9356.c driver it employs calls spi_transfer(). In the read_ext_eeprom() function, there is an unsigned int8 array called Data with a size of 3 bytes.
Data is initialized as:
Data[0] = 0x0c;
Data[1] = address; // the address which must be read
Data[2] = 0;
spi_transfer is then called as
spi_transfer(STREAM_SPI_9356, Data, Data, 3);
The function then returns (Data[2]).
I guess I'm going to ask a couple of things. spi_transfer() is "intelligent" enough to start placing the data it reads back starting at offset 2 in the array. Does anyone know if this is related to the data in the array being non-zero? How does it know that only 8 bits are being written for the address and not 2 or 3? Or is this just bad practice and no one should assume that spi_transfer() is intelligent enough to permit the use of the same array for both the written and read data?
Second question. If I'm dealing with an eeprom that is expecting an 8 bit opcode followed by a 16 bit address, would the following be the correct way to read the byte which is stored at that 16 bit address?
Code: | unsigned int8 read_byte_from_eeprom(unsigned int16 address) {
unsigned int8 out_data[4], in_data[4];
out_data[0] = 0x03; // READ opcode
out_data[1] = make8(address, 1);
out_data[2] = make8(address, 0);
// out_data[3] is irrelevant (technically) but I'll ensure it's set anyway
out_data[3] = 0;
// ignore the fact that I'm not pulling /CS low and subsequently restoring it
spi_transfer(EEPROM_STREAM, out_data, in_data, 4);
} |
When spi_transfer() exits, will my read byte be located at in_data[3]?
Last edited by newguy on Wed Jun 14, 2023 10:59 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Jun 10, 2023 2:38 am |
|
|
You need to look at the data sheet, showing how the bytes are positioned
in the 'packet'. It should show a diagram, with the clocks versus what is
sent/received on each.
If it does expect a 32clock transfer, with the incoming data bits ignored
for the last eight clocks, and it generating an output byte on it's SDO
for those eight clocks, then 'yes'. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Wed Jun 14, 2023 11:04 am |
|
|
Confirmed. If you call spi_transfer() in the manner shown in the manual - with two arrays, write[] & read[], read[] will be populated with the expected response beginning at an offset which corresponds to 1 higher than the total bytes written to SPI.
Example: SPI eeprom which expects a 1 byte opcode followed by a 2 byte address. To read 3 bytes from the thing:
write[0] = opcode
write[1] = MSB address
write[2] = LSB address
write[3] = 0
write[4] = 0
write[5] = 0
read[0] = ignore
read[1] = ignore
read[2] = ignore
read[3] = byte 1, retrieved from (address)
read[4] = byte 2, retrieved from (address + 1)
read[5] = byte 3, retrieved from (address + 2) |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|