- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, I have not used the SPI Master function before and have a few questions. I am interface to the XRA1403 SPI 16-BIT IO Expander to toggle 16 LEDs. The SPI interface is described in the data sheet:
The SPI command Byte format is
Bit 7 (1=Read Operation and 0=Write Operation),
Bits6:1 is the Command Byte
Bit 0 is Reserved
My question is when I call the SPI_Write function will it clear bit 7 of the Command byte? Or must I control it in the Command Byte word.
#define OCR1_WR 0x02 // Write to Output Control Register, but 7 is cleared
#define OCR1_RD 0x82 // Read from Output Control Register, but 7 is set
So a write would look like:
SPIM_WriteTxData(OCR1_WR | 1); // sets bit 1 in the OCR1 register
Is my read command correct?
But I am not sure how to do a read, can anyone help me with a read?
Thanks,
Joe
Solved! Go to Solution.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Joe,
You can refer to the code example SCB_SpiCommMaster example project, where you need to only use the SPI Master (SCB) portion. PSoC has dedicated communication blocks called the SCB. If you have exhausted all your dedicated SCB blocks, then you can choose the UDB based SPI.
You need to have the following functions to read a data from XRA1403:
1. First you need to send the master command from the master SPI (SCB) device, that looks something like
#define OCR1_RD 0x82 . /* 1000 0010b -> MSB set to 1 indicating read operation. You need to read the register 0x02 */
SPIM_SpiUartWriteTXdata(OCR1_RD); /*Send the complete command as per given in packet format */
while(packet size != SPIM_SpiUartGetRxBufferSize())
{
}
/*Here packet size is no of packets to send. If packet size = no. of packets received, it means transmission is complete. In your application packet size is 1.*/
SCB_SpiUartClearRxBuffer(); /*Clear the data received from slave as it is junk for now. */
2. After successfully sending the command, your slave would have processed this command and will send the value of the register requested by the master. Now the master has to read this data from the slave. Remember, the master also has to send data through MOSI while receiving data from the slave (MISO). So you need to pass some temporary value to the buffer, which will be discarded by the slave.
uint8 temp = 0xFF;
SPIM_SpiUartWriteTxData(temp);
while(packet size != SPIM_SpiUartGetRxBufferSize())
{
}
SPIM_SpiUartClearTxBuffer(); /* Clear temp buffer data */
data = SpiUartReadRxdata(); /* Read the RxBuffer data */
Hope this helps!
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Joe,
What is the master device you're using?
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Joe,
You can refer to the code example SCB_SpiCommMaster example project, where you need to only use the SPI Master (SCB) portion. PSoC has dedicated communication blocks called the SCB. If you have exhausted all your dedicated SCB blocks, then you can choose the UDB based SPI.
You need to have the following functions to read a data from XRA1403:
1. First you need to send the master command from the master SPI (SCB) device, that looks something like
#define OCR1_RD 0x82 . /* 1000 0010b -> MSB set to 1 indicating read operation. You need to read the register 0x02 */
SPIM_SpiUartWriteTXdata(OCR1_RD); /*Send the complete command as per given in packet format */
while(packet size != SPIM_SpiUartGetRxBufferSize())
{
}
/*Here packet size is no of packets to send. If packet size = no. of packets received, it means transmission is complete. In your application packet size is 1.*/
SCB_SpiUartClearRxBuffer(); /*Clear the data received from slave as it is junk for now. */
2. After successfully sending the command, your slave would have processed this command and will send the value of the register requested by the master. Now the master has to read this data from the slave. Remember, the master also has to send data through MOSI while receiving data from the slave (MISO). So you need to pass some temporary value to the buffer, which will be discarded by the slave.
uint8 temp = 0xFF;
SPIM_SpiUartWriteTxData(temp);
while(packet size != SPIM_SpiUartGetRxBufferSize())
{
}
SPIM_SpiUartClearTxBuffer(); /* Clear temp buffer data */
data = SpiUartReadRxdata(); /* Read the RxBuffer data */
Hope this helps!
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you have a direct link to the SCB_SpiCommMaster example project? Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bragadeesh,
Hello, thank for the code it really helped me get going. Here is what I have so far:
#define OUTPUTCTRL1 0x02 // read/write, output control of p0-p7
#define OUTPUTCTRL1_RD 0x82 // read/write, output control of p0-p7
#define OUTPUTCTRL2 0x03 // read/write, output control of p8-p15
int packet_size = 1;
uint8 mydata = 0;
uint8 temp = 0xff;
CyGlobalIntEnable; /* Enable global interrupts. */
SPIM_LEDDRIVER_Start();
SPIM_LEDDRIVER_WriteTxData((GPIOCONF1 << 8)| 0x00); // set port0-7 to outputs
SPIM_LEDDRIVER_WriteTxData((GPIOCONF2 << 8)| 0x00); // set port8-15 to outputs
SPIM_LEDDRIVER_WriteTxData(OUTPUTCTRL1_RD << 8 | 0x0);
while(packet_size != SPIM_LEDDRIVER_GetRxBufferSize())
{
}
SPIM_LEDDRIVER_ClearRxBuffer(); // clear the data receive from the slave
SPIM_LEDDRIVER_WriteTxData(temp); // set port8-15 to outputs
while(packet_size != SPIM_LEDDRIVER_GetRxBufferSize())
{
}
SPIM_LEDDRIVER_ClearTxBuffer();// clear temp buffer data
mydata = SPIM_LEDDRIVER_ReadRxData();
----
Is it proper to shift up the address 8 bit and OR it with the data, for example SPIM_LEDDRIVER_WriteTxData((GPIOCONF1 << 8)| 0x00)? The shift direction is MSB first and would put the data words first and followed by the address word.
Also, how deep should my RX and TX buffers be?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Joe,
You can't have a 8 bit buffer and try to send a 16 bit data. In the Configure SPI dialog box, in Configure tab, increase the data bits to 16. If you do that you will be able to send 16 bit data like you have tried in your code.
But if you want only 8 bit buffer, you need to send the data twice. For eg:
SPIM_LEDDRIVER_WriteTxData((GPIOCONF1);
SPIM_LEDDRIVER_WriteTxData(0x00);
Or instead of sending it two times, you can use SPIM_PutArray( uint8 data[], uint8 ByteCount) /* 8 bit buffer */
For eg:
uint8 data[2] = {0x82,0x00};
SPIM_PutArray(data,2);
Since you are reading and clearing the buffer often, the minimum of 4 bytes is enough for your application.
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can find the code example in PsoC Creator 4.2
Open PSoC Creator. File -> Code Example-> SCB_SpiCommMaster
Also, PSoC 5LP doesn't have SCB block. Only PSoC 4/6 have them.
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am using the SPI Master Full Duplex mode macro v2.50 in my PSOC5 Design.