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,
If the LIN Stack V4.5.9 provided LIN slave demo works on your site?
best regards,
Mike
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.