LPC54628 SPI slave

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC54628 SPI slave

620 Views
aswinprabhu
Contributor III

Hi,`

There are two boards with LPC54628 on them communicating via SPI in master-slave mode using interrupts. LPC PLL is 96MHz, Flexcomm at 48MHz, SPI baud rate at 500kHz, MSbfirst, CPOL=CPHA= same settings on both master and slave. Code is written in Keil

Transfer of data from Master to Slave occurs properly and can be verified from oscilloscope. However, when I try to send the data received by slave to computer's UART, i see that the data is all messed up. To see where the problem is happening, I inserted LED_toggle() function which toggles a GPIO output pin such that whenever the code enters SPI ISR due to Rx_not_empty flag, this pin gets toggled.

Observation: As you can see from the image, the code generates and enters the Rx_not_empty ISR during every clock cycle instead of once every 16 clock cycles. Could someone tell why this is happening?

</

 

#include "spi.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "clock_config.h"
#include "wdt.h"
#include "delay.h"
#include "pins.h"
#include "spi.h"
#include "usart.h"

uint8_t count;
uint8_t slave_RxIndex;
uint16_t SPI_Rx[10] = {0,0,0,0,0,0,0,0,0,0};
bool slaveFinished = false;
uint16_t temp16;
uint32_t temp32;

void IRQ_DO_FC5_SPI_Slave(void){
	/* read data to avoid rxOverflow */
	if (SPI_GetStatusFlags(FLEXCOMM5_PERIPHERAL) & kSPI_RxNotEmptyFlag){
		SPI_Rx[slave_RxIndex]= SPI_ReadData(FLEXCOMM5_PERIPHERAL);
		slave_RxIndex++;
		LED_toggle();
	}
	
	if (slave_RxIndex == 0x08){
		slaveFinished = true;
		slave_RxIndex = 0;
	}
}

int main(void){
	WWDT_Disable(WWDT);
	for (uint8_t i=0; i<1; i++){	// some delay to ensure voltage has stabilized prior to executing code
		delay();
	}
	WWDT_Disable(WWDT);
	
	CLOCK_EnableClock(kCLOCK_InputMux);
	CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
	CLOCK_AttachClk(kFRO_HF_to_FLEXCOMM5); 	
	CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);	
	
	
	count = 0;
	slave_RxIndex = 0;
	slaveFinished = false;
	temp32 = 0;
	temp16 = 0;
	
	BOARD_InitBootPins();
	BOARD_BootClockRUN();
	BOARD_InitDebugConsole();
	delay();
	FLEXCOMM5_init();

	
	GPIO->B[0][GPIO_LED] = 0;
	FLEXCOMM5_PERIPHERAL->FIFOTRIG &= ~0x1; // If LSb = 0, then ransmit FIFO level does not generate a FIFO level trigger
	
	while(1){
		
		if (slaveFinished == true){
			slaveFinished = false;
			slave_RxIndex = 0;
			
			/* clear tx/rx errors and empty FIFOs */
			FLEXCOMM5_PERIPHERAL->FIFOCFG |= SPI_FIFOCFG_EMPTYTX_MASK | SPI_FIFOCFG_EMPTYRX_MASK;
			FLEXCOMM5_PERIPHERAL->FIFOSTAT |= SPI_FIFOSTAT_TXERR_MASK | SPI_FIFOSTAT_RXERR_MASK;
			
			for (uint8_t i=0; i< 8U; i++){
				PRINTF("Rx[%d]=0x%d, ", i, SPI_Rx[i]);
			}
			PRINTF("\r\n\r\n");
		}
	}
}

 

>

 

 

// SLAVE SPI CONFIGURATION SETTINGS:

const spi_slave_config_t FLEXCOMM5_config = {
  .enableSlave = true,
  .polarity = kSPI_ClockPolarityActiveHigh,
  .phase = kSPI_ClockPhaseFirstEdge,
  .direction = kSPI_MsbFirst,
  .dataWidth = kSPI_Data16Bits,
  .sselPol = kSPI_SpolActiveAllLow,
  .txWatermark = kSPI_TxFifo0,
  .rxWatermark = kSPI_RxFifo1
};

void FLEXCOMM5_init(void) {
  RESET_PeripheralReset(kFC5_RST_SHIFT_RSTn);
  /* Initialization function */
	SPI_SlaveInit(FLEXCOMM5_PERIPHERAL, &FLEXCOMM5_config);
  /* Enable interrupts */
  SPI_EnableInterrupts(FLEXCOMM5_PERIPHERAL, (kSPI_RxLvlIrq));
	/* Enable interrupt FLEXCOMM5_IRQn request in the NVIC. */
  EnableIRQ(FLEXCOMM5_FLEXCOMM_IRQN);
	PRINTF("DI_SPI_Slave_FC5_init \r\n");
}

 

scope_2.png

In this image Yellow (Channel-1) is Slave Select.

Green (Ch2) is SPI_CLOCK.

Purple (Ch3) is MOSI.

Pink (Ch4) is the toggling of output pin which happens whenever the code enters SPI_ISR due to Rx_FIFO_not_empty condition.

0 Kudos
3 Replies

601 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello aswinprabhu,

Could you please check have you received data in SPI_Rx[].

 

Regards,

Alice

 

0 Kudos

564 Views
aswinprabhu
Contributor III

Hello Alice_Yang,

 

Sorry for the delayed response.

I was able to solve the issue by ensuring that the SPI TxFIFO never became empty.

 

(The original code did not do anything to ensure that the TxFIFO had data in it since SPI Tx functionality of the peripheral was not being used. I did not add that piece of code since I felt intuitively that an empty TxFIFO will only result in zeroes being shifted out of the MISO line.

Somehow this resulted in the code generating an SPI interrupt on receiving each bit, as can be seen in the attached image. It may be noted that the generation of interrupt on SPI frame errors was disabled. Anyway, once I ensured that TxFIFO never became empty, the issue was solved).

 

Thanks!

0 Kudos

551 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello aswinprabhu,

OK, thanks very much for your shaing.

 

Regards,

Alice

0 Kudos