当前位置:网站首页>NXP jn5169 uses hardware SPI slave to send and receive data

NXP jn5169 uses hardware SPI slave to send and receive data

2020-12-06 09:22:30 osc_ 72k9vb4y




One 、SPI Introduction to the slave machine

        SPI Bus slave interface allows JN5169 High speed synchronous data transmission with peripheral devices . JN5169 As SPI The slave device on the bus runs , Connect to SPI The external device of the bus acts as the host . Pin and SPI The bus main interface is different , As shown in the following table :

 Insert picture description here


        SPI The bus uses a simple shift register data transmission scheme ,SPISSEL Used as low level effective selective control . Data moves out and into active devices in a first in, first out manner , So as to allow SPI The bus device sends and receives data at the same time . Master output slave input or master input slave output data transmission is relative to the clock signal generated by the external host SPISCLK Of .

SPI The bus slave includes the following functions :

  • Full duplex synchronous data transmission
  • From the machine to the external clock up to 8 MHz
  • Support 8 Bit transfer ( Can be configured first MSB or LSB), Between each transmission SPISSEL Set to invalid
  • Inside FIFO, Maximum 255 Bytes , For sending and receiving
  • standard SPI Bus mode 0; Data is sampled at the positive edge of the clock
  • Maskable interrupt , Used to receive FIFO Not empty , send out FIFO It's empty , receive FIFO Fill level above threshold , send out FIFO Below threshold , send out FIFO overflow , receive FIFO underflow , send out FIFO underflow , Receive timeout
  • The programmable receive timeout period allows an interrupt to be generated , To prompt if no other data arrives during the timeout period , Then read and receive FIFO

Two 、JN5169 Slave code

1、 Interrupt mode

#define MSB		FALSE		//spi Transmit from the highest bit 
#define LSB		TRUE		//spi Transmit from the lowest bit 

uint8 TxBuff[10];		// Send buffer 
uint8 RxBuff[10];		// Receive buffer 

void vCbSpiSlaveInt(uint32 u32Device, uint32 u32ItemBitmap)
{
   
    
	uint8 recv;
    if(E_AHI_DEVICE_SPIS == u32Device){
   
    			//SPI Slave interrupt 
    	if((u32ItemBitmap & (1 << 0)) == E_AHI_SPIS_INT_RX_FIRST_MASK){
   
    
    		vPrintf(" Data is already being received FIFO In the receiving , It used to be empty \n");
    	}
    	if((u32ItemBitmap & (1 << 1)) == E_AHI_SPIS_INT_TX_LAST_MASK){
   
    
    		vPrintf(" send out FIFO The last remaining byte in has been sent , Buffer is empty \n");
    	}
    	if((u32ItemBitmap & (1 << 2)) == E_AHI_SPIS_INT_RX_CLIMB_MASK){
   
    
    		// This interrupt prompts the application to read data from the receive buffer 
    		// Wait for a read threshold interrupt or read timeout interrupt , When one of the interrupts occurs , The user-defined callback function will be called to handle the interrupt 
    		// function  u8AHI_SpiSlaveRxReadByte() Is called in this callback function .
    		vPrintf(" receive FIFO The fill level of has exceeded the configured threshold level \n");
    		recv = u8AHI_SpiSlaveRxReadByte();
    		vPrintf("recv1 = %x\n", recv);
    		recv = u8AHI_SpiSlaveRxReadByte();
    		vPrintf("recv2 = %x\n", recv);
    	}
    	if((u32ItemBitmap & (1 << 3)) == E_AHI_SPIS_INT_TX_FALL_MASK){
   
    
    		// Wait for a write threshold interrupt to prompt a write send  FIFO
    		// When this interrupt occurs , The user-defined callback function will be called to handle the interrupt ,vAHI_SpiSlaveTxWriteByte() Is called in this callback function .
    		// This interrupt prompts the application to write data to the send buffer 
    		// The number of bytes written should not exceed the buffer size minus the buffer write threshold .
    		vPrintf(" send out FIFO The fill level of has dropped below the configured threshold level \n");
    		vAHI_SpiSlaveTxWriteByte(0x99);
    	}
    	if((u32ItemBitmap & (1 << 4)) == E_AHI_SPIS_INT_RX_OVER_MASK){
   
    
    		vPrintf(" Data has been received but received FIFO Full or busy ( So the data is discarded )\n");
    	}
    	if((u32ItemBitmap & (1 << 5)) == E_AHI_SPIS_INT_TX_OVER_MASK){
   
    
    		vPrintf(" send out FIFO Written but full \n");
    	}
    	if((u32ItemBitmap & (1 << 6)) == E_AHI_SPIS_INT_RX_UNDER_MASK){
   
    
    		vPrintf(" receive FIFO Read but empty \n");
    	}
    	if((u32ItemBitmap & (1 << 7)) == E_AHI_SPIS_INT_TX_UNDER_MASK){
   
    
    		vPrintf(" Try to send but send FIFO Empty or not ready ( So by SPI The bus sent 0x00)\n");
    	}
    	if((u32ItemBitmap & (1 << 8)) == E_AHI_SPIS_INT_RX_TIMEOUT_MASK){
   
    
    		// Wait for a read threshold interrupt or read timeout interrupt , When one of the interrupts occurs , The user-defined callback function will be called to handle the interrupt 
    		// function  u8AHI_SpiSlaveRxReadByte() Is called in this callback function .
    		vPrintf(" Receive timeout occurred ( No other data was received during this period )\n");
    		recv = u8AHI_SpiSlaveRxReadByte();
    		vPrintf("recv3 = %x\n", recv);
    	}
    }
}

PUBLIC void vSPI_Slave_Init()
{
   
    
	bAHI_SpiSlaveEnable(FALSE,	//SPISMISO : DIO13, SPISMOSI : DIO12
			MSB,				// High bit starts transmitting 
			TxBuff,				// Send buffer 
			sizeof(TxBuff),		// Send buffer size 
			1,					// Fill threshold of the send buffer , In bytes (0 To 255), This threshold indicates that when sending buffer data size this threshold , The slave should write data to the host 
			RxBuff,				// Receive buffer 
			sizeof(RxBuff),		// Receive buffer size 
			1,					// Fill threshold of receive buffer , In bytes (0 To 255), This threshold indicates that when the receive buffer data size threshold , Data should be read to the receive buffer 
			100,				// Receive timeout , In microseconds (0 To 4095)
			0x1FF				// Interrupt enable bit , It's on here 9 A break 
	);
	vAHI_SpiSlaveRegisterCallback(vCbSpiSlaveInt);// Register interrupt callback function 

	// Write raw data to the send buffer .
	// The number of bytes written must not exceed the size of the buffer .
	// By default , If sent  FIFO  Is empty and the transmission is by remote  SPI  The host starts , be  SPI  The slave will send data bytes  0x00.
	// Because the fill threshold of the send buffer is set to 1, So every time the host reads data from the slave machine , The slave sends a send buffer to the host , Until the send buffer is empty ( fifo )
	vAHI_SpiSlaveTxWriteByte(0x56);
	vAHI_SpiSlaveTxWriteByte(0x57);
	vAHI_SpiSlaveTxWriteByte(0x58);
	vAHI_SpiSlaveTxWriteByte(0x59);
	vAHI_SpiSlaveTxWriteByte(0x60);
}

PUBLIC void AppColdStart(void)
{
   
    
	vAHI_WatchdogStop();
	(void) u32AHI_Init();

	vSPI_Slave_Init();
	vUartInit();

	vAHI_DelayXms(500);

	vPrintf("System init!\n");

	while (1) {
   
    

	}
}

PUBLIC void AppWarmStart(void)
{
   
    
	AppColdStart();
}

design sketch

 Insert picture description here

2、 Polling mode

#define MSB		FALSE		//spi Transmit from the highest bit 
#define LSB		TRUE		//spi Transmit from the lowest bit 

uint8 TxBuff[10];
uint8 RxBuff[10];

PUBLIC void vSPI_Slave_Init()
{
   
    
	bAHI_SpiSlaveEnable(FALSE,	//SPISMISO : DIO13, SPISMOSI : DIO12
			MSB,				// High bit starts transmitting 
			TxBuff,				// Send buffer 
			sizeof(TxBuff),		// Send buffer size 
			1,					// Fill threshold of the send buffer , In bytes (0 To 255), This threshold indicates that when sending buffer data size this threshold , The slave should write data to the host 
			RxBuff,				// Receive buffer 
			sizeof(RxBuff),		// Receive buffer size 
			1,					// Fill threshold of receive buffer , In bytes (0 To 255), This threshold indicates that when the receive buffer data size threshold , Data should be read to the receive buffer 
			100,				// Receive timeout , In microseconds (0 To 4095)
			0x00				// Interrupt enable bit , It's closed here, all interrupted 
	);

	// Write raw data to the send buffer .
	// The number of bytes written must not exceed the size of the buffer .
	// By default , If sent  FIFO  Is empty and the transmission is by remote  SPI  The host starts , be  SPI  The slave will send data bytes  0x00.
	// Because the fill threshold of the send buffer is set to 1, So every time the host reads data from the slave machine , The slave sends a send buffer to the host , Until the send buffer is empty ( fifo )
	vAHI_SpiSlaveTxWriteByte(0x56);
	vAHI_SpiSlaveTxWriteByte(0x57);
	vAHI_SpiSlaveTxWriteByte(0x58);
	vAHI_SpiSlaveTxWriteByte(0x59);
	vAHI_SpiSlaveTxWriteByte(0x60);
}

PUBLIC void AppColdStart(void)
{
   
    
	uint8 sta, len, recv;
	vAHI_WatchdogStop();
	(void) u32AHI_Init();

	vSPI_Slave_Init();
	vUartInit();

	vAHI_DelayXms(500);

	vPrintf("System init!\n");

	// In the actual running time, the serial port is printed and commented out 
	while (1) {
   
    
		sta = u8AHI_SpiSlaveStatus();
		if((sta & 0x01) == E_AHI_SPIS_STAT_RX_AVAIL_MASK){
   
    	// Receive buffer is not empty 
			len = u8AHI_SpiSlaveRxFillLevel();
			//vPrintf(" Receive buffer fill level :%d\n", len);
			if((sta & 0x04) == E_AHI_SPIS_STAT_RX_ABOVE_MASK){
   
    	// Receive buffer fill level above threshold 
				//vPrintf(" receive FIFO The fill level of has exceeded the configured threshold level \n");
				recv = u8AHI_SpiSlaveRxReadByte();
				vPrintf("recv1 = %x\n", recv);
			}
			else{
   
    
				//vPrintf(" receive FIFO The fill level of has dropped below the configured threshold level \n");
			}
		}
		else{
   
    
			//vPrintf(" The receive buffer is empty \n");
		}
		if((sta & 0x02) == E_AHI_SPIS_STAT_TX_PENDING_MASK){
   
    	// Send buffer is not empty 
			len = u8AHI_SpiSlaveTxFillLevel();
			//vPrintf(" Send buffer fill level :%d\n", len);
			if((sta & 0x08) == E_AHI_SPIS_STAT_TX_ABOVE_MASK){
   
    	// Send buffer fill level above threshold 
				//vPrintf(" Send buffer fill level above threshold \n");
			}
			else{
   
    
				//vPrintf(" send out FIFO The fill level of has dropped below the configured threshold level \n");
				vAHI_SpiSlaveTxWriteByte(0x99);
			}
		}
		else{
   
    
			//vPrintf(" The send buffer is empty \n");
			vAHI_SpiSlaveTxWriteByte(0x99);
		}
	}
}

PUBLIC void AppWarmStart(void)
{
   
    
	AppColdStart();
}

design sketch

 Insert picture description here

 Insert picture description here


3、 ... and 、STC15W408AS Host code

#define SPI_S0	0x04
#define SPI_S1	0x08

#define SPIF	0x80	//SPSTAT.7
#define WCOL	0x40	//SPSTAT.6

#define SSIG	0x80	//SPCTL.7
#define SPEN	0x40	//SPCTL.6
#define DORD	0x20	//SPCTL.5
#define MSTR	0x10	//SPCTL.4
#define CPOL	0x08	//SPCTL.3
#define CPHA	0x04	//SPCTL.2
#define SPDHH	0x00	//CPU_CLK/4
#define SPDH	0x01	//CPU_CLK/16
#define SPDL	0x02	//CPU_CLK/64
#define SPDLL	0x03	//CPU_CLK/128

sbit SS   = P1 ^ 2;	//SPI_1 Of SS foot 

void InitSPI_1(void)
{
   
     
	ACC = P_SW1;                                // Switch to the first group SPI
	ACC &= ~(SPI_S0 | SPI_S1);                  //SPI_S0=0 SPI_S1=0
	P_SW1 = ACC;                                //(P1.2/SS, P1.3/MOSI, P1.4/MISO, P1.5/SCLK)

//	ACC = P_SW1;                                // Available for testing U7,U7 The second group was used SPI control Flash
//	ACC &= ~(SPI_S0 | SPI_S1);                  //SPI_S0=1 SPI_S1=0
//	ACC |= SPI_S0;                              //(P2.4/SS_2, P2.3/MOSI_2, P2.2/MISO_2, P2.1/SCLK_2)
//	P_SW1 = ACC;

//	ACC = P_SW1;                                // Switch to the third group SPI
//	ACC &= ~(SPI_S0 | SPI_S1);                  //SPI_S0=0 SPI_S1=1
//	ACC |= SPI_S1;                              //(P5.4/SS_3, P4.0/MOSI_3, P4.1/MISO_3, P4.3/SCLK_3)
//	P_SW1 = ACC;


	SPDAT = 0;                  // initialization SPI data 
	SPSTAT = SPIF | WCOL;       // eliminate SPI Status bit 
	SPCTL = SPEN | MSTR | SSIG | SPDHH;        // Host mode 
}


uchar SPISwap(uchar dat)
{
   
     
	SPDAT = dat;                // Trigger SPI send data 

	while((SPSTAT & SPIF) != SPIF);    // Wait for the send to complete 

	SPSTAT = SPIF | WCOL;       // eliminate SPI Status bit 
	return SPDAT;               // return SPI data 
}

uchar spi_send_byte(uchar dat)
{
   
     
	uchar recv = 0;

	SS = 0;
	recv = SPISwap(dat);
	SS = 1;

	return recv;
}


void main(void)
{
   
     
	InitSPI_1();
	Init_Uart();
	EA = 1;

	Delay500ms();
	Delay500ms();

	printf("System init\r\n");

	while(1) {
   
     

		printf("recv = %x\r\n", spi_send_byte(0x56));

		Delay500ms();
		Delay500ms();
		Delay500ms();
		Delay500ms();
	}

}


版权声明
本文为[osc_ 72k9vb4y]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/20201206091639065z.html