I'm trying to write a program using the LPC1788 microcontroller, and I need to send and transmit data to a UFDC (universal frequency-to-digital converter) using SPI protocol. A datasheet for this can be found here. My microcontroller's SSP controller is set as the master and the UFDC presumably becomes the slave. I'm able to transmit information down the MOSI line and see the data appear on an oscilloscope. However, when I try to receive data on the MISO line, I only get back what I sent down the MOSI.
Here is a picture of the schematic.
The relevant part of the code I've written is below:
SSP_CFG_Type sspConfig;
SSP_DATA_SETUP_Type sspData;
LPC_SSP_TypeDef *SSPx = NULL;
UFDC_RESULT_T result_SSP0_FX1, result_SSP0_FX2;
UFDC_RESULT_T result_SSP1_FX1, result_SSP1_FX2;
UFDC_RESULT_T *result, *resultFX1, *resultFX2 = NULL;
uint8_t resultSign;
uint64_t resultInt, resultFract;
uint8_t SSP0resultFX1sign, SSP0resultFX2sign;
uint8_t SSP1resultFX1sign, SSP1resultFX2sign;
uint64_t SSP0resultFX1int, SSP0resultFX2int;
uint64_t SSP1resultFX1int, SSP1resultFX2int;
uint64_t SSP0resultFX1fract, SSP0resultFX2fract;
uint64_t SSP1resultFX1fract, SSP1resultFX2fract;
uint16_t getAccInstr = 0x01FF;
uint16_t setAccInstr = 0x0204;
uint16_t checkStatusInstr = 0x03FF;
uint16_t setMeasureModeInstr1 = 0x0600;
uint16_t setMeasureModeInstr2 = 0x060E;
uint16_t getBCDResultInstr = 0x07FF;
uint8_t startMeasureInstr = 0x09;
uint32_t measureInstr;
uint8_t txData[2];
uint8_t rxData[2];
uint16_t data;
sspConfig.CPHA = SSP_CPHA_FIRST;
sspConfig.CPOL = SSP_CPOL_HI;
sspConfig.ClockRate = 100000;
sspConfig.Databit = SSP_DATABIT_8;
sspConfig.Mode = SSP_MASTER_MODE;
sspConfig.FrameFormat = SSP_FRAME_SPI;
sspData.tx_data = txData;
sspData.rx_data = rxData;
sspData.length = 2;
printf("Initialising SSP0 and SSP1...\n\n");
PINSEL_ConfigPin(0, 15, 2); // SSP0_SCK
PINSEL_ConfigPin(0, 16, 2); // SSP0_SSEL
PINSEL_ConfigPin(0, 17, 2); // SSP0_MISO
PINSEL_ConfigPin(0, 18, 2); // SSP0_MOSI
PINSEL_ConfigPin(0, 6, 2); // SSP1_SCK
PINSEL_ConfigPin(0, 7, 2); // SSP1_SSEL
PINSEL_ConfigPin(0, 8, 2); // SSP1_MISO
PINSEL_ConfigPin(0, 9, 2); // SSP1_MOSI
PINSEL_SetFilter(0, 7, DISABLE);
PINSEL_SetFilter(0, 8, DISABLE);
PINSEL_SetFilter(0, 9, DISABLE);
SSP_Init(LPC_SSP0, &sspConfig);
SSP_Init(LPC_SSP1, &sspConfig);
SSP_Cmd(LPC_SSP0, ENABLE);
SSP_Cmd(LPC_SSP1, ENABLE);
printf("Reading UDFC frequency values...\n\n");
for(int i=0; i < 2; i++)
{
if(i == 0)
{
SSPx = LPC_SSP0;
resultFX1 = &result_SSP0_FX1;
resultFX2 = &result_SSP0_FX2;
}
else
{
SSPx = LPC_SSP1;
resultFX1 = &result_SSP1_FX1;
resultFX2 = &result_SSP1_FX2;
}
// Set UFDC accuracy to 0.05%.
SSP_SendData(SSPx, (uint8_t)(setAccInstr >> 8));
SSP_SendData(SSPx, (uint8_t)(setAccInstr & 0xFF));
// Check accuracy.
while(1)
{
SSP_SendData(SSPx, (uint8_t)(getAccInstr >> 8));
SSP_SendData(SSPx, (uint8_t)(getAccInstr & 0xFF));
data = SSP_ReceiveData(SSPx);
printf("Accuracy check 1: %i\n", data >> 8);
printf("Accuracy check 2: %i\n", data & 0xFF);
}
// More code follows.
The output I'm getting from this is below:
Accuracy check 1: 0
Accuracy check 2: 0
Accuracy check 1: 0
Accuracy check 2: 255
Accuracy check 1: 0
Accuracy check 2: 2
Accuracy check 1: 0
Accuracy check 2: 4
Accuracy check 1: 0
Accuracy check 2: 1
Accuracy check 1: 0
Accuracy check 2: 255
Accuracy check 1: 0
Accuracy check 2: 1
Accuracy check 1: 0
Accuracy check 2: 255
Accuracy check 1: 0
Accuracy check 2: 1
Accuracy check 1: 0
Accuracy check 2: 255
Edit: It's possible to set "loop back enable" with the SPI controllers to make the MOSI read input from the MISO and vice versa. However, I've checked the relevant register and this is disabled.