Hi,
I am trying to use the processor expert SPI bean to help establish communication between my MCU and a sensor. I know very little about how SPI works, and am having difficulty trouble-shooting the problem. Does the hcs12 store any data being sent from the slave in a buffer, which can then be read at a later time using the RecvChar command?
A potential problem is that the hcs12 only seems to run the clock (SCLK) signal while it is sending data, and I can't figure out how to get it to run during the time when it is supposed to be receiving a signal. Also, I don't see a way to modify or pick the clock speed. I have attached the document which describes the SPI interface on my sensor, and posted my code below.
/* Including used modules for compiling procedure */ #include "Cpu.h" #include "Events.h" #include "SPI3.h" #include "Inhr1.h" #include "Inhr2.h" #include "Inhr3.h" #include "SRREADY.h" #include "PORTP0.h" #include "PORTP1.h" #include "PORTP2.h" #include "PORTP3.h" /* Include shared modules, which are used for whole project */ #include "PE_Types.h" #include "PE_Error.h" #include "PE_Const.h" #include "IO_Map.h" //constants int SPI_DELAY = 100; //vars int response=0; int skipperoo=0; byte recvd1=0; byte recvd2=0; int reply=0; int SPIcommand(byte command, byte operand) { PORTP0_SetVal(); PORTP1_ClrVal(); SPI3_SendChar(command); SPI3_SendChar(operand); PORTP0_ClrVal(); PORTP1_SetVal(); //while(!SRREADY_GetVal()); // while(!PORTP2_GetVal()); Cpu_Delay100US(SPI_DELAY); PORTP0_SetVal(); PORTP1_ClrVal(); SPI3_RecvChar(&recvd1); SPI3_RecvChar(&recvd2); reply = recvd1; reply <<= 8; reply += recvd2; return reply; } void main(void) { /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ PE_low_level_init(); /*** End of Processor Expert internal initialization. ***/ for(;;) { response = SPIcommand(4,0); PORTP3_NegVal(); //Cpu_Delay100US(1*SPI_DELAY); } /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/ for(;;){} /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/ } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
Solved! Go to Solution.
Hello,
I think that the main problem with your code is that you have not met the SPI data format requirements of the slave device, as detailed in its datasheet.
You do not say, but am I correct in assuming that "PORTP0" represents the signal SEN0, and "PORTP1" the signal SEN1? It would appear that SEN0 should remain inactive high for the whole period of a command sequence. Similarly SEN1 should remain inactive high for the whole period of an event interface sequence.
Additionally, a command may have either no operand, or a single 16-bit (word) operand. Your code does not currently allow for either of these alternatives. So we appear to require either a total transmission of 8-bits for no operand, or alternatively a total of 24-bits.
It would appear that you may need a separate function for each case, or a special "invalid" operand value that is outside the normal operand range. A value of 0xFFFF might be such a value. Perhaps something like the following untested code would work -
word SPIcommand( byte command, word operand) { byte recvd1; byte recvd2; PORTP0_SetVal(); // Ensure SEN0 event interface disabled PORTP1_ClrVal(); // Enable SEN1 command interface SPI3_SendChar(command); if (operand < 0xFFFF) { // Test for operand present SPI3_SendChar((byte)(operand / 256)); // High operand byte SPI3_SendChar((byte)(operand % 256)); // Low operand byte } PORTP1_SetVal(); // Set SEN1 inactive while (!SRREADY_GetVal()); // Wait until ready for data return PORTP1_ClrVal(); // Re-enable SEN1 command interface SPI3_RecvChar(&recvd1); // High return byte SPI3_RecvChar(&recvd2); // Low return byte PORTP1_SetVal(); // Set SEN1 inactive return (recvd1 * 256 + recvd2); }
Regards,
Mac
Actually, I will take that back. Things don't work.
The signal SRDY, which is supposed to go low-high when the slave is ready to transmit a response, is not doing anything, ever. Yet somehow, there is a signal appearing on SDO. Now, my question is, since the master controls the clock, how does the master know when to run the SCK signal for receiving information? It can't possibly, unless reading the signal from SRDY, right? Only, that signal is not transitioning, and somehow the slave device is still sending something out. I am so confused...
Hello,
I think that the main problem with your code is that you have not met the SPI data format requirements of the slave device, as detailed in its datasheet.
You do not say, but am I correct in assuming that "PORTP0" represents the signal SEN0, and "PORTP1" the signal SEN1? It would appear that SEN0 should remain inactive high for the whole period of a command sequence. Similarly SEN1 should remain inactive high for the whole period of an event interface sequence.
Additionally, a command may have either no operand, or a single 16-bit (word) operand. Your code does not currently allow for either of these alternatives. So we appear to require either a total transmission of 8-bits for no operand, or alternatively a total of 24-bits.
It would appear that you may need a separate function for each case, or a special "invalid" operand value that is outside the normal operand range. A value of 0xFFFF might be such a value. Perhaps something like the following untested code would work -
word SPIcommand( byte command, word operand) { byte recvd1; byte recvd2; PORTP0_SetVal(); // Ensure SEN0 event interface disabled PORTP1_ClrVal(); // Enable SEN1 command interface SPI3_SendChar(command); if (operand < 0xFFFF) { // Test for operand present SPI3_SendChar((byte)(operand / 256)); // High operand byte SPI3_SendChar((byte)(operand % 256)); // Low operand byte } PORTP1_SetVal(); // Set SEN1 inactive while (!SRREADY_GetVal()); // Wait until ready for data return PORTP1_ClrVal(); // Re-enable SEN1 command interface SPI3_RecvChar(&recvd1); // High return byte SPI3_RecvChar(&recvd2); // Low return byte PORTP1_SetVal(); // Set SEN1 inactive return (recvd1 * 256 + recvd2); }
Regards,
Mac