the min VDR: 14.6 V the max VDR: 14.6 V DR1_ZEFF: 11.00 Ohm DR1_PHASE: 33.60 degree DR1_CURRENT: 431.25 mA ****************************************** (RESP_DIAG Frame): 23 49 49 2C 30 45 54 00 00 28 00 00 28 00 00 38 00 00 28 00 00 28 00 00 28 00 00 38 00 00 88 B7 [18:50:55.312]收←◆ (CMD Frame): 03 14 01 20 00 7F A6 6F 35 1F 0F 00 00 00 00 00 00 00 00 4C 80 8B 04 01 20 02 5D 00 00 00 93 0E [18:50:55.642]收←◆ Response calculated by BaseStation : 5D 76 50 D7 72 E0 Receive Response from Key Fob:1E 20 00 C0 00 95 02 01 5D 76 50 D7 72 E0 1C 75 55 55 55 55 55 55 55 55 55 55 55 55 55 55 57 ******************** ** PKE HT-3 PASS! ** ******************** |
图 1.3 终端程序 SPI 消息帧显示
因为时钟配置在之前 S32K144 Clock Module 中已经介绍过了,这里就不再赘述,只是需要介绍一下,PEPS 方案中所使用到的引脚的复用情况。其中需要注意的是,与 NJJ29C2 RSTN、BUSY 以及 IRQ 相连的引脚是配置成 GPIO,以便执行 NJJ29C2 复位,检查 NJJ29C2 是否正忙(此时需要等待,不能再发 SPI 命令),检查 NJJ29C2 是否有响应。
具体代码如下:
void Port_Init(void) { /* PORT clock enable */ ENABLE_PORT_CLOCK(PCC_PORTA_INDEX); ENABLE_PORT_CLOCK(PCC_PORTB_INDEX); ENABLE_PORT_CLOCK(PCC_PORTC_INDEX); ENABLE_PORT_CLOCK(PCC_PORTD_INDEX);
/* PTC16 is used as GPIO: Simulated IIC SDA */ CFG_PIN_FUNCTION(PORTC, PTC16, Alt1);
/* PTC17 is used as GPIO: Simulated IIC SCL */ CFG_PIN_FUNCTION(PORTC, PTC17, Alt1);
/* GPIO: RGB LED */ CFG_PIN_FUNCTION(PORTD, PTD15, Alt1); /* RED LED */ CFG_PIN_FUNCTION(PORTD, PTD16, Alt1); /* GREEN LED */ CFG_PIN_FUNCTION(PORTD, PTD0, Alt1); /* BLUE LED */
/* Control & Indicator: * PTB11 --> RSTN * PTC10 --> BUSY * PTC11 --> IRQ */ CFG_PIN_FUNCTION(PORTB, PTB11, Alt1);
CFG_PIN_FUNCTION(PORTC, PTC10, Alt1); Port_Internal_Pull_Down(PORTC, PTC10); /* enable pull-down resistor if input configured */
CFG_PIN_FUNCTION(PORTC, PTC11, Alt1); Port_Internal_Pull_Down(PORTC, PTC11); /* enable pull-down resistor if input configured */
/* For Debug: * PTB1 --> LPUART0_TX * PTA2 --> LPUART0_RX */ CFG_PIN_FUNCTION(PORTB, PTB1, Alt2); CFG_PIN_FUNCTION(PORTA, PTA2, Alt6);
/* Connect to PC: * PTC7 --> LPUART1_TX * PTC6 --> LPUART1_RX */ CFG_PIN_FUNCTION(PORTC, PTC7, Alt2); CFG_PIN_FUNCTION(PORTC, PTC6, Alt2);
/* Connect to RF Receiver: * PTD7 --> LPUART2_TX * PTD6 --> LPUART2_RX */ CFG_PIN_FUNCTION(PORTD, PTD7, Alt2); CFG_PIN_FUNCTION(PORTD, PTD6, Alt2);
/* PTB0 is used as LPSPI1_PCS0 * PTB2 is used as LPSPI1_SCK * PTB3 is used as LPSPI1_SIN * PTB4 is used as LPSPI1_SOUT */ CFG_PIN_FUNCTION(PORTB, PTB0, Alt3); CFG_PIN_FUNCTION(PORTB, PTB2, Alt3); CFG_PIN_FUNCTION(PORTB, PTB3, Alt3); CFG_PIN_FUNCTION(PORTB, PTB4, Alt3);
} |
LPUART 接收中断使能,在之前的文档 S32K144 LPUART Module 已经有介绍,就不再说明。
这里只是要介绍一下,由于 SPI 数据的传送(双向,S32K144 à NJJ29C2 以及 S32K144 ß NJJ29C2)是同时发生,如果是按照最基本的方式(发送完数据后再去接收),是无法接收到响应数据的。所以 NXP 推荐了两种方式:一种是中断,另一种则是 DMA。
本篇文章只介绍 LPSPI 中断接收的配置,因为这已经能够实现 S32K144 以及 NJJ29C2 的正常通讯。
另外 NXP 也强调过,在一个完整的命令(32 bytes)收发期间,SCSN 必须保持低电平。因为它的上升沿已经被定义为帧的结束,之后 NJJ29C2 会开始处理。所以如果不能保证 SCSN 在这期间为低电平的话,可能会造成回传的响应时钟重复 Response code(如 0x20)。如果一个数据帧结束之后,如果实际传输的字节数与预期的字节数不一致,也会导致传输数据被丢弃,IRQ 也会变为高电平来通报故障。
关于 LPSPI 初始化的配置代码及说明请参考 附录 1,以下是关于 LPSPI 接收中断的配置代码:
LPSPI.h |
typedef void (*LPSPI_CallbackType) (LPSPI_MemMapPtr pLPSPI); |
LPSPI.c |
LPSPI_CallbackType LPSPI_Callback = NULL; …… void LPSPI_SetCallback(LPSPI_CallbackType pfnCallback) { LPSPI_Callback = pfnCallback; }
void LPSPI0_IRQHandler (void) { LPSPI_Callback (LPSPI0); } |
rssiSingle_Main.c |
void LPSPI0_ISR(LPSPI_MemMapPtr pLPSPI) { /* read received data */ cendricRespData[cendricRespIndex] = LPSPI0->RDR; cendricRespIndex++;
/* the index should not exceed 32 bytes */ cendricRespIndex &= 0x1F; } …… /* LPSPI0 Module Initialization */ LPSPI0_Init_Master();
/* Enable LPSPI0 interrupt */ S32K144_Enable_Interrupt(LPSPI0_IRQn); S32K144_NVIC_SetNonCorePriority(LPSPI0_IRQn, 6); /* priority 6 of 0-15 */
/* set up callback routine */ LPSPI_SetCallback(LPSPI0_ISR); |