Reputation: 650
I've recently got I2C working in no time with some MCC generated functions which are well documented in the .h file, however SPI gives me nothing and is causing me frustraions, not helped by the fact I'm new to these serial protocols.
I'm simply trying to read a register on a MCP23S17, then write to it, then read it back again to verify it's changed.
I'm not even sure I'm going about this the right way but I've included my code below with comments. For some reason I seem to need to add some dummy writes to get the first read to work, but only happens on the 2nd loop though.
#include "mcc_generated_files/mcc.h"
uint8_t receiveData; /* Data that will be received */
uint8_t OpCodeW = 0x40;
uint8_t OpCodeR = 0x41;
void main(void)
{
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
Reset1_GPIO_SetLow();
__delay_ms(200);
Reset1_GPIO_SetHigh();
__delay_ms(200);
printf("Initalised \r\n");
while (1)
{
SPI1_Open(SPI1_DEFAULT);
CS1_GPIO_SetLow();
// Read IODIRA Register 0x00
SPI1_ExchangeByte(OpCodeR); // Address + Read
SPI1_ExchangeByte(0x00); // ??? -- When I add this in it works 2nd loop -- ???
receiveData = SPI1_ExchangeByte(0x00); // Returns 0x00 1st loop, then 0xFF after ...
// ... but only when duplicate sending of byte above ???
printf("Read IODIRA: 0x%02x \r\n", receiveData);
// Try writing to IODIRA Register
// Not sure what SPI1_WriteByte actually does!
// I thought it might be the same as ExchangeByte but without anything returned
// No idea!
SPI1_WriteByte(OpCodeW); // Address + Write
SPI1_WriteByte(0x00); // Register Addres IODIRA (Port A)
SPI1_WriteByte(0xF0); // Data to be written
// Read back changed IODIRA Register again - Same routine as above
SPI1_ExchangeByte(OpCodeR); // Address + Read
SPI1_ExchangeByte(0x00); // Same routine as above ...
// ... but always prints 0x00
receiveData = SPI1_ExchangeByte(0x00); // Register Address, IODIRA (Port A)
printf("Wrote to IODIRA and read back: 0x%02x \r\n", receiveData);
printf(" ----- \r\n\n");
CS1_GPIO_SetHigh();
SPI1_Close();
__delay_ms(5000);
}
}
The actual printed output looks like this:
Initalised
Read IODIRA: 0x00 // Should be 0xFF
Wrote to IODIRA and read back: 0x00 // Should be 0xF0
-----
Read IODIRA: 0xff // This is right now!
Wrote to IODIRA and read back: 0x00 // but this hasn't changed
-----
Read IODIRA: 0xff
Wrote to IODIRA and read back: 0x00
Read IODIRA: 0xff
Wrote to IODIRA and read back: 0x00
Any help greatly appreciated.
Upvotes: 0
Views: 701
Reputation: 650
Turns out the answer was the Chip Select need to be set (low) with each SPI write to tell the device when a message has started/completed. I was using this more like an enable (keeping the device CS low) all the time as I only wanted to talk to one device, but that was incorrect.
Upvotes: 1