I am using SPI to send data from an analog front end to a microcontroller and would like to be able to receive the data. Before receiving the data, I send data to the AFE to set certain registers in the AFE and would like to read the received data on the SIn pin on the microcontroller. I am using a Kinetis K53 tower microcontroller and an ADAS1000sdz Analog Devices Front End.
I have to send command words to the AFE to set control registers in it that tell me what data is to be sent and at what rate. To do this, I am pushing the command words into the TX FIFO. I can see that there is data in the TX FIFO consistent with what I have sent. I can see the TCR counter incrementing. Every control bit is 32 bits, including the address of the control register in the AFE. I have set the frame size to 8 bits- which means, that to send one control word, I must send 8 bits at a time. This corresponds to 4 SPI0_PUSHR commands for one control register. At every PUSHR, I am also doing POPR, to check what data is getting received.
However at no point during the setting of the 4 control registers in the AFE, am I ever receiving any data in the RX FIFO.
Also, I understand that only after setting the control registers in the AFE, will I be able to get the sampled data from the AFE to the microcontroller. So after setting four control registers, which corresponds to 16 PUSHR commands in total, I should read the relevant received data from the AFE. However, the RX FIFO is again read byte-by-byte; so how would I read the received data?
If the data is streaming continuously, how would I know where one frame of data begins and one frame ends? I have set the incoming sampling rate at the time of setting the control registers present in the AFE.
Edit : I am setting in the ADAS1000SDZ, a FRAMES register to issue the command to read the data. According to the datasheet, writing to the frame header register issues the read command to start putting the converted data out on the SDO pin.
I tried the example given in the ADAS1000SDZ datasheet, which is to generate a 150Hz sine tone, and still didn't receive any data in the RX FIFO registers after the write.
How do I read the registers that are read-only? How do I access the data there?
Message was edited by: Samyukta Ramnath
Hi, Samyukta,
I have downloaded and browsed the data sheet of ADSA1000 from Analog Device website, I suppose you connect the SPI module of K50 to the primary SPI interface of ADSA1000, in other words, you connect the /CS, SCLK,SDI,SDO to the SPI pin of K50.
The frame size of ADAS1000 is 32 bits, but the maximum frame size of K53 is 16 bits, the TXDATA is 16 bits, fortunately, the SPI of K53 supports the Continuous mode, in other words, you can use two 16 bits frame as a 32 bits frame. In detail, when you send the first word, set CONT bit in the SPIx_PUSHR, when you send second data, clear the CONT in SPIx_PUSHR, in this way, the /PCSx will cover 32 bits. Secondly, I suggest you do not use FIFO mode, you can disable FIFO mode by
setting the DIS_TXF and DIS_RXF bits.
I suggest you write the SPI register directly instead of using SDK function, because SDK uses the stream data format, the writing function is to write the data to a buffer rather than writing SPIx_PUSHR directly.
Hope it can help you
BR
XiangJun Rong
I am not using any SDK functions and am addressing the SDI registers directly. Initially, I was sending out 32 bits as four 8 bit words, but had not taken into account the continuous chip select. In my code, the chip select is always low.. I tried what you said, keeping the frame size as 16 bits and pushing two 16 bit words with the SPI_PUSHR_CONT asserted for the first word and deasserted for the second.
While I do get some response, it is clearly not the correct data that I am expecting.
Hi, Symyukta,
If you use 16 bits words, the the FMSZ bits in SPI0_CTAR0 should be 0xF, if you use 8 bits word, the FMSZ bits should be 0x7. I suggest you connect the SCLK and PCS0, SIN to oscilloscope and check if if the signals are correct.
Secondly, pls check the CPHA and CPOL bits and check if your configuration matches with the SPI timing of the ADSA1000.
Thirdly, I suggest you connect the SIN pin to High or low with a pull-up/down resistor if you can float the SIN pin of the ADSA1000. BTW, pls check the data sheet of ADSA1000, maybe the ADSA1000 needs special setting so that the SIN pin can output correct data.
Hope it can help you
BR
Xiangjun Rong
I noticed one thing, when I connected MISO to ground I was getting all zeros and to VDD was getting always 0xff. But when I connected gnd to MOSI, I was getting any random data in and similar random result when connecting MOSI to VDD. It suggests that the data being read in is correct but the commands being sent out are somehow being garbled. I will try and acquire a scope to view all the signals properly. Thank you!
I have kept my frame size as 8 bits per frame and am sending words out like so:
int register_configure(int address)
{
//int data[5];
int data;
unsigned int data1,data2,data3,data4;
int address1, address2, address3,address4;
address1 = address & 0x000000ff;
address2=address & 0x0000ff00;
address2 = address2>>8;
address3 = address & 0x00ff0000;
address3 = address3>>16;
address4 = address & 0xff000000;
address4 = address4>>24;
address4 = address4 & 0x000000ff;
SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | //The CTAR0 is selected
(SPI_PUSHR_CONT_MASK) | //Chip select is continuous through transfers
SPI_PUSHR_TXDATA(address4))|
SPI_PUSHR_PCS(1) ; //Pushes the required data
while((SPI0_SR & SPI_SR_TCF_MASK)==0){}//wait till the transfer is complete
data1 = SPI0_POPR; // the latest data in the RX FIFO is transferred to data1
while((SPI0_SR & SPI_SR_TFFF_MASK)==0); //wait till the TX FIFO is not empty
while((SPI0_SR & SPI_SR_RFDF_MASK)==0); //wait till the RX FIFO is not empty
SPI0_SR |= SPI_SR_TFFF_MASK; // TX FIFO is not empty set
SPI0_SR |= SPI_SR_RFDF_MASK; //sets the RX FIFO is not empty flag
SPI0_SR |= SPI_SR_TCF_MASK; //Transfer is complete flag set
SPI0_PUSHR = (SPI_PUSHR_CTAS(0x00)) |
(SPI_PUSHR_CONT_MASK) |
SPI_PUSHR_TXDATA(address3)|
SPI_PUSHR_PCS(1); //CS is asserted
while((SPI0_SR & SPI_SR_TCF_MASK)==0){}//wait till the transfer is complete
while((SPI0_SR & SPI_SR_TFFF_MASK)==0); //wait till the TX FIFO is not empty
while((SPI0_SR & SPI_SR_RFDF_MASK)==0); //wait till the RX FIFO is not empty
data2 = SPI0_POPR; // the latest data in the RX FIFO is transferred to data1
SPI0_SR |= SPI_SR_TFFF_MASK; // TX FIFO is not empty set
SPI0_SR |= SPI_SR_RFDF_MASK; //sets the RX FIFO is not empty flag
SPI0_SR |= SPI_SR_RFOF_MASK;
SPI0_SR |= SPI_SR_TCF_MASK; //Transfer is complete flag set
SPI0_PUSHR = (SPI_PUSHR_CTAS(0x00)) |
(SPI_PUSHR_CONT_MASK) |
SPI_PUSHR_TXDATA(address2)|
SPI_PUSHR_PCS(1);
while((SPI0_SR & SPI_SR_TCF_MASK)==0){}//wait till the transfer is complete
while((SPI0_SR & SPI_SR_TFFF_MASK)==0); //wait till the TX FIFO is not empty
while((SPI0_SR & SPI_SR_RFDF_MASK)==0); //wait till the RX FIFO is not empty
data3 = SPI0_POPR; // the latest data in the RX FIFO is transferred to data1
SPI0_SR |= SPI_SR_TFFF_MASK; // TX FIFO is not empty set
SPI0_SR |= SPI_SR_RFDF_MASK; //sets the RX FIFO is not empty flag
SPI0_SR |= SPI_SR_RFOF_MASK;
SPI0_SR |= SPI_SR_TCF_MASK; //Transfer is complete flag set
SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) |
(SPI_PUSHR_CONT_MASK) |
SPI_PUSHR_TXDATA(address1)|
SPI_PUSHR_PCS(1));
while((SPI0_SR & SPI_SR_TCF_MASK)==0){}//wait till the transfer is complete
while((SPI0_SR & SPI_SR_TFFF_MASK)==0); //wait till the TX FIFO is not empty
while((SPI0_SR & SPI_SR_RFDF_MASK)==0); //wait till the RX FIFO is not empty
data4 = SPI0_POPR; // the latest data in the RX FIFO is transferred to data1
SPI0_SR |= SPI_SR_TFFF_MASK; // TX FIFO is not empty set
SPI0_SR |= SPI_SR_RFDF_MASK; //sets the RX FIFO is not empty flag
SPI0_SR |= SPI_SR_TCF_MASK; //Transfer is complete flag set
data = (((data1<<24) & 0xff000000)|((data2<<16)&0x00ff0000)|((data3<<8)&0x0000ff00)|(data4 & 0x000000ff));
return data;
}
i.e. I have pushed data byte by byte four times. Is this approach wrong?
These are my initializations :
SPI0_MCR = ((SPI_MCR_HALT_MASK) | //halts transfers
(SPI_MCR_MDIS_MASK & 0x00)); //enables module clocks
SPI0_MCR = (SPI_MCR_MSTR_MASK )| //master mode
(SPI_MCR_ROOE_MASK)| // incoming data shifted into shift register
//overwriting previous data
//when RX FIFO is full
(SPI_MCR_DCONF(0x00))| // SPI
(SPI_MCR_PCSIS(1))| // determines inactive state of PC(X):
// 0 : inactive PC(x) is low
(SPI_MCR_DIS_TXF_MASK)|
(SPI_MCR_DIS_RXF_MASK)|
(SPI_MCR_CONT_SCKE_MASK && 0x00); //continuous SKE enable
SPI0_CTAR0 = (SPI_CTAR_DBR_MASK & 0x00) |
(SPI_CTAR_FMSZ(0xff)) |
(SPI_CTAR_PDT(0x00)) |
(SPI_CTAR_BR(0x04)) | //was 0x07 //baud rate prescaler
(SPI_CTAR_CPOL_MASK & 0x00) |
(SPI_CTAR_CPHA_MASK & 0x00) |
(SPI_CTAR_PBR(0x02)) | //was 0x02 /pre baud prescaler
(SPI_CTAR_PCSSCK(0x02) |
(SPI_CTAR_PASC(0x00)) |
(SPI_CTAR_CSSCK(0x06)) |
(SPI_CTAR_ASC(0)) |
(SPI_CTAR_PDT(0x00)) |
(SPI_CTAR_DT(0))) ; // mode 0 operation
SPI0_MCR &= 0xfffffffe ; //start transfers again