I am using FSL_LIN_2x_STACK_PACKAGE_4.5.9 and running an example design for LIN slave on kinetis KEA64.
I want to use the function to transmit a response using the following function but I couldnot see any response from the slave to the master.
Here is my main.c file and the lin_lld_uart.c files.
/*
* main implementation: use this 'C' sample to create your own application
*/
#define MOTOR_SELECTION_INCREASE 1
#define MOTOR_SELECTION_DECREASE 2
#define MOTOR_SELECTION_STOP 3
/**********************************************************************************************
* Global variables
**********************************************************************************************/
l_u8 LIN_counter =0, LED_counter = 0;
l_u8 Motor1_temp = 30;
l_u8 Motor1_Selection;
/***********************************************************************************************
*
* @brief CLK_Init - Initialize the clocks to run at 20 MHz from the 10Mhz external XTAL
* @param none
* @return none
*
************************************************************************************************/
void Clk_Init()
{
ICS_C1|=ICS_C1_IRCLKEN_MASK; /* Enable the internal reference clock*/
ICS_C3= 0x50; /* Reference clock frequency = 39.0625 KHz*/
while(!(ICS_S & ICS_S_LOCK_MASK)); /* Wait for PLL lock, now running at 40 MHz (1024 * 39.0625Khz) */
ICS_C2|=ICS_C2_BDIV(1) ; /*BDIV=2, Bus clock = 20 MHz*/
ICS_S |= ICS_S_LOCK_MASK ; /* Clear Loss of lock sticky bit */
}
/***********************************************************************************************
*
* @brief lin_application_timer_FTM0 - Initialize the timer for LIN application
* @param none
* @return none
*
************************************************************************************************/
void lin_application_timer_FTM0()
{
SIM_SCGC |= SIM_SCGC_FTM0_MASK; /* Enable Clock for FTM0 */
FTM0_SC |= FTM_SC_PS(7); /* Select Preescaler in this case 128. 20 Mhz /128 =156.25 Khz. */
/* Counter increase by one every 6.4 us */
/* Enable Channle 0*/
FTM0_C0SC |= FTM_CnSC_CHIE_MASK; /* Enable channel 0 interrupt */
FTM0_C0SC |= FTM_CnSC_MSA_MASK; /* Channel as Output compare mode */
/*Select interrupt frequency*/
FTM0_C0V = FTM_CnV_VAL(391) ; /* Interrupt every 2.5ms */
FTM0_SC |= FTM_SC_CLKS(1); /*FTM0 use system clock*/
/* Set the ICPR and ISER registers accordingly */
NVIC_ICPR |= 1 << ((INT_FTM0-16)%32);
NVIC_ISER |= 1 << ((INT_FTM0-16)%32);
}
void main()
{
l_u8 ret;
l_u8 vector_number;
//l_u16 i;
Clk_Init();
GPIO_Init();
ret = l_sys_init();
ret = l_ifc_init(LI0);
vector_number = INT_UART0 -16;
NVIC_ICPR |= 1 << (vector_number%32);
NVIC_ISER |= 1 << (vector_number%32);
lin_application_timer_FTM0();
for (;;){
/* Check if temp signal is updated */
if (l_flg_tst_LI0_Motor1Selection_flag()){
/* Clear this flag... */
l_flg_clr_LI0_Motor1Selection_flag();
/* Store selection data */
Motor1_Selection = l_u8_rd_LI0_Motor1Selection();
/* The application will change Motor selection in case
the temperature is greater than maximum value to release motor power
This will be transfered by sporadic frame type in LIN bus */
l_u8_wr_LI0_Motor1Temp(Motor1_temp);
/* Check if power off motor due to high temperature */
if (Motor1_Selection == MOTOR_SELECTION_STOP) {
/*---------- add code here to stop motor ------------*/
}
if (Motor1_Selection == MOTOR_SELECTION_INCREASE){
LED2_ON;
}
if (Motor1_Selection == MOTOR_SELECTION_DECREASE){
LED2_OFF;
}
}
}
}
void FTM0_IRQHandler()
{
if (1==((FTM0_C0SC & FTM_CnSC_CHF_MASK)>>FTM_CnSC_CHF_SHIFT) ) /* If the CHF of the channel is equal to 0 */
{
(void)FTM0_C0SC; /* Read to clear flag */
FTM0_C0SC ^= FTM_CnSC_CHF_MASK; /* Clear flag */
FTM0_C0V = FTM0_C0V + 391 ; /* Refresh interrupt period */
if (LED_counter>=50){
/* Toggle LED for LIN transmission */
/* Reset counter */
LED0_TOGGLE;
lin_lld_uart_tx_response(); //here my slave should transmit a response for the LIN transmission
LED_counter = 0;
if (Motor1_Selection == MOTOR_SELECTION_INCREASE){
Motor1_temp++;
LED2_ON;
LED3_OFF;
}
else if (Motor1_Selection == MOTOR_SELECTION_DECREASE){
Motor1_temp--;
LED2_OFF;
LED3_ON;
}
}
LED_counter++;
}
}
This part of the code or function definition is from lin_lld_uart.c file and this function is declared in lin_lld_uart.h file.
void lin_lld_uart_tx_response
(
)
{
/* calculate checksum */
response_buffer[*(response_buffer)+1] = lin_checksum(response_buffer, pid);
cnt_byte = 1;
/* Send First byte */
pUART->uartd.byte = response_buffer[1];
/* Set LIN Status */
state = SEND_DATA;
} /* End function lin_lld_UART_tx_response() */
How can i transmit a response from slave?
Hi,
Yes, the KEA64 Slave project works on my board. This program is designed in such way when a signal from slave is updated and then a sporadic frame is transmitted from master. So the "for loop in the main program" is not at all executed and I am using PCAN USB pro as my master and PLINView Pro to set the frames. But I donot understand the following part of program. Only the interrupt part with LED toggling is getting executed. And how can I update the signal from slave manually in the program?
if (1==((FTM0_C0SC & FTM_CnSC_CHF_MASK)>>FTM_CnSC_CHF_SHIFT) ) /* If the CHF of the channel is equal to 0 */
{
(void)FTM0_C0SC; /* Read to clear flag */
FTM0_C0SC ^= FTM_CnSC_CHF_MASK; /* Clear flag */
FTM0_C0V = FTM0_C0V + 391 ; /* Refresh interrupt period */
if (LED_counter>=50){
/* Toggle LED for LIN transmission */
/* Reset counter */
LED0_TOGGLE;
LED_counter = 0;
if (Motor1_Selection == MOTOR_SELECTION_INCREASE){
printf("motor1 slave");
Motor1_temp++;
LED2_ON;
LED3_OFF;
}
else if (Motor1_Selection == MOTOR_SELECTION_DECREASE){
Motor1_temp--;
LED2_OFF;
LED3_ON;
}
}
LED_counter++;
}
And as soon as I connected my LIN slave to the master PCANUSB pro the led0 started blinking.
Hi,
Sorry for the later reply.
The LIN Slave application calls the lin_application_timer_FTM0() function, which enable the FTM0 module.
The FTM0 will generate the interrupt every 2.5ms.
In FTM0_IRQHandler() function, the LED0 will toggle every 2.5X50 = 125ms.
When the KEA64 board with board, the LED0 will start toggle without LIN bus working or not.
void lin_application_timer_FTM0()
{
SIM_SCGC |= SIM_SCGC_FTM0_MASK; /* Enable Clock for FTM0 */
FTM0_SC |= FTM_SC_PS(7); /* Select Preescaler in this case 128. 20 Mhz /128 =156.25 Khz. */
/* Counter increase by one every 6.4 us */
/* Enable Channle 0*/
FTM0_C0SC |= FTM_CnSC_CHIE_MASK; /* Enable channel 0 interrupt */
FTM0_C0SC |= FTM_CnSC_MSA_MASK; /* Channel as Output compare mode */
/*Select interrupt frequency*/
FTM0_C0V = FTM_CnV_VAL(391) ; /* Interrupt every 2.5ms */
FTM0_SC |= FTM_SC_CLKS(1); /*FTM0 use system clock*/
/* Set the ICPR and ISER registers accordingly */
NVIC_ICPR |= 1 << ((INT_FTM0-16)%32);
NVIC_ISER |= 1 << ((INT_FTM0-16)%32);
}
Have a great day,
Mike
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
How can I use the function lin_lld_uart_tx_response(); to send a response byte from my slave to master. My slave is receiving only and is not sending any response byte. And the response buffer i filled it with number 9. How can I add lines of code when it receives unconditional frame from master, my slave should respond back with number 9 using the following functions.
lin_lld_uart_rx_response(1);
lin_lld_uart_tx_response();
And how to detect an unconditional frame from the identifier or PID ?
Hi,
The LIN Stack for KEA product demo also provides how to response LIN Master.
The below function called in KEA64_LIN_Slave project will response LIN master with Motor1 Temperature.
l_u8_wr_LI0_Motor1Temp(Motor1_temp);
I had make some change with LIN Master schedule table just with [NormalTable]:
[Motor1Control] is LIN Master send to select motor1;
[Motor1State_Cycl] in LIN Slave send to response the motor1 state (6 bytes).
The 6 bytes located in lin_pFrameBuf[LIN_FRAME_BUF_SIZE] array at <lin_cfg.c> file:
The l_u8_wr_LI0_Motor1Temp(Motor1_temp); function will modify the [Motor1State_Cycl] related data range.
For my LIN bus analyzer tool with some issues, I use scope to capture the LIN bus signal and could find the LIN Slave response data to LIN master.
Please check below LIN Bus communication signals:
After I change the response data value, then I could get below LIN Slave response data changed.
Wish it helps.
Have a great day,
Mike
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Yeah, it means that LED0 will toggle for no matter there is LIN transmission between master and slave. Then it is not compulsory to name the function by "lin_application_timer_FTM0()" and it can be any name right? A timer interrupt is running and LED0 will toggle on this timer interrupt, that's it right? It has nothing to do with LIN transmission from master to slave for LED0.