SPI Communication

cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Communication

1,099 Views
caden013
Contributor III

Hi all,

I am trying to use the SPI protocol to communicate between my board (LPC55S06-EVK) and an external ADC (EVAL-AD7984 from Analog Devices). I have attached the page from the datasheet of my ADC to show you how the SPI communication works so that you can understand my code given below (I have also attached my entire source file). My question is this: how do I enable (start) and disable (stop) the SPI SCK from running? First, does the function CLOCK_AttachClk start the clock signal on SPI SCK? Second, what function should I use to stop the SPI SCK? 

If I am going about this the wrong way, please point me in the right direction.

(My next question, which is probably for another community post, is how do I input the data from the EVAL board via the SPI MISO back to my NXP board and interpret it?)

caden013_0-1624564393444.png

 

Here is my code:

while (1)
{
SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_L); // start SCTIMER
GPIO_PinWrite(GPIO, 1, 1, 1); // set CNV (start conversion)

if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_MatchEventOnly, matchValue_tCONV, 0, kSCTIMER_Counter_L,
&eventCounter_tCONV) == kStatus_Success)
{
GPIO_PinWrite(GPIO, 1, 1, 0); // clear CNV
}

if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_MatchEventOnly, matchValue_tEN, 0, kSCTIMER_Counter_L,
&eventCounter_tEN) == kStatus_Success)
{
CLOCK_AttachClk(kFRO12M_to_FLEXCOMM7); // start clock (12 MHz)
}

if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_MatchEventOnly, matchValue_tACQ, 0, kSCTIMER_Counter_L,
&eventCounter_tACQ) == kStatus_Success)
{
//CLOCK_StopClk...;
}

SCTIMER_SetupCounterLimitAction(SCT0, kSCTIMER_Counter_L, eventCounter_tACQ); // reset counter when t_ACQ is reached
SCTIMER_StopTimer(SCT0, kSCTIMER_Counter_L); // stop SCTIMER
}

Labels (2)
Tags (2)
0 Kudos
7 Replies

1,074 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Caden,

Regarding your question, I think your code is too complicated.

As you connect 3 signals to the AD7984, I suggest you connect the SSELx  of LPC5506 to CONV of ADC, connect the SCK of LPC to SCK pin of ADC, connect the MISO  pin of LPC to SDO of ADC. You do not need any GPIO or SCT modules.

The high width of SSEL can be controlled by the TRANSFER_ DELAY bits of SPI delay register.

Because the width of data is 18 bits, so you have to transfer twice for example, transfer 8 bits first times with EOT bit of FIFOWR register cleared, transfer remaining 10 bits in second times with EOT bit set, after the second transfer, the SSEL signal will becomes high with the time defined by TRANSFER_ DELAY.

I hope you write the SPI register directly without calling the SDK function.

Regarding the CLOCK_AttachClk() function, it select the SPI driving clock, the SCK clock is from the clock defined by CLOCK_AttachClk() with a baudrate divider as Frank said.

Hope it can help you

BR

XiangJun Rong

 

 

1,071 Views
frank_meyer
Senior Contributor II

> Because the width of data is 18 bits, so you have to transfer twice for example, transfer 8 bits first times with EOT bit of FIFOWR register cleared, transfer remaining 10 bits in second times with EOT bit set, after the second transfer, the SSEL signal will becomes high with the time defined by TRANSFER_ DELAY.

Since the O.P. seems more at a beginner level here, the choice of a device requiring 18-bit transfers seems very unfortunate to me. It unneccesarily complicates the understanding, and the required code.

You don't learn driving in a F1 car on a race track.

1,078 Views
frank_meyer
Senior Contributor II

> First, does the function CLOCK_AttachClk start the clock signal on SPI SCK?

No, it doesn't. It only enables the peripheral unit.

The SCK signal start when you write to the Tx register. In this case, usually the FIFOWR register.

> Second, what function should I use to stop the SPI SCK? 

None. When the transfer according to the current SPI configuration is finished, SCK stops automatically.

NXP's idea to integrate multiple serial communication busses (UART, SPI, I2C, I2S) into one "flexcomm" unit makes it rather complex, and difficult to understand.

Besides of the MCU user manual, I would suggest to read up a more generic SPI tutorial.

This is the first one coming up in a search: https://www.corelis.com/education/tutorials/spi-tutorial/

 

1,050 Views
caden013
Contributor III

The external ADC (EVAL-AD7984) that I am using does not have a usable SDI (MOSI) pin (the SDI pin is tied to logic 1). I have connected an LED to the SCK pin header to see if my clock signal is being propagated, and I cannot determine that it is. You said that I needed to write to the FIFOWR register to turn on the clock, so I used the function "SPI_WriteData," which did not turn on my clock signal. Then, I tried using the instruction "SPI3->FIFOWR = 1," but again it did not work.

I used the function "SPI_ReadData" to input the ADC values, but my results are always 0. I assume that if I fix my clock signal, I will at least see values other than 0. 

Sorry for my novice understanding, but I appreciate your help. 

0 Kudos

1,037 Views
frank_meyer
Senior Contributor II

> The external ADC (EVAL-AD7984) that I am using does not have a usable SDI (MOSI) pin (the SDI pin is tied to logic 1)

Which is no problem, the device does not need input. The transmit data are irrelevant in this case.

> I have connected an LED to the SCK pin header to see if my clock signal is being propagated, and I cannot determine that it is.

If you are using normal clock speeds, you will not see anything. This is just plain physiology of the human eye. You would need a scope.

> You said that I needed to write to the FIFOWR register to turn on the clock, so I used the function "SPI_WriteData," which did not turn on my clock signal. Then, I tried using the instruction "SPI3->FIFOWR = 1," but again it did not work.

The SPI interface must be properly initialized (clocks enables, pins configured).

Aren't there SDK examples for the SPI interface ? Building and running one should be no problem. If you connect to ADC board to this SPI interface, you should at least be able to observe the signals, even if it is not according to the ADC datasheet.

If the connections are electrically/logically correct, nothing breaks. From there, you can start to modify it, to get your ADC running.

 

1,001 Views
caden013
Contributor III

Does the SPI communication begin as soon as all the corresponding SPI registers are initialized? For example, as soon as I initialize the CFG register in my code, is the SSEL signal set according to the rest of the settings in the CFG register?

0 Kudos

978 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Caden,

This is snippet of SPI code based on LPC54628, pls try to refer to it.

void SPI3InitMaster(void)
{
//Reset FC3
SYSCON->PRESETCTRL[1]|=1<<14;
SYSCON->PRESETCTRL[1]&=~(1<<14);
//set gated clock of FC3
SYSCON->AHBCLKCTRL[1]|=1<<14;
//set the FC3 as spi
FLEXCOMM3->PSELID=0x02;
//set SPI clock divider
//select 12MHz FRO_12M
SYSCON->FCLKSEL[3]=0x00;
//SPI configuration
//master mode,MSB first,CPHA=CPOL=0
SPI3->CFG=0x04;
//spi3 enable
//SPI3->CFG|=0x01;
//set delay
SPI3->DLY=0x2222;
//spi divider
SPI3->DIV=0x00;
SPI3->FIFOCFG=0x03;
//FIFO configuration
//enable FIFO
#if FIFOMODE
SPI3->FIFOTRIG=0x03;
#else
SPI3->FIFOTRIG=0x10103;
#endif
}

 

void SPI3PinAssignment(void)
{
uint32_t pin_config;
//PINs Configuration for Master
CLOCK_EnableClock(kCLOCK_Iocon);
CLOCK_EnableClock(kCLOCK_Gpio0);
// P0_0/FC3_SCK, pin4 of J14
pin_config = (/* Pin is configured as FC3_SCK */
IOCON_PIO_FUNC1 +1 |
/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Input filter disabled */
IOCON_PIO_INPFILT_OFF |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN0 (coords: N2) is configured as FC3_SCK */
IOCON_PinMuxSet(IOCON, 0, 0, pin_config);

// P0_1/FC3_SSEL0, pin1 of J14
pin_config = (/* Pin is configured as FC3_CTS_SDA_SSEL0 */
IOCON_PIO_FUNC1 + 1 |
/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Input filter disabled */
IOCON_PIO_INPFILT_OFF |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN1 (coords: K13) is configured as FC3_CTS_SDA_SSEL0 */
IOCON_PinMuxSet(IOCON, 0, 1, pin_config);

//// P0_3/FC3_MOSI, pin2 of J14
pin_config = (/* Pin is configured as FC3_RXD_SDA_MOSI */
IOCON_PIO_FUNC1|
/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Input filter disabled */
IOCON_PIO_INPFILT_OFF |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN3 (coords: P5) is configured as FC3_RXD_SDA_MOSI */
IOCON_PinMuxSet(IOCON, 0, 3, pin_config);


// P0_2/FC3_MOSI, pin3 of J14
pin_config = (/* Pin is configured as FC3_TXD_SCL_MISO */
IOCON_PIO_FUNC1 |
/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Input filter disabled */
IOCON_PIO_INPFILT_OFF |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN2 (coords: N5) is configured as FC3_TXD_SCL_MISO */
IOCON_PinMuxSet(IOCON, 0, 2, pin_config);

 

}

void enableSPI3(void)
{
//spi3 enable
SPI3->CFG|=0x01;
}

void masterDirectlySendByte(uint8_t data)
{
uint32_t ctrl = 0x73e0000;
//poll if the FIFI is full
while(!(SPI3->FIFOSTAT&(1<<5))) {}
SPI3->FIFOWR = ctrl | data;

}

 

void main()

{
SPI3PinAssignment();
SPI3InitMaster();
enableSPI3();

while(1) {

//masterDirectlySendByte(0xD3);
masterDirectlySendByte(100+i);

 

..

}

 

}

 

0 Kudos