S32 SDK
flexcan_driver.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
65 #include "flexcan_driver.h"
66 #include "interrupt_manager.h"
67 
68 
69 
70 /*******************************************************************************
71  * Definitions
72  ******************************************************************************/
73 
74 #define FLEXCAN_MB_HANDLE_RXFIFO 0U
75 
76 /*******************************************************************************
77  * Variables
78  ******************************************************************************/
79 
80 /* Pointer to runtime state structure.*/
82 
83 /*******************************************************************************
84  * Private Functions
85  ******************************************************************************/
87  uint8_t instance,
88  uint8_t mb_idx,
89  const flexcan_data_info_t *tx_info,
90  uint32_t msg_id,
91  const uint8_t *mb_data,
92  bool isBlocking
93  );
95  uint8_t instance,
96  uint8_t mb_idx,
97  flexcan_msgbuff_t *data,
98  bool isBlocking
99  );
101  uint8_t instance,
102  flexcan_msgbuff_t *data,
103  bool isBlocking
104  );
105 static void FLEXCAN_DRV_CompleteTransfer(uint32_t instance, uint8_t mb_idx);
106 static void FLEXCAN_DRV_CompleteRxMessageFifoData(uint32_t instance);
107 #if FEATURE_CAN_HAS_DMA_ENABLE
108 static void FLEXCAN_DRV_CompleteRxFifoDataDMA(void *parameter, edma_chn_status_t status);
109 #endif
110 
111 /*******************************************************************************
112  * Code
113  ******************************************************************************/
114 
115 /*FUNCTION**********************************************************************
116  *
117  * Function Name : FLEXCAN_DRV_SetBitrate
118  * Description : Set FlexCAN baudrate.
119  * This function will set up all the time segment values. Those time segment
120  * values are passed in by the user and are based on the required baudrate.
121  *
122  * Implements : FLEXCAN_DRV_SetBitrate_Activity
123  *END**************************************************************************/
124 void FLEXCAN_DRV_SetBitrate(uint8_t instance, const flexcan_time_segment_t *bitrate)
125 {
126  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
127  DEV_ASSERT(bitrate != NULL);
128 
129  /* Set time segments*/
130  FLEXCAN_HAL_SetTimeSegments(g_flexcanBase[instance], bitrate);
131 }
132 
133 /*FUNCTION**********************************************************************
134  *
135  * Function Name : FLEXCAN_DRV_SetBitrateCbt
136  * Description : Set FlexCAN bitrate.
137  * This function will set up all the time segment values. Those time segment
138  * values are passed in by the user and are based on the required baudrate.
139  *
140  * Implements : FLEXCAN_DRV_SetBitrateCbt_Activity
141  *END**************************************************************************/
142 void FLEXCAN_DRV_SetBitrateCbt(uint8_t instance, const flexcan_time_segment_t *bitrate)
143 {
144  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
145  DEV_ASSERT(bitrate != NULL);
146 
147  /* Set time segments*/
148  FLEXCAN_HAL_SetTimeSegmentsCbt(g_flexcanBase[instance], bitrate);
149 }
150 
151 /*FUNCTION**********************************************************************
152  *
153  * Function Name : FLEXCAN_DRV_GetBitrate
154  * Description : Get FlexCAN baudrate.
155  * This function will be return the current bit rate settings
156  *
157  * Implements : FLEXCAN_DRV_GetBitrate_Activity
158  *END**************************************************************************/
159 void FLEXCAN_DRV_GetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate)
160 {
161  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
162  DEV_ASSERT(bitrate != NULL);
163 
164  /* Get the time segments*/
165  FLEXCAN_HAL_GetTimeSegments(g_flexcanBase[instance], bitrate);
166 }
167 
168 /*FUNCTION**********************************************************************
169  *
170  * Function Name : FLEXCAN_DRV_SetMasktype
171  * Description : Set RX masking type.
172  * This function will set RX masking type as RX global mask or RX individual
173  * mask.
174  *
175  * Implements : FLEXCAN_DRV_SetRxMaskType_Activity
176  *END**************************************************************************/
178 {
179  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
180 
181  FLEXCAN_HAL_SetRxMaskType(g_flexcanBase[instance], type);
182 }
183 
184 /*FUNCTION**********************************************************************
185  *
186  * Function Name : FLEXCAN_DRV_SetRxFifoGlobalMask
187  * Description : Set Rx FIFO global mask as the 11-bit standard mask or the
188  * 29-bit extended mask.
189  *
190  * Implements : FLEXCAN_DRV_SetRxFifoGlobalMask_Activity
191  *END**************************************************************************/
193  uint8_t instance,
195  uint32_t mask)
196 {
197  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
198 
199  CAN_Type * base = g_flexcanBase[instance];
200 
201  if (id_type == FLEXCAN_MSG_ID_STD)
202  {
203  /* Set standard global mask for RX FIOF*/
205  }
206  else if (id_type == FLEXCAN_MSG_ID_EXT)
207  {
208  /* Set extended global mask for RX FIFO*/
210  }
211  else {
212  /* Should not get here */
213  }
214 }
215 
216 /*FUNCTION**********************************************************************
217  *
218  * Function Name : FLEXCAN_DRV_SetRxMbGlobalMask
219  * Description : Set Rx Message Buffer global mask as the 11-bit standard mask
220  * or the 29-bit extended mask.
221  *
222  * Implements : FLEXCAN_DRV_SetRxMbGlobalMask_Activity
223  *END**************************************************************************/
225  uint8_t instance,
227  uint32_t mask)
228 {
229  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
230 
231  CAN_Type * base = g_flexcanBase[instance];
232 
233  if (id_type == FLEXCAN_MSG_ID_STD)
234  {
235  /* Set standard global mask for RX MB*/
237  }
238  else if (id_type == FLEXCAN_MSG_ID_EXT)
239  {
240  /* Set extended global mask for RX MB*/
242  }
243  else {
244  /* Should not get here */
245  }
246 }
247 
248 /*FUNCTION**********************************************************************
249  *
250  * Function Name : FLEXCAN_DRV_SetRxIndividualMask
251  * Description : Set Rx individual mask as the 11-bit standard mask or the
252  * 29-bit extended mask.
253  *
254  * Implements : FLEXCAN_DRV_SetRxIndividualMask_Activity
255  *END**************************************************************************/
257  uint8_t instance,
259  uint8_t mb_idx,
260  uint32_t mask)
261 {
262  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
263 
264  CAN_Type * base = g_flexcanBase[instance];
265  status_t stat = STATUS_SUCCESS;
266 
267  if (id_type == FLEXCAN_MSG_ID_STD)
268  {
269  /* Set standard individual mask*/
270  stat = FLEXCAN_HAL_SetRxIndividualStdMask(base, mb_idx, mask);
271  }
272  else if (id_type == FLEXCAN_MSG_ID_EXT)
273  {
274  /* Set extended individual mask*/
275  stat = FLEXCAN_HAL_SetRxIndividualExtMask(base, mb_idx, mask);
276  }
277  else {
278  /* Should not get here */
279  }
280 
281  return stat;
282 }
283 
284 /*FUNCTION**********************************************************************
285  *
286  * Function Name : FLEXCAN_DRV_Init
287  * Description : Initialize FlexCAN driver.
288  * This function will select a source clock, reset FlexCAN module, set maximum
289  * number of message buffers, initialize all message buffers as inactive, enable
290  * RX FIFO if needed, mask all mask bits, disable all MB interrupts, enable
291  * FlexCAN normal mode, and enable all the error interrupts if needed.
292  *
293  * Implements : FLEXCAN_DRV_Init_Activity
294  *END**************************************************************************/
296  uint32_t instance,
297  flexcan_state_t *state,
298  const flexcan_user_config_t *data)
299 {
300  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
301  DEV_ASSERT(state != NULL);
302 
303  status_t result;
304  CAN_Type * base = g_flexcanBase[instance];
305  flexcan_time_segment_t bitrate;
306  status_t osifStat;
307  uint32_t i, j;
308 
309  FLEXCAN_HAL_Disable(base);
310 
311 #if FEATURE_CAN_HAS_PE_CLKSRC_SELECT
312  /* Select a source clock for the FlexCAN engine */
313  FLEXCAN_HAL_SelectClock(base, data->pe_clock);
314 #endif
315 
316  /* Enable the CAN clock */
317  FLEXCAN_HAL_Enable(base);
318 
319  /* Initialize FLEXCAN device */
320  FLEXCAN_HAL_Init(base);
321 
322  /* Enable/Disable FD and check FD was set as expected. Setting FD as enabled
323  * might fail if the current CAN instance does not support FD. */
324  FLEXCAN_HAL_SetFDEnabled(base, data->fd_enable);
325  if (FLEXCAN_HAL_IsFDEnabled(base) != data->fd_enable)
326  {
327  return STATUS_ERROR;
328  }
329 
330  /* If the FD feature is enabled, enable the Stuff Bit Count, in order to be
331  * ISO-compliant. */
333 
334  /* Disable the self reception feature if FlexCAN is not in loopback mode. */
335  if (data->flexcanMode != FLEXCAN_LOOPBACK_MODE)
336  {
337  FLEXCAN_HAL_SetSelfReception(base, false);
338  }
339 
340  /* Enable RxFIFO feature, if requested. This might fail if the FD mode is
341  * enabled. */
342  if (data->is_rx_fifo_needed)
343  {
344  result = FLEXCAN_HAL_EnableRxFifo(base, (uint32_t)data->num_id_filters);
345  if (result != STATUS_SUCCESS)
346  {
347  return result;
348  }
349  }
350 
351 #if FEATURE_CAN_HAS_DMA_ENABLE
352  /* Enable DMA support for RxFIFO transfer, if requested. */
354  {
355  result = FLEXCAN_HAL_SetRxFifoDMA(base, true);
356  if (result != STATUS_SUCCESS)
357  {
358  return result;
359  }
360  }
361 #endif
362 
363  /* Select mode */
365 
366  /* Set payload size. */
367  FLEXCAN_HAL_SetPayloadSize(base, data->payload);
368 
369  result = FLEXCAN_HAL_SetMaxMsgBuffNum(base, data->max_num_mb);
370  if (result != STATUS_SUCCESS)
371  {
372  return result;
373  }
374 
375  /* Set bit rate. */
376  bitrate = data->bitrate;
377  FLEXCAN_HAL_SetTimeSegments(base, &bitrate);
378  if (FLEXCAN_HAL_IsFDEnabled(base))
379  {
380  bitrate = data->bitrate_cbt;
381  FLEXCAN_HAL_SetTimeSegmentsCbt(base, &bitrate);
382  }
383 
384  /* Enable FlexCAN interrupts.*/
385  if (g_flexcanWakeUpIrqId[instance] != NotAvail_IRQn)
386  {
388  }
391  for (i = 0; i < FEATURE_CAN_MB_IRQS_MAX_COUNT; i++)
392  {
394  {
396  }
397  }
398 
399  for (i = 0; i < FEATURE_CAN_MAX_MB_NUM; i++)
400  {
401  osifStat = OSIF_SemaCreate(&state->mbs[i].mbSema, 0U);
402  if (osifStat != STATUS_SUCCESS)
403  {
404  for (j = 0; j < i; j++)
405  {
406  (void)OSIF_SemaDestroy(&state->mbs[j].mbSema);
407  }
408  return STATUS_ERROR;
409  }
410  state->mbs[i].isBlocking = false;
411  state->mbs[i].mb_message = NULL;
412  state->mbs[i].state = FLEXCAN_MB_IDLE;
413  }
414 
415  /* Store transfer type and DMA channel number used in transfer */
416  state->transferType = data->transfer_type;
417 #if FEATURE_CAN_HAS_DMA_ENABLE
418  state->rxFifoDMAChannel = data->rxFifoDMAChannel;
419 #endif
420 
421  /* Save runtime structure pointers so irq handler can point to the correct state structure */
422  g_flexcanStatePtr[instance] = state;
423 
424  return (STATUS_SUCCESS);
425 }
426 
427 /*FUNCTION**********************************************************************
428  *
429  * Function Name : FLEXCAN_DRV_ConfigTxMb
430  * Description : Configure a Tx message buffer.
431  * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
432  * the function will make sure if the MB requested is not occupied by RX FIFO
433  * and ID filter table. Then this function will set up the message buffer fields,
434  * configure the message buffer code for Tx buffer as INACTIVE, and enable the
435  * Message Buffer interrupt.
436  *
437  * Implements : FLEXCAN_DRV_ConfigTxMb_Activity
438  *END**************************************************************************/
440  uint8_t instance,
441  uint8_t mb_idx,
442  const flexcan_data_info_t *tx_info,
443  uint32_t msg_id)
444 {
445  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
446  DEV_ASSERT(tx_info != NULL);
447 
449  CAN_Type * base = g_flexcanBase[instance];
450 
451  /* Initialize transmit mb*/
452  cs.dataLen = tx_info->data_length;
453  cs.msgIdType = tx_info->msg_id_type;
454  if (tx_info->is_remote)
455  {
456  cs.code = (uint32_t)FLEXCAN_TX_REMOTE;
457  }
458  else
459  {
460  cs.code = (uint32_t)FLEXCAN_TX_INACTIVE;
461  }
462  return FLEXCAN_HAL_SetTxMsgBuff(base, mb_idx, &cs, msg_id, NULL);
463 }
464 
465 /*FUNCTION**********************************************************************
466  *
467  * Function Name : FLEXCAN_DRV_SendBlocking
468  * Description : This function sends a CAN frame using a configured message
469  * buffer. The function blocks until either the frame was sent, or the specified
470  * timeout expired.
471  *
472  * Implements : FLEXCAN_DRV_SendBlocking_Activity
473  *END**************************************************************************/
475  uint8_t instance,
476  uint8_t mb_idx,
477  const flexcan_data_info_t *tx_info,
478  uint32_t msg_id,
479  const uint8_t *mb_data,
480  uint32_t timeout_ms)
481 {
482  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
483  DEV_ASSERT(tx_info != NULL);
484 
485  status_t result;
486  flexcan_state_t * state = g_flexcanStatePtr[instance];
487  CAN_Type * base = g_flexcanBase[instance];
488 
489  result = FLEXCAN_DRV_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data, true);
490 
491  if(result == STATUS_SUCCESS)
492  {
493  status_t status;
494 
495  /* Enable message buffer interrupt*/
496  (void)FLEXCAN_HAL_SetMsgBuffIntCmd(base, mb_idx, true);
497  /* Enable error interrupts */
499 
500  status = OSIF_SemaWait(&state->mbs[mb_idx].mbSema, timeout_ms);
501 
502  if (status == STATUS_SUCCESS)
503  {
504  state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
505  FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, (1UL << mb_idx));
506  result = STATUS_SUCCESS;
507  }
508  else
509  {
510  state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
511  result = STATUS_TIMEOUT;
512  }
513  }
514 
515  return result;
516 }
517 
518 /*FUNCTION**********************************************************************
519  *
520  * Function Name : FLEXCAN_DRV_Send
521  * Description : This function sends a CAN frame using a configured message
522  * buffer. The function returns immediately. If a callback is installed, it will
523  * be invoked after the frame was sent.
524  *
525  * Implements : FLEXCAN_DRV_Send_Activity
526  *END**************************************************************************/
528  uint8_t instance,
529  uint8_t mb_idx,
530  const flexcan_data_info_t *tx_info,
531  uint32_t msg_id,
532  const uint8_t *mb_data)
533 {
534  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
535  DEV_ASSERT(tx_info != NULL);
536 
537  status_t result;
538  CAN_Type * base = g_flexcanBase[instance];
539 
540  result = FLEXCAN_DRV_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data, false);
541  if(result == STATUS_SUCCESS)
542  {
543  /* Enable message buffer interrupt*/
544  result = FLEXCAN_HAL_SetMsgBuffIntCmd(base, mb_idx, true);
545  /* Enable error interrupts */
547  }
548 
549  return result;
550 }
551 
552 /*FUNCTION**********************************************************************
553  *
554  * Function Name : FLEXCAN_DRV_ConfigMb
555  * Description : Configure a Rx message buffer.
556  * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
557  * the function will make sure if the MB requested is not occupied by RX FIFO
558  * and ID filter table. Then this function will set up the message buffer fields,
559  * configure the message buffer code for Rx message buffer as NOT_USED, enable
560  * the Message Buffer interrupt, configure the message buffer code for Rx
561  * message buffer as INACTIVE, copy user's buffer into the message buffer data
562  * area, and configure the message buffer code for Rx message buffer as EMPTY.
563  *
564  * Implements : FLEXCAN_DRV_ConfigRxMb_Activity
565  *END**************************************************************************/
567  uint8_t instance,
568  uint8_t mb_idx,
569  const flexcan_data_info_t *rx_info,
570  uint32_t msg_id)
571 {
572  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
573  DEV_ASSERT(rx_info != NULL);
574 
575  status_t result;
577  CAN_Type * base = g_flexcanBase[instance];
578 
579  cs.dataLen = rx_info->data_length;
580  cs.msgIdType = rx_info->msg_id_type;
581  cs.fd_enable = rx_info->fd_enable;
582  /* Initialize rx mb*/
583  cs.code = (uint32_t)FLEXCAN_RX_NOT_USED;
584  result = FLEXCAN_HAL_SetRxMsgBuff(base, mb_idx, &cs, msg_id);
585  if (result != STATUS_SUCCESS)
586  {
587  return result;
588  }
589 
590  /* Initialize receive MB*/
591  cs.code = (uint32_t)FLEXCAN_RX_INACTIVE;
592  result = FLEXCAN_HAL_SetRxMsgBuff(base, mb_idx, &cs, msg_id);
593  if (result != STATUS_SUCCESS)
594  {
595  return result;
596  }
597 
598  /* Set up FlexCAN message buffer fields for receiving data*/
599  cs.code = (uint32_t)FLEXCAN_RX_EMPTY;
600  return FLEXCAN_HAL_SetRxMsgBuff(base, mb_idx, &cs, msg_id);
601 }
602 
603 /*FUNCTION**********************************************************************
604  *
605  * Function Name : FLEXCAN_DRV_ConfigRxFifo
606  * Description : Confgure RX FIFO ID filter table elements.
607  * This function will confgure RX FIFO ID filter table elements, and enable RX
608  * FIFO interrupts.
609  *
610  * Implements : FLEXCAN_DRV_ConfigRxFifo_Activity
611  *END**************************************************************************/
613  uint8_t instance,
615  const flexcan_id_table_t *id_filter_table)
616 {
617  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
618 
619  CAN_Type * base = g_flexcanBase[instance];
620 
621  /* Initialize rx fifo*/
622  FLEXCAN_HAL_SetRxFifoFilter(base, id_format, id_filter_table);
623 }
624 
625 /*FUNCTION**********************************************************************
626  *
627  * Function Name : FLEXCAN_DRV_ReceiveBlocking
628  * Description : This function receives a CAN frame into a configured message
629  * buffer. The function blocks until either a frame was received, or the
630  * specified timeout expired.
631  *
632  * Implements : FLEXCAN_DRV_ReceiveBlocking_Activity
633  *END**************************************************************************/
635  uint8_t instance,
636  uint8_t mb_idx,
637  flexcan_msgbuff_t *data,
638  uint32_t timeout_ms)
639 {
640  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
641 
642  status_t result;
643  flexcan_state_t * state = g_flexcanStatePtr[instance];
644  CAN_Type * base = g_flexcanBase[instance];
645 
646  result = FLEXCAN_DRV_StartRxMessageBufferData(instance, mb_idx, data, true);
647 
648  if(result == STATUS_SUCCESS)
649  {
650  status_t status;
651 
652  status = OSIF_SemaWait(&state->mbs[mb_idx].mbSema, timeout_ms);
653 
654  if (status == STATUS_SUCCESS)
655  {
656  state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
657  FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, (1UL << mb_idx));
658  result = FLEXCAN_HAL_GetMsgBuff(base, mb_idx, data);
659  }
660  else
661  {
662  state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
663  return STATUS_TIMEOUT;
664  }
665  }
666 
667  return result;
668 }
669 
670 /*FUNCTION**********************************************************************
671  *
672  * Function Name : FLEXCAN_DRV_Receive
673  * Description : This function receives a CAN frame into a configured message
674  * buffer. The function returns immediately. If a callback is installed, it will
675  * be invoked after the frame was received and read into the specified buffer.
676  *
677  * Implements : FLEXCAN_DRV_Receive_Activity
678  *END**************************************************************************/
680  uint8_t instance,
681  uint8_t mb_idx,
682  flexcan_msgbuff_t *data)
683 {
684  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
685 
686  status_t result;
687 
688  result = FLEXCAN_DRV_StartRxMessageBufferData(instance, mb_idx, data, false);
689 
690  return result;
691 }
692 
693 /*FUNCTION**********************************************************************
694  *
695  * Function Name : FLEXCAN_DRV_RxFifoBlocking
696  * Description : This function receives a CAN frame using the Rx FIFO. The
697  * function blocks until either a frame was received, or the specified timeout
698  * expired.
699  *
700  * Implements : FLEXCAN_DRV_RxFifoBlocking_Activity
701  *END**************************************************************************/
703  uint8_t instance,
704  flexcan_msgbuff_t *data,
705  uint32_t timeout_ms)
706 {
707  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
708 
709  status_t result;
710  flexcan_state_t * state = g_flexcanStatePtr[instance];
711 
712  result = FLEXCAN_DRV_StartRxMessageFifoData(instance, data, true);
713 
714  if(result == STATUS_SUCCESS)
715  {
716  result = OSIF_SemaWait(&state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mbSema, timeout_ms);
717 
719  }
720 
721  return result;
722 }
723 
724 /*FUNCTION**********************************************************************
725  *
726  * Function Name : FLEXCAN_DRV_RxFifo
727  * Description : This function receives a CAN frame using the Rx FIFO. The
728  * function returns immediately. If a callback is installed, it will be invoked
729  * after the frame was received and read into the specified buffer.
730  *
731  * Implements : FLEXCAN_DRV_RxFifo_Activity
732  *END**************************************************************************/
734  uint8_t instance,
735  flexcan_msgbuff_t *data)
736 {
737  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
738 
739  status_t result;
740 
741  result = FLEXCAN_DRV_StartRxMessageFifoData(instance, data, false);
742 
743  return result;
744 }
745 
746 /*FUNCTION**********************************************************************
747  *
748  * Function Name : FLEXCAN_DRV_Deinit
749  * Description : Shutdown a FlexCAN module.
750  * This function will disable all FlexCAN interrupts, and disable the FlexCAN.
751  *
752  * Implements : FLEXCAN_DRV_Deinit_Activity
753  *END**************************************************************************/
754 status_t FLEXCAN_DRV_Deinit(uint8_t instance)
755 {
756  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
757 
758  const flexcan_state_t * state = g_flexcanStatePtr[instance];
759  status_t result = STATUS_SUCCESS;
760  status_t osifStat;
761  uint32_t i;
762 
763  /* Disable FlexCAN interrupts.*/
764  if (g_flexcanWakeUpIrqId[instance] != NotAvail_IRQn)
765  {
767  }
770  for (i = 0; i < FEATURE_CAN_MB_IRQS_MAX_COUNT; i++)
771  {
773  {
775  }
776  }
777 
778  /* Disable FlexCAN.*/
780 
781  for (i = 0; i < FEATURE_CAN_MAX_MB_NUM; i++)
782  {
783  osifStat = OSIF_SemaDestroy(&state->mbs[i].mbSema);
784  if (osifStat != STATUS_SUCCESS)
785  {
786  result = STATUS_ERROR;
787  }
788  }
789 
790  return result;
791 }
792 /*FUNCTION**********************************************************************
793  *
794  * Function Name : FLEXCAN_DRV_IRQHandler
795  * Description : Interrupt handler for FLEXCAN.
796  * This handler read data from MB or FIFO, and then clear the interrupt flags.
797  * This is not a public API as it is called whenever an interrupt occurs.
798  *
799  * Implements : FLEXCAN_DRV_IRQHandler_Activity
800  *END**************************************************************************/
801 void FLEXCAN_DRV_IRQHandler(uint8_t instance)
802 {
803  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
804 
805  uint32_t flag_reg;
806  CAN_Type * base = g_flexcanBase[instance];
807  flexcan_state_t * state = g_flexcanStatePtr[instance];
808  status_t result = STATUS_SUCCESS;
809 
810  /* Get the interrupts that are enabled and ready */
812 
813  /* Check Tx/Rx interrupt flag and clear the interrupt */
814  if(flag_reg != 0U)
815  {
816  uint8_t mb_idx = 0;
817  while ((flag_reg & 1U) == 0U)
818  {
819  flag_reg >>= 1U;
820  ++mb_idx;
821  }
822 
823  bool rxfifoEnabled = FLEXCAN_HAL_IsRxFifoEnabled(base);
824  if ((mb_idx == FEATURE_CAN_RXFIFO_FRAME_AVAILABLE) && rxfifoEnabled)
825  {
827  {
828  /* Get RX FIFO field values */
830 
831  /* Complete receive data */
833  FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, 1UL << mb_idx);
834 
835  /* Invoke callback */
836  if (state->callback != NULL)
837  {
838  state->callback(instance, FLEXCAN_EVENT_RXFIFO_COMPLETE, state);
839  }
840  }
841  }
842  else
843  {
844  /* Check mailbox completed reception */
845  if (state->mbs[mb_idx].state == FLEXCAN_MB_RX_BUSY)
846  {
847  /* Unlock RX message buffer and RX FIFO*/
848  result = FLEXCAN_HAL_LockRxMsgBuff(base, mb_idx);
849  if (result == STATUS_SUCCESS)
850  {
851  /* Get RX MB field values*/
852  result = FLEXCAN_HAL_GetMsgBuff(base, mb_idx, state->mbs[mb_idx].mb_message);
853  }
854  if (result == STATUS_SUCCESS)
855  {
856  /* Unlock RX message buffer and RX FIFO*/
858 
859  /* Complete receive data */
860  FLEXCAN_DRV_CompleteTransfer(instance, mb_idx);
861  FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, 1UL << mb_idx);
862 
863  /* Invoke callback */
864  if (state->callback != NULL)
865  {
866  state->callback(instance, FLEXCAN_EVENT_RX_COMPLETE, state);
867  }
868  }
869  }
870  }
871 
872  /* Check mailbox completed transmission */
873  if (state->mbs[mb_idx].state == FLEXCAN_MB_TX_BUSY)
874  {
875  /* Complete transmit data */
876  FLEXCAN_DRV_CompleteTransfer(instance, mb_idx);
877 
878  if (state->mbs[mb_idx].isRemote)
879  {
880  /* If the frame was a remote frame, clear the flag only if the response was
881  * not received yet. If the response was received, leave the flag set in order
882  * to be handled when the user calls FLEXCAN_DRV_RxMessageBuffer. */
884  (void) FLEXCAN_HAL_LockRxMsgBuff(base, mb_idx);
885  (void) FLEXCAN_HAL_GetMsgBuff(base, mb_idx, &mb);
887 
888  if (((mb.cs & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32_t)FLEXCAN_RX_EMPTY)
889  {
890  FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, 1UL << mb_idx);
891  }
892  }
893  else
894  {
895  FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, 1UL << mb_idx);
896  }
897 
898  /* Invoke callback */
899  if (state->callback != NULL)
900  {
901  state->callback(instance, FLEXCAN_EVENT_TX_COMPLETE, state);
902  }
903  }
904  }
905 
906  /* Clear all other interrupts in ERRSTAT register (Error, Busoff, Wakeup) */
908 
909  return;
910 }
911 
912 #if FEATURE_CAN_HAS_PRETENDED_NETWORKING
913 
914 /*FUNCTION**********************************************************************
915  *
916  * Function Name : FLEXCAN_DRV_WakeUpHandler
917  * Description : Wake up handler for FLEXCAN.
918  * This handler verifies the event which caused the wake up and invokes the
919  * user callback, if configured.
920  * This is not a public API as it is called whenever an wake up event occurs.
921  *
922  *END**************************************************************************/
923 void FLEXCAN_DRV_WakeUpHandler(uint8_t instance)
924 {
925  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
926 
927  CAN_Type * base = g_flexcanBase[instance];
928  flexcan_state_t * state = g_flexcanStatePtr[instance];
929 
930  uint32_t flag = base->WU_MTC;
931 
932  /* Invoke callback */
933  if (state->callback != NULL)
934  {
935  if ((flag & CAN_WU_MTC_WTOF_MASK) != 0U)
936  {
937  base->WU_MTC |= CAN_WU_MTC_WTOF_MASK;
938  state->callback(instance, FLEXCAN_EVENT_WAKEUP_TIMEOUT, state);
939  }
940  if ((flag & CAN_WU_MTC_WUMF_MASK) != 0U)
941  {
942  base->WU_MTC |= CAN_WU_MTC_WUMF_MASK;
943  state->callback(instance, FLEXCAN_EVENT_WAKEUP_MATCH, state);
944  }
945  }
946 }
947 
948 #endif /* FEATURE_CAN_HAS_PRETENDED_NETWORKING */
949 
950 /*FUNCTION**********************************************************************
951  *
952  * Function Name : FLEXCAN_DRV_GetTransferStatus
953  * Description : This function returns whether the previous FLEXCAN receive is
954  * completed.
955  * When performing a non-blocking receive, the user can call this function to
956  * ascertain the state of the current receive progress: in progress (or busy)
957  * or complete (success).
958  *
959  * Implements : FLEXCAN_DRV_GetTransferStatus_Activity
960  *END**************************************************************************/
961 status_t FLEXCAN_DRV_GetTransferStatus(uint32_t instance, uint8_t mb_idx)
962 {
963  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
964 
965  const flexcan_state_t * state = g_flexcanStatePtr[instance];
966  status_t status;
967 
968  if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
969  {
970  status = STATUS_SUCCESS;
971  }
972  else
973  {
974  status = STATUS_BUSY;
975  }
976 
977  return status;
978 }
979 
980 /*FUNCTION**********************************************************************
981  *
982  * Function Name : FLEXCAN_DRV_AbortTransfer
983  * Description : This function shuts down the FLEXCAN by disabling interrupts and
984  * the transmitter/receiver.
985  * This function disables the FLEXCAN interrupts, disables the transmitter and
986  * receiver.
987  *
988  * Implements : FLEXCAN_DRV_AbortTransfer_Activity
989  *END**************************************************************************/
990 status_t FLEXCAN_DRV_AbortTransfer(uint32_t instance, uint8_t mb_idx)
991 {
992  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
993 
994  const flexcan_state_t * state = g_flexcanStatePtr[instance];
995 
996  /* Check if a transfer is running. */
997  if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
998  {
1000  }
1001 
1002  /* Stop the running transfer. */
1003  FLEXCAN_DRV_CompleteTransfer(instance, mb_idx);
1004 
1005  return STATUS_SUCCESS;
1006 }
1007 
1008 /*FUNCTION**********************************************************************
1009  *
1010  * Function Name : FLEXCAN_DRV_StartSendData
1011  * Description : Initiate (start) a transmit by beginning the process of
1012  * sending data.
1013  * This is not a public API as it is called from other driver functions.
1014  *
1015  *END**************************************************************************/
1017  uint8_t instance,
1018  uint8_t mb_idx,
1019  const flexcan_data_info_t *tx_info,
1020  uint32_t msg_id,
1021  const uint8_t *mb_data,
1022  bool isBlocking
1023  )
1024 {
1025  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
1026  DEV_ASSERT(tx_info != NULL);
1027 
1028  status_t result;
1030  flexcan_state_t * state = g_flexcanStatePtr[instance];
1031  CAN_Type * base = g_flexcanBase[instance];
1032 
1033  if (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE)
1034  {
1035  return STATUS_BUSY;
1036  }
1037  state->mbs[mb_idx].state = FLEXCAN_MB_TX_BUSY;
1038  state->mbs[mb_idx].isBlocking = isBlocking;
1039  state->mbs[mb_idx].isRemote = tx_info->is_remote;
1040 
1041  cs.dataLen = tx_info->data_length;
1042  cs.msgIdType = tx_info->msg_id_type;
1043 
1044  cs.fd_enable = tx_info->fd_enable;
1045  cs.fd_padding = tx_info->fd_padding;
1046  cs.enable_brs = tx_info->enable_brs;
1047  if (tx_info->is_remote)
1048  {
1049  cs.code = (uint32_t)FLEXCAN_TX_REMOTE;
1050  }
1051  else
1052  {
1053  cs.code = (uint32_t)FLEXCAN_TX_DATA;
1054  }
1055  result = FLEXCAN_HAL_SetTxMsgBuff(base, mb_idx, &cs, msg_id, mb_data);
1056 
1057  if (result != STATUS_SUCCESS)
1058  {
1059  state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
1060  }
1061 
1062  return result;
1063 }
1064 
1065 /*FUNCTION**********************************************************************
1066  *
1067  * Function Name : FLEXCAN_DRV_StartRxMessageBufferData
1068  * Description : Initiate (start) a receive by beginning the process of
1069  * receiving data and enabling the interrupt.
1070  * This is not a public API as it is called from other driver functions.
1071  *
1072  *END**************************************************************************/
1074  uint8_t instance,
1075  uint8_t mb_idx,
1076  flexcan_msgbuff_t *data,
1077  bool isBlocking
1078  )
1079 {
1080  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
1081 
1082  status_t result = STATUS_SUCCESS;
1083  CAN_Type * base = g_flexcanBase[instance];
1084  flexcan_state_t * state = g_flexcanStatePtr[instance];
1085 
1086  /* Start receiving mailbox */
1087  if(state->mbs[mb_idx].state != FLEXCAN_MB_IDLE)
1088  {
1089  return STATUS_BUSY;
1090  }
1091  state->mbs[mb_idx].state = FLEXCAN_MB_RX_BUSY;
1092  state->mbs[mb_idx].mb_message = data;
1093  state->mbs[mb_idx].isBlocking = isBlocking;
1094 
1095  /* Enable MB interrupt*/
1096  result = FLEXCAN_HAL_SetMsgBuffIntCmd(base, mb_idx, true);
1097  /* Enable error interrupts */
1099 
1100  if (result != STATUS_SUCCESS)
1101  {
1102  state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
1103  }
1104 
1105  return result;
1106 }
1107 
1108 
1109 /*FUNCTION**********************************************************************
1110  *
1111  * Function Name : FLEXCAN_DRV_StartRxMessageFifoData
1112  * Description : Initiate (start) a receive by beginning the process of
1113  * receiving data and enabling the interrupt.
1114  * This is not a public API as it is called from other driver functions.
1115  *
1116  *END**************************************************************************/
1118  uint8_t instance,
1119  flexcan_msgbuff_t *data,
1120  bool isBlocking
1121  )
1122 {
1123  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
1124 
1125  CAN_Type * base = g_flexcanBase[instance];
1126  flexcan_state_t * state = g_flexcanStatePtr[instance];
1127 #if FEATURE_CAN_HAS_DMA_ENABLE
1128  status_t edmaStat;
1129 #endif
1130 
1131  /* Start receiving fifo */
1133  {
1134  return STATUS_BUSY;
1135  }
1136  /* Check if RxFIFO feature is enabled */
1137  if (!FLEXCAN_HAL_IsRxFifoEnabled(base))
1138  {
1139  return STATUS_ERROR;
1140  }
1141 
1143 
1144  state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].isBlocking = isBlocking;
1145 
1146  /* This will get filled by the interrupt handler */
1147  state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mb_message = data;
1148 
1149 #if FEATURE_CAN_HAS_DMA_ENABLE
1150  if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
1151  {
1152  status_t edmaStatus;
1153 
1154  edmaStatus = EDMA_DRV_InstallCallback(state->rxFifoDMAChannel,
1155  FLEXCAN_DRV_CompleteRxFifoDataDMA,
1156  (void *)((uint32_t)instance));
1157 
1158  if (edmaStatus != STATUS_SUCCESS)
1159  {
1161  return STATUS_ERROR;
1162  }
1163 
1164  edmaStatus = EDMA_DRV_ConfigSingleBlockTransfer(state->rxFifoDMAChannel,
1166  (uint32_t)(base->RAMn),
1167  (uint32_t)(state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mb_message),
1169  16U);
1170 
1171  if (edmaStatus != STATUS_SUCCESS)
1172  {
1174  return STATUS_ERROR;
1175  }
1176 
1177  edmaStat = EDMA_DRV_StartChannel(state->rxFifoDMAChannel);
1178  if (edmaStat != STATUS_SUCCESS)
1179  {
1181  return STATUS_ERROR;
1182  }
1183 
1184  return STATUS_SUCCESS;
1185  }
1186 #endif
1187 
1188  /* Enable RX FIFO interrupts*/
1192 
1193  /* Enable error interrupts */
1195 
1196  return STATUS_SUCCESS;
1197 }
1198 
1199 /*FUNCTION**********************************************************************
1200  *
1201  * Function Name : FLEXCAN_DRV_CompleteTransfer
1202  * Description : Finish up a transmit by completing the process of sending
1203  * data and disabling the interrupt.
1204  * This is not a public API as it is called from other driver functions.
1205  *
1206  *END**************************************************************************/
1207 static void FLEXCAN_DRV_CompleteTransfer(uint32_t instance, uint8_t mb_idx)
1208 {
1209  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
1210 
1211  CAN_Type * base = g_flexcanBase[instance];
1212  flexcan_state_t * state = g_flexcanStatePtr[instance];
1213 
1214  /* Disable the transmitter data register empty interrupt */
1215  (void)FLEXCAN_HAL_SetMsgBuffIntCmd(base, mb_idx, false);
1216  /* Disable error interrupts */
1218 
1219  /* Update the information of the module driver state */
1220  if (state->mbs[mb_idx].isBlocking)
1221  {
1222  (void)OSIF_SemaPost(&state->mbs[mb_idx].mbSema);
1223  }
1224  state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
1225 }
1226 
1227 #if FEATURE_CAN_HAS_DMA_ENABLE
1228 /*FUNCTION**********************************************************************
1229  *
1230  * Function Name : FLEXCAN_DRV_CompleteRxFifoDataDMA
1231  * Description : Finish up a DMA transfer (this is just a wrapper over
1232  * FLEXCAN_DRV_CompleteRxMessageFifoData).
1233  * This is not a public API as it is called from other driver functions.
1234  *
1235  *END**************************************************************************/
1236 static void FLEXCAN_DRV_CompleteRxFifoDataDMA(void *parameter, edma_chn_status_t status)
1237 {
1238  uint32_t instance = (uint32_t)parameter;
1239  (void)status;
1240 
1242 }
1243 #endif
1244 
1245 /*FUNCTION**********************************************************************
1246  *
1247  * Function Name : FLEXCAN_DRV_CompleteRxMessageFifoData
1248  * Description : Finish up a receive by completing the process of receiving
1249  * data and disabling the interrupt.
1250  * This is not a public API as it is called from other driver functions.
1251  *
1252  *END**************************************************************************/
1253 static void FLEXCAN_DRV_CompleteRxMessageFifoData(uint32_t instance)
1254 {
1255  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
1256 
1257  CAN_Type * base = g_flexcanBase[instance];
1258  flexcan_state_t * state = g_flexcanStatePtr[instance];
1259 
1261  {
1262  /* Disable RX FIFO interrupts*/
1266 
1267  /* Disable error interrupts */
1269  }
1270 #if FEATURE_CAN_HAS_DMA_ENABLE
1271  else
1272  {
1273  flexcan_msgbuff_t *fifo_message = state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mb_message;
1274  uint32_t *msgData_32 = (uint32_t *)fifo_message->data;
1275 
1276  (void) EDMA_DRV_StopChannel(state->rxFifoDMAChannel);
1277  /* Adjust the ID if it is not extended */
1278  if (((fifo_message->cs) & CAN_CS_IDE_MASK) == 0U)
1279  {
1280  fifo_message->msgId = fifo_message->msgId >> CAN_ID_STD_SHIFT;
1281  }
1282  /* Extract the data length */
1283  fifo_message->dataLen = (uint8_t)((fifo_message->cs & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
1284  /* Reverse the endianness */
1285  REV_BYTES_32(msgData_32[0], msgData_32[0]);
1286  REV_BYTES_32(msgData_32[1], msgData_32[1]);
1287  }
1288 #endif
1289  /* Clear fifo message*/
1290  state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mb_message = NULL;
1291 
1292  /* Update status for receive by using fifo*/
1294  {
1296  }
1298 }
1299 
1300 /*FUNCTION**********************************************************************
1301  *
1302  * Function Name : FLEXCAN_DRV_InstallEventCallback
1303  * Description : Installs a callback function for the IRQ handler.
1304  *
1305  * Implements : FLEXCAN_DRV_InstallEventCallback_Activity
1306  *END**************************************************************************/
1307 void FLEXCAN_DRV_InstallEventCallback(uint8_t instance, flexcan_callback_t callback, void *callbackParam)
1308 {
1309  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
1310 
1311  flexcan_state_t * state = g_flexcanStatePtr[instance];
1312 
1313  state->callback = callback;
1314  state->callbackParam = callbackParam;
1315 }
1316 
1317 #if FEATURE_CAN_HAS_PRETENDED_NETWORKING
1318 
1319 /*FUNCTION**********************************************************************
1320  *
1321  * Function Name : FLEXCAN_DRV_ConfigPN
1322  * Description : Configures Pretended Networking settings.
1323  *
1324  * Implements : FLEXCAN_DRV_ConfigPN_Activity
1325  *END**************************************************************************/
1326 void FLEXCAN_DRV_ConfigPN(uint8_t instance, bool enable, const flexcan_pn_config_t *pnConfig)
1327 {
1328  DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
1329 
1330  CAN_Type * base = g_flexcanBase[instance];
1331 
1333 
1334  if (enable)
1335  {
1336  FLEXCAN_HAL_ConfigPN(base, pnConfig);
1337  }
1338 
1339  FLEXCAN_HAL_SetPN(base, enable);
1340 
1342 }
1343 
1344 #endif /* FEATURE_CAN_HAS_PRETENDED_NETWORKING */
1345 
1346 
1347 /*******************************************************************************
1348  * EOF
1349  ******************************************************************************/
const IRQn_Type g_flexcanOredMessageBufferIrqId[CAN_INSTANCE_COUNT][FEATURE_CAN_MB_IRQS_MAX_COUNT]
Table to save message buffer IRQ numbers for FlexCAN instances.
const IRQn_Type g_flexcanBusOffIrqId[CAN_INSTANCE_COUNT]
Table to save Bus off IRQ numbers for FlexCAN instances.
#define FEATURE_CAN_RXFIFO_FRAME_AVAILABLE
status_t FLEXCAN_HAL_SetRxFifoDMA(CAN_Type *base, bool enable)
Enables/Disables the DMA support for RxFIFO.
void FLEXCAN_HAL_SetRxMsgBuffGlobalExtMask(CAN_Type *base, uint32_t extMask)
Sets the FlexCAN RX Message Buffer global extended mask.
Definition: flexcan_hal.c:1607
void FLEXCAN_HAL_SetTimeSegmentsCbt(CAN_Type *base, const flexcan_time_segment_t *timeSeg)
Sets the FlexCAN time segments for setting up bit rate for FD BRS.
Definition: flexcan_hal.c:547
void FLEXCAN_HAL_ClearErrIntStatusFlag(CAN_Type *base)
Clears all other interrupts in ERRSTAT register (Error, Busoff, Wakeup).
Definition: flexcan_hal.c:1337
status_t FLEXCAN_DRV_Receive(uint8_t instance, uint8_t mb_idx, flexcan_msgbuff_t *data)
Receives a CAN frame using the specified message buffer.
status_t FLEXCAN_DRV_Deinit(uint8_t instance)
Shuts down a FlexCAN instance.
Internal driver state information.
void FLEXCAN_HAL_ConfigPN(CAN_Type *base, const flexcan_pn_config_t *pnConfig)
Configures the Pretended Networking mode.
void FLEXCAN_HAL_SetTimeSegments(CAN_Type *base, const flexcan_time_segment_t *timeSeg)
Sets the FlexCAN time segments for setting up bit rate.
Definition: flexcan_hal.c:493
void FLEXCAN_HAL_GetTimeSegments(const CAN_Type *base, flexcan_time_segment_t *timeSeg)
Gets the FlexCAN time segments to calculate the bit rate.
Definition: flexcan_hal.c:578
void FLEXCAN_HAL_ExitFreezeMode(CAN_Type *base)
Un freezes the FlexCAN module.
Definition: flexcan_hal.c:1272
flexcan_operation_modes_t flexcanMode
void FLEXCAN_HAL_Enable(CAN_Type *base)
Enables FlexCAN controller.
Definition: flexcan_hal.c:386
flexcan_fd_payload_size_t payload
status_t FLEXCAN_DRV_ConfigTxMb(uint8_t instance, uint8_t mb_idx, const flexcan_data_info_t *tx_info, uint32_t msg_id)
FlexCAN transmit message buffer field configuration.
status_t OSIF_SemaDestroy(const semaphore_t *const pSem)
Destroys a previously created semaphore.
flexcan_time_segment_t bitrate
void * callbackParam
status_t FLEXCAN_HAL_EnableRxFifo(CAN_Type *base, uint32_t numOfFilters)
Enables the Rx FIFO.
Definition: flexcan_hal.c:947
__IO uint32_t WU_MTC
Definition: S32K144.h:964
__IO uint32_t RAMn[CAN_RAMn_COUNT]
Definition: S32K144.h:958
bool FLEXCAN_HAL_IsFDEnabled(const CAN_Type *base)
Checks if the Flexible Data rate feature is enabled.
Definition: flexcan_hal.c:1790
flexcan_rx_fifo_id_filter_num_t num_id_filters
static uint32_t FLEXCAN_HAL_GetAllMsgBuffIntStatusFlag(const CAN_Type *base)
Gets all FlexCAN Message Buffer interrupt flags.
Definition: flexcan_hal.h:672
status_t FLEXCAN_DRV_RxFifo(uint8_t instance, flexcan_msgbuff_t *data)
Receives a CAN frame using the message FIFO.
status_t FLEXCAN_HAL_GetMsgBuff(CAN_Type *base, uint32_t msgBuffIdx, flexcan_msgbuff_t *msgBuff)
Gets the FlexCAN message buffer fields.
Definition: flexcan_hal.c:838
status_t FLEXCAN_HAL_SetMsgBuffIntCmd(CAN_Type *base, uint32_t msgBuffIdx, bool enable)
Enables/Disables the FlexCAN Message Buffer interrupt.
Definition: flexcan_hal.c:1210
static status_t FLEXCAN_DRV_StartRxMessageFifoData(uint8_t instance, flexcan_msgbuff_t *data, bool isBlocking)
void FLEXCAN_HAL_Disable(CAN_Type *base)
Disables FlexCAN controller.
Definition: flexcan_hal.c:408
status_t EDMA_DRV_StopChannel(uint8_t channel)
Stops the eDMA channel.
Definition: edma_driver.c:790
#define FEATURE_CAN_MAX_MB_NUM
status_t FLEXCAN_HAL_LockRxMsgBuff(CAN_Type *base, uint32_t msgBuffIdx)
Locks the FlexCAN Rx message buffer.
Definition: flexcan_hal.c:918
#define CAN_CS_IDE_MASK
Definition: flexcan_hal.h:283
uint8_t data[64]
Definition: flexcan_hal.h:191
void FLEXCAN_HAL_SetRxFifoGlobalStdMask(CAN_Type *base, uint32_t stdMask)
Sets the FlexCAN RX FIFO global standard mask.
Definition: flexcan_hal.c:1434
void FLEXCAN_DRV_ConfigRxFifo(uint8_t instance, flexcan_rx_fifo_id_element_format_t id_format, const flexcan_id_table_t *id_filter_table)
FlexCAN RX FIFO field configuration.
void FLEXCAN_HAL_EnterFreezeMode(CAN_Type *base)
Freezes the FlexCAN module.
Definition: flexcan_hal.c:1288
status_t OSIF_SemaCreate(semaphore_t *const pSem, const uint8_t initValue)
Creates a semaphore with a given value.
flexcan_msgbuff_id_type_t msg_id_type
void FLEXCAN_HAL_SetSelfReception(CAN_Type *base, bool enable)
Enables/Disables the Self Reception feature.
Definition: flexcan_hal.c:1882
void FLEXCAN_DRV_InstallEventCallback(uint8_t instance, flexcan_callback_t callback, void *callbackParam)
Installs a callback function for the IRQ handler.
#define CAN_WU_MTC_WTOF_MASK
Definition: S32K144.h:1513
static flexcan_state_t * g_flexcanStatePtr[CAN_INSTANCE_COUNT]
#define REV_BYTES_32(a, b)
Reverse byte order in a word.
Definition: s32_core_cm4.h:112
void INT_SYS_DisableIRQ(IRQn_Type irqNumber)
Disables an interrupt for a given IRQ number.
#define FLEXCAN_MB_HANDLE_RXFIFO
#define CAN_ID_STD_SHIFT
Definition: flexcan_hal.h:264
void FLEXCAN_HAL_SetErrIntCmd(CAN_Type *base, flexcan_int_type_t errType, bool enable)
Enables error interrupt of the FlexCAN module.
Definition: flexcan_hal.c:1247
#define CAN_INSTANCE_COUNT
Definition: S32K144.h:986
#define DEV_ASSERT(x)
Definition: devassert.h:78
static void FLEXCAN_DRV_CompleteRxMessageFifoData(uint32_t instance)
edma_chn_status_t
Channel status for eDMA channel.
Definition: edma_driver.h:125
flexcan_rxfifo_transfer_type_t transferType
const IRQn_Type g_flexcanWakeUpIrqId[CAN_INSTANCE_COUNT]
Table to save wakeup IRQ numbers for FlexCAN instances.
#define CAN_WU_MTC_WUMF_MASK
Definition: S32K144.h:1509
void FLEXCAN_DRV_SetRxMaskType(uint8_t instance, flexcan_rx_mask_type_t type)
Sets the RX masking type.
#define CAN_CS_DLC_SHIFT
Definition: flexcan_hal.h:276
void FLEXCAN_HAL_SetOperationMode(CAN_Type *base, flexcan_operation_modes_t mode)
Set operation mode.
Definition: flexcan_hal.c:1671
void FLEXCAN_HAL_SetRxMsgBuffGlobalStdMask(CAN_Type *base, uint32_t stdMask)
Sets the FlexCAN Rx Message Buffer global standard mask.
Definition: flexcan_hal.c:1543
FlexCAN timing related structures Implements : flexcan_time_segment_t_Class.
Definition: flexcan_hal.h:198
status_t FLEXCAN_DRV_ConfigRxMb(uint8_t instance, uint8_t mb_idx, const flexcan_data_info_t *rx_info, uint32_t msg_id)
FlexCAN receive message buffer field configuration.
void FLEXCAN_HAL_SetRxMaskType(CAN_Type *base, flexcan_rx_mask_type_t type)
Sets the Rx masking type.
Definition: flexcan_hal.c:1404
#define CAN_CS_DLC_MASK
Definition: flexcan_hal.h:275
status_t FLEXCAN_DRV_GetTransferStatus(uint32_t instance, uint8_t mb_idx)
Returns whether the previous FLEXCAN transfer has finished.
#define FEATURE_CAN_MB_IRQS_MAX_COUNT
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:31
#define FEATURE_CAN_RXFIFO_WARNING
status_t FLEXCAN_DRV_Init(uint32_t instance, flexcan_state_t *state, const flexcan_user_config_t *data)
Initializes the FlexCAN peripheral.
static void FLEXCAN_HAL_UnlockRxMsgBuff(const CAN_Type *base)
Unlocks the FlexCAN Rx message buffer.
Definition: flexcan_hal.h:525
static void FLEXCAN_DRV_CompleteTransfer(uint32_t instance, uint8_t mb_idx)
void FLEXCAN_HAL_SetRxFifoFilter(CAN_Type *base, flexcan_rx_fifo_id_element_format_t idFormat, const flexcan_id_table_t *idFilterTable)
Sets the FlexCAN Rx FIFO fields.
Definition: flexcan_hal.c:1090
void(* flexcan_callback_t)(uint8_t instance, flexcan_event_type_t eventType, flexcan_state_t *flexcanState)
FlexCAN Driver callback function type Implements : flexcan_callback_t_Class.
static bool FLEXCAN_HAL_IsRxFifoEnabled(const CAN_Type *base)
Checks if Rx FIFO is enabled.
Definition: flexcan_hal.h:557
status_t FLEXCAN_DRV_AbortTransfer(uint32_t instance, uint8_t mb_idx)
Ends a non-blocking FlexCAN transfer early.
flexcan_rx_fifo_id_element_format_t
ID formats for RxFIFO Implements : flexcan_rx_fifo_id_element_format_t_Class.
Definition: flexcan_hal.h:109
void FLEXCAN_HAL_ReadRxFifo(const CAN_Type *base, flexcan_msgbuff_t *rxFifo)
Gets the FlexCAN Rx FIFO data.
Definition: flexcan_hal.c:1358
status_t FLEXCAN_HAL_SetRxMsgBuff(CAN_Type *base, uint32_t msgBuffIdx, const flexcan_msgbuff_code_status_t *cs, uint32_t msgId)
Sets the FlexCAN message buffer fields for receiving.
Definition: flexcan_hal.c:752
FlexCAN message buffer structure Implements : flexcan_msgbuff_t_Class.
Definition: flexcan_hal.h:188
flexcan_msgbuff_id_type_t msgIdType
Definition: flexcan_hal.h:178
status_t FLEXCAN_DRV_SendBlocking(uint8_t instance, uint8_t mb_idx, const flexcan_data_info_t *tx_info, uint32_t msg_id, const uint8_t *mb_data, uint32_t timeout_ms)
Sends a CAN frame using the specified message buffer, in a blocking manner.
static status_t FLEXCAN_DRV_StartRxMessageBufferData(uint8_t instance, uint8_t mb_idx, flexcan_msgbuff_t *data, bool isBlocking)
FlexCAN RX FIFO ID filter table structure Implements : flexcan_id_table_t_Class.
Definition: flexcan_hal.h:122
CAN_Type *const g_flexcanBase[CAN_INSTANCE_COUNT]
Table of base addresses for FlexCAN instances.
status_t FLEXCAN_DRV_RxFifoBlocking(uint8_t instance, flexcan_msgbuff_t *data, uint32_t timeout_ms)
Receives a CAN frame using the message FIFO, in a blocking manner.
static void FLEXCAN_HAL_SetPN(CAN_Type *base, bool enable)
Enables/Disables the Pretended Networking mode.
Definition: flexcan_hal.h:973
void(* callback)(uint8_t instance, flexcan_event_type_t eventType, struct FlexCANState *state)
flexcan_time_segment_t bitrate_cbt
flexcan_rxfifo_transfer_type_t transfer_type
flexcan_mb_state_t state
status_t FLEXCAN_HAL_SetRxIndividualStdMask(CAN_Type *base, uint32_t msgBuffIdx, uint32_t stdMask)
Sets the FlexCAN Rx individual standard mask for ID filtering in the Rx MBs and the Rx FIFO...
Definition: flexcan_hal.c:1476
Pretended Networking configuration structure Implements : flexcan_pn_config_t_Class.
Definition: flexcan_hal.h:244
status_t OSIF_SemaWait(semaphore_t *const pSem, const uint32_t timeout)
Decrement a semaphore with timeout.
status_t EDMA_DRV_StartChannel(uint8_t channel)
Starts an eDMA channel.
Definition: edma_driver.c:765
const IRQn_Type g_flexcanErrorIrqId[CAN_INSTANCE_COUNT]
Table to save error IRQ numbers for FlexCAN instances.
void FLEXCAN_HAL_Init(CAN_Type *base)
Initializes the FlexCAN controller.
Definition: flexcan_hal.c:450
status_t FLEXCAN_HAL_SetTxMsgBuff(CAN_Type *base, uint32_t msgBuffIdx, const flexcan_msgbuff_code_status_t *cs, uint32_t msgId, const uint8_t *msgData)
Sets the FlexCAN message buffer fields for transmitting.
Definition: flexcan_hal.c:603
void FLEXCAN_DRV_SetRxFifoGlobalMask(uint8_t instance, flexcan_msgbuff_id_type_t id_type, uint32_t mask)
Sets the FlexCAN RX FIFO global standard or extended mask.
status_t FLEXCAN_HAL_SetMaxMsgBuffNum(CAN_Type *base, uint32_t maxMsgBuffNum)
Sets the maximum number of Message Buffers.
Definition: flexcan_hal.c:1033
status_t OSIF_SemaPost(semaphore_t *const pSem)
Increment a semaphore.
status_t FLEXCAN_DRV_ReceiveBlocking(uint8_t instance, uint8_t mb_idx, flexcan_msgbuff_t *data, uint32_t timeout_ms)
Receives a CAN frame using the specified message buffer, in a blocking manner.
void FLEXCAN_DRV_SetBitrateCbt(uint8_t instance, const flexcan_time_segment_t *bitrate)
Sets the FlexCAN bit rate for FD BRS.
void FLEXCAN_HAL_SelectClock(CAN_Type *base, flexcan_clk_source_t clk)
Selects the clock source for FlexCAN.
flexcan_msgbuff_id_type_t
FlexCAN Message Buffer ID type Implements : flexcan_msgbuff_id_type_t_Class.
Definition: flexcan_hal.h:139
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
static status_t FLEXCAN_DRV_StartSendData(uint8_t instance, uint8_t mb_idx, const flexcan_data_info_t *tx_info, uint32_t msg_id, const uint8_t *mb_data, bool isBlocking)
#define CAN_CS_CODE_SHIFT
Definition: flexcan_hal.h:292
flexcan_msgbuff_t * mb_message
void FLEXCAN_HAL_SetPayloadSize(CAN_Type *base, flexcan_fd_payload_size_t payloadSize)
Sets the payload size of the MBs.
Definition: flexcan_hal.c:1802
static void FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(CAN_Type *base, uint32_t flag)
Clears the interrupt flag of the message buffers.
Definition: flexcan_hal.h:686
void FLEXCAN_HAL_SetStuffBitCount(CAN_Type *base, bool enable)
Enables/Disables the Stuff Bit Count for CAN FD frames.
Definition: flexcan_hal.c:1861
void FLEXCAN_DRV_SetRxMbGlobalMask(uint8_t instance, flexcan_msgbuff_id_type_t id_type, uint32_t mask)
Sets the FlexCAN RX MB global standard or extended mask.
void FLEXCAN_DRV_IRQHandler(uint8_t instance)
Interrupt handler for a FlexCAN instance.
FlexCAN data info from user Implements : flexcan_data_info_t_Class.
flexcan_rx_mask_type_t
FlexCAN RX mask type. Implements : flexcan_rx_mask_type_t_Class.
Definition: flexcan_hal.h:131
status_t EDMA_DRV_ConfigSingleBlockTransfer(uint8_t channel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t dataBufferSize)
Configures a simple single block data transfer with DMA.
Definition: edma_driver.c:487
#define CAN_CS_CODE_MASK
Definition: flexcan_hal.h:291
void FLEXCAN_HAL_SetRxFifoGlobalExtMask(CAN_Type *base, uint32_t extMask)
Sets the FlexCAN Rx FIFO global extended mask.
Definition: flexcan_hal.c:1455
status_t FLEXCAN_DRV_Send(uint8_t instance, uint8_t mb_idx, const flexcan_data_info_t *tx_info, uint32_t msg_id, const uint8_t *mb_data)
Sends a CAN frame using the specified message buffer.
status_t FLEXCAN_DRV_SetRxIndividualMask(uint8_t instance, flexcan_msgbuff_id_type_t id_type, uint8_t mb_idx, uint32_t mask)
Sets the FlexCAN RX individual standard or extended mask.
volatile flexcan_mb_handle_t mbs[FEATURE_CAN_MAX_MB_NUM]
FlexCAN Message Buffer code and status for transmit and receive Implements : flexcan_msgbuff_code_sta...
Definition: flexcan_hal.h:175
status_t EDMA_DRV_InstallCallback(uint8_t channel, edma_callback_t callback, void *parameter)
Registers the callback function and the parameter for eDMA channel.
Definition: edma_driver.c:285
void FLEXCAN_DRV_SetBitrate(uint8_t instance, const flexcan_time_segment_t *bitrate)
Sets the FlexCAN bit rate.
#define FEATURE_CAN_RXFIFO_OVERFLOW
FlexCAN configuration.
status_t FLEXCAN_HAL_SetRxIndividualExtMask(CAN_Type *base, uint32_t msgBuffIdx, uint32_t extMask)
Sets the FlexCAN Rx individual extended mask for ID filtering in the Rx Message Buffers and the Rx FI...
Definition: flexcan_hal.c:1510
void FLEXCAN_DRV_GetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate)
Gets the FlexCAN bit rate.
void FLEXCAN_HAL_SetFDEnabled(CAN_Type *base, bool enable)
Enables/Disables Flexible Data rate (if supported).
Definition: flexcan_hal.c:1771