Hello Tomahawk,
Firstly, there seems to be a little confusion with the SPI operation.
- With SPI there is no "address". You directly enable a slave device by activating its /SS (slave select) line. In many cases, this will be a GPIO line at the master. For the master, data is simultaneously sent from the MOSI line and received via the MISO line - there is no "RW bit" like in I2C.
- For the master to receive data from a SPI slave, you would send a dummy byte to initiate the transfer of data from the slave. The returned byte value would need to be within the slave send buffer prior to the dummy byte being sent, so it is not possible for data to be returned in response to a command, within a single byte transaction.
I am not sure what your slave device is, but as an example, assume you wish to read data from a SPI compatible EEPROM. The following steps would typically be involved.
Send READ command - ignore return
Send first address byte - ignore return
Send second address byte - ignore return
Send dummy byte - first data byte returned
Send dummy byte - second data byte returned
etc.
When initialising the SPI module as a master you will need to match the CPOL and CPHA parameters to the requirements of the slave device. Whether or not you need to de-activate and then re-activate the /SS signal after each byte will also depend on the slave requirements. Provided a relatively fast SPI clock rate is selected, it is usually not necessary to use SPI interrupts for a master. This is not the case for the MCU operating as a slave.
For each master SPI transaction, you need to write a byte to SPDR, and a short while later you will have received a returned byte from the SPI slave. So the SPI function might be similar to the following code, but does not include control of the /SS line, that may need to be added.
byte SPI_proc (byte data)
{
while (!SPSCR_SPTE); /* Wait for Tx buffer empty */
SPDR = data; /* Send byte */
while (!SPSCR_SPRF); /* Wait for Rx buffer full */
return (SPDR); /* Received byte value */
}
For the EEPROM example given above -
SPI_proc (READ_CMD);
SPI_proc (address1);
SPI_proc (address2);
value1 = SPI_proc (0);
value2 = SPI_proc (0);
Regards,
Mac