can_pal.c
Go to the documentation of this file.
1 /*
2  * Copyright 2017 NXP
3  * All rights reserved.
4  *
5  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
6  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
8  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
9  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
11  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
12  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
13  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
14  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
15  * THE POSSIBILITY OF SUCH DAMAGE.
16  */
17 
67 #include "can_pal.h"
68 #include "device_registers.h"
69 
70 /*******************************************************************************
71  * Definitions
72  ******************************************************************************/
73 #if (defined(CAN_OVER_FLEXCAN))
74 
75 /* Internal FlexCAN Rx FIFO state information */
76 typedef struct
77 {
78  bool rxFifoEn;
80 } flexcan_rx_fifo_state_t;
81 
82 #endif
83 
84 /*******************************************************************************
85  * Variables
86  ******************************************************************************/
87 #if (defined(CAN_OVER_FLEXCAN))
88 
90 static flexcan_state_t s_flexcanState[NO_OF_FLEXCAN_INSTS_FOR_CAN];
92 static uint32_t s_flexcanStateInstanceMapping[NO_OF_FLEXCAN_INSTS_FOR_CAN];
94 static bool s_flexcanStateIsAllocated[NO_OF_FLEXCAN_INSTS_FOR_CAN];
96 static const can_buff_config_t *s_hwObjConfigs[NO_OF_FLEXCAN_INSTS_FOR_CAN][FEATURE_CAN_MAX_MB_NUM];
98 static flexcan_rx_fifo_state_t s_flexcanRxFifoState[NO_OF_FLEXCAN_INSTS_FOR_CAN];
100 static can_callback_t userCallbacks[NO_OF_FLEXCAN_INSTS_FOR_CAN];
101 
102 #endif
103 
104 /*******************************************************************************
105  * Private Functions
106  ******************************************************************************/
107 
108 /*FUNCTION**********************************************************************
109  *
110  * Function Name : CAN_AllocateState
111  * Description : Allocates one of the available state structures.
112  *
113  *END**************************************************************************/
114 static uint8_t CAN_AllocateState(bool *isAllocated,
115  uint32_t *instanceMapping,
116  uint32_t instance,
117  uint8_t numberOfinstances)
118 {
119  uint8_t i;
120  /* Allocate one of the CAN state structures for this instance */
121  for (i = 0; i < numberOfinstances; i++)
122  {
123  if (isAllocated[i] == false)
124  {
125  instanceMapping[i] = instance;
126  isAllocated[i] = true;
127  break;
128  }
129  }
130  return i;
131 }
132 
133 /*FUNCTION**********************************************************************
134  *
135  * Function Name : CAN_FreeState
136  * Description : Deallocates one of the available state structures.
137  *
138  *END**************************************************************************/
139 static void CAN_FreeState(bool *isAllocated,
140  const uint32_t *instanceMapping,
141  uint32_t instance,
142  uint8_t numberOfinstances)
143 {
144  uint8_t i;
145  /* Free one of the CAN state structures for this instance */
146  for (i = 0; i < numberOfinstances; i++)
147  {
148  if (instanceMapping[i] == instance)
149  {
150  isAllocated[i] = false;
151  break;
152  }
153  }
154 }
155 
156 #if (defined(CAN_OVER_FLEXCAN))
157 
158 /*FUNCTION**********************************************************************
159  *
160  * Function Name : CAN_FindFlexCANState
161  * Description : Search the state structure of the FlexCAN instance
162  *
163  *END**************************************************************************/
164 static uint8_t CAN_FindFlexCANState(uint32_t instance)
165 {
166  uint8_t i;
167 
168  for (i = 0; i < NO_OF_FLEXCAN_INSTS_FOR_CAN; i++)
169  {
170  if (s_flexcanStateInstanceMapping[i] == instance)
171  {
172  break;
173  }
174  }
175  return i;
176 }
177 
178 /*FUNCTION**********************************************************************
179  *
180  * Function Name : CAN_GetVirtualBuffIdx
181  * Description : Determines the index of the last buffer occupied by Rx
182  * FIFO filters
183  *
184  *END**************************************************************************/
185 static inline uint32_t CAN_GetVirtualBuffIdx(uint32_t x)
186 {
187  return (5U + ((((x) + 1U) * 8U) / 4U));
188 }
189 
190 /*FUNCTION**********************************************************************
191  *
192  * Function Name : CAN_InternalCallback
193  * Description : Internal callback used to translate buffer indices
194  * and event types
195  *
196  *END**************************************************************************/
197 static void CAN_InternalCallback(uint8_t instance,
198  flexcan_event_type_t eventType,
199  uint32_t buffIdx,
200  flexcan_state_t *state)
201 {
202  uint8_t index = CAN_FindFlexCANState(instance);
203  can_callback_t callback = userCallbacks[index];
204 
205  /* If FlexCAN Rx FIFO is enabled, translate real buffer index to virtual index */
206  if ((s_flexcanRxFifoState[index].rxFifoEn == true) && (buffIdx != 0U))
207  {
208  buffIdx -= CAN_GetVirtualBuffIdx((uint32_t) s_flexcanRxFifoState[index].numIdFilters);
209  }
210 
211  /* Translate FlexCAN events to CAN PAL events and invoke the callback provided by user */
212  switch (eventType)
213  {
215  callback(instance,
217  (uint8_t) buffIdx,
218  (flexcan_state_t *) state);
219  break;
221  callback(instance,
223  (uint8_t) buffIdx,
224  (flexcan_state_t *) state);
225  break;
227  callback(instance,
229  (uint8_t) buffIdx,
230  (flexcan_state_t *) state);
231  break;
232  default:
233  /* Event types not implemented in PAL */
234  break;
235  }
236 }
237 
238 #endif
239 
240 /*******************************************************************************
241  * Public Functions
242  ******************************************************************************/
243 
244 /*FUNCTION**********************************************************************
245  *
246  * Function Name : CAN_Init
247  * Description : Configures the CAN module
248  *
249  * Implements : CAN_Init_Activity
250  *END**************************************************************************/
251 status_t CAN_Init(const can_instance_t * const instance,
252  const can_user_config_t *config)
253 {
254  DEV_ASSERT(instance != NULL);
255  DEV_ASSERT(config != NULL);
256 
257  status_t status = STATUS_ERROR;
258  uint8_t index = 0U;
259 
260  /* Define CAN PAL over FLEXCAN */
261  #if (defined (CAN_OVER_FLEXCAN))
262  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
263  {
265 
266  flexcan_user_config_t flexcanConfig;
267 
268  /* Allocate one of the FLEXCAN state structure for this instance */
269  index = CAN_AllocateState(s_flexcanStateIsAllocated,
270  s_flexcanStateInstanceMapping,
271  instance->instIdx,
272  NO_OF_FLEXCAN_INSTS_FOR_CAN);
273 
274  /* Clear Rx FIFO state */
275  s_flexcanRxFifoState[index].rxFifoEn = false;
276 
277  /* Configure features implemented by PAL */
278  flexcanConfig.max_num_mb = config->maxBuffNum;
279  flexcanConfig.flexcanMode = (flexcan_operation_modes_t) config->mode;
281  flexcanConfig.fd_enable = config->enableFD;
282  flexcanConfig.payload = (flexcan_fd_payload_size_t) config->payloadSize;
283 #endif
284 
285  flexcanConfig.bitrate.phaseSeg1 = config->nominalBitrate.phaseSeg1;
286  flexcanConfig.bitrate.phaseSeg2 = config->nominalBitrate.phaseSeg2;
287  flexcanConfig.bitrate.preDivider = config->nominalBitrate.preDivider;
288  flexcanConfig.bitrate.propSeg = config->nominalBitrate.propSeg;
289  flexcanConfig.bitrate.rJumpwidth = config->nominalBitrate.rJumpwidth;
290 
291 #if FEATURE_CAN_HAS_FD
292  flexcanConfig.bitrate_cbt.phaseSeg1 = config->dataBitrate.phaseSeg1;
293  flexcanConfig.bitrate_cbt.phaseSeg2 = config->dataBitrate.phaseSeg2;
294  flexcanConfig.bitrate_cbt.preDivider = config->dataBitrate.preDivider;
295  flexcanConfig.bitrate_cbt.propSeg = config->dataBitrate.propSeg;
296  flexcanConfig.bitrate_cbt.rJumpwidth = config->dataBitrate.rJumpwidth;
297 #endif
298 
299 #if FEATURE_CAN_HAS_PE_CLKSRC_SELECT
300  flexcanConfig.pe_clock = (flexcan_clk_source_t) config->peClkSrc;
301 #endif
302 
303  /* If extension is used, configure Rx FIFO */
304  if (config->extension != NULL)
305  {
306  flexcanConfig.is_rx_fifo_needed = true;
307  flexcanConfig.num_id_filters = ((extension_flexcan_rx_fifo_t *)
308  (config->extension))->numIdFilters;
309 #if FEATURE_CAN_HAS_DMA_ENABLE
310  flexcanConfig.rxFifoDMAChannel = 0U;
311 #endif
313 
314  /* Compute maximum number of virtual buffers */
315  flexcanConfig.max_num_mb += CAN_GetVirtualBuffIdx(flexcanConfig.num_id_filters);
316 
317  /* Update Rx FIFO state */
318  s_flexcanRxFifoState[index].rxFifoEn = true;
319  s_flexcanRxFifoState[index].numIdFilters = flexcanConfig.num_id_filters;
320  }
321  else
322  {
323  flexcanConfig.is_rx_fifo_needed = false;
325 #if FEATURE_CAN_HAS_DMA_ENABLE
326  flexcanConfig.rxFifoDMAChannel = 0U;
327 #endif
329  }
330 
331  /* Initialize FLEXCAN instance */
332  status = FLEXCAN_DRV_Init((uint8_t) instance->instIdx,
333  &s_flexcanState[index],
334  &flexcanConfig);
335 
336  /* Configure Rx FIFO if needed */
337  if ((status == STATUS_SUCCESS) &&
338  (s_flexcanRxFifoState[index].rxFifoEn == true))
339  {
341  (uint8_t) instance->instIdx,
342  ((extension_flexcan_rx_fifo_t *) (config->extension))->idFormat,
343  ((extension_flexcan_rx_fifo_t *) (config->extension))->idFilterTable);
344  }
345  }
346  #endif
347 
348  return status;
349 }
350 
351 /*FUNCTION**********************************************************************
352  *
353  * Function Name : CAN_Deinit
354  * Description : De-initializes the CAN module
355  *
356  * Implements : CAN_Deinit_Activity
357  *END**************************************************************************/
358 status_t CAN_Deinit(const can_instance_t * const instance)
359 {
360  DEV_ASSERT(instance != NULL);
361 
362  status_t status = STATUS_ERROR;
363 
364  /* Define CAN PAL over FLEXCAN */
365  #if defined(CAN_OVER_FLEXCAN)
366  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
367  {
368  /* De-initialize the FlexCAN module */
369  status = FLEXCAN_DRV_Deinit((uint8_t) instance->instIdx);
370 
371  if (status == STATUS_SUCCESS)
372  {
373  /* Clear FlexCAN instance mapping */
374  CAN_FreeState(s_flexcanStateIsAllocated,
375  s_flexcanStateInstanceMapping,
376  instance->instIdx,
377  NO_OF_FLEXCAN_INSTS_FOR_CAN);
378  }
379  }
380  #endif
381 
382  return status;
383 }
384 
385 /*FUNCTION**********************************************************************
386  *
387  * Function Name : CAN_SetBitrate
388  * Description : Configures the CAN bit timing variables.
389  *
390  * Implements : CAN_SetBitrate_Activity
391  *END**************************************************************************/
392 status_t CAN_SetBitrate(const can_instance_t * const instance,
393  can_bitrate_phase_t phase,
394  const can_time_segment_t *bitTiming)
395 {
396  DEV_ASSERT(instance != NULL);
397  DEV_ASSERT(bitTiming != NULL);
398 
399  status_t status = STATUS_ERROR;
400 
401  /* Define CAN PAL over FLEXCAN */
402  #if defined(CAN_OVER_FLEXCAN)
403  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
404  {
405  status = STATUS_SUCCESS;
406 
407  if (phase == CAN_NOMINAL_BITRATE)
408  {
409  FLEXCAN_DRV_SetBitrate((uint8_t) instance->instIdx,
410  (flexcan_time_segment_t *) bitTiming);
411  }
412 #if FEATURE_CAN_HAS_FD
413  else
414  {
415  FLEXCAN_DRV_SetBitrateCbt((uint8_t) instance->instIdx,
416  (flexcan_time_segment_t *) bitTiming);
417  }
418 #endif
419  }
420  #endif
421 
422  return status;
423 }
424 
425 /*FUNCTION**********************************************************************
426  *
427  * Function Name : CAN_GetBitrate
428  * Description : Returns the CAN configured bit timing variables.
429  *
430  * Implements : CAN_GetBitrate_Activity
431  *END**************************************************************************/
432 status_t CAN_GetBitrate(const can_instance_t * const instance,
433  can_bitrate_phase_t phase,
434  can_time_segment_t *bitTiming)
435 {
436  DEV_ASSERT(instance != NULL);
437  DEV_ASSERT(bitTiming != NULL);
438 
439  status_t status = STATUS_ERROR;
440 
441  /* Define CAN PAL over FLEXCAN */
442  #if defined(CAN_OVER_FLEXCAN)
443  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
444  {
445  status = STATUS_SUCCESS;
446 
447  if (phase == CAN_NOMINAL_BITRATE)
448  {
449  FLEXCAN_DRV_GetBitrate((uint8_t) instance->instIdx,
450  (flexcan_time_segment_t *) bitTiming);
451  }
452 #if FEATURE_CAN_HAS_FD
453  else
454  {
455  FLEXCAN_DRV_GetBitrateFD((uint8_t) instance->instIdx,
456  (flexcan_time_segment_t *) bitTiming);
457  }
458 #endif
459  }
460  #endif
461 
462  return status;
463 }
464 
465 /*FUNCTION**********************************************************************
466  *
467  * Function Name : CAN_ConfigTxBuff
468  * Description : Configures a buffer for transmission.
469  *
470  * Implements : CAN_ConfigTxBuff_Activity
471  *END**************************************************************************/
472 status_t CAN_ConfigTxBuff(const can_instance_t * const instance,
473  uint32_t buffIdx,
474  const can_buff_config_t *config)
475 {
476  DEV_ASSERT(instance != NULL);
477  DEV_ASSERT(config != NULL);
478 
479  status_t status = STATUS_ERROR;
480  uint8_t index;
481 
482  /* Define CAN PAL over FLEXCAN */
483  #if defined(CAN_OVER_FLEXCAN)
484  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
485  {
487 
488  index = CAN_FindFlexCANState(instance->instIdx);
489 
490  /* If Rx FIFO is enabled, buffer 0 (zero) can only be used for reception */
491  DEV_ASSERT((s_flexcanRxFifoState[index].rxFifoEn == false) || (buffIdx != 0U));
492  /* Check buffer index to avoid overflow */
494 
495  flexcan_data_info_t dataInfo = {
497  .data_length = (config->enableFD ? (uint32_t) 64U : (uint32_t) 8U),
499  .fd_enable = config->enableFD,
500  .fd_padding = config->fdPadding,
501  .enable_brs = config->enableBRS,
502 #endif
503  .is_remote = false
504  };
505 
506  /* Save buffer config for later use */
507  s_hwObjConfigs[index][buffIdx] = config;
508 
509  /* Compute virtual buffer index */
510  if (s_flexcanRxFifoState[index].rxFifoEn)
511  {
512  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
513  }
514 
515  /* Configure FlexCAN MB for transmission */
516  status = FLEXCAN_DRV_ConfigTxMb((uint8_t) instance->instIdx,
517  (uint8_t) buffIdx,
518  &dataInfo,
519  0U);
520  }
521  #endif
522 
523  return status;
524 }
525 
526 /*FUNCTION**********************************************************************
527  *
528  * Function Name : CAN_ConfigRemoteResponseBuff
529  * Description : Configures a transmit buffer for remote frame response. This
530  * function will set up the buffer fields, configure the buffer code for Tx
531  * buffer as RX_RANSWER, and enable the buffer interrupt.
532  *
533  * Implements : CAN_ConfigRemoteResponseBuff_Activity
534  *END**************************************************************************/
536  uint32_t buffIdx,
537  const can_buff_config_t *config,
538  const can_message_t *message)
539 {
540  DEV_ASSERT(instance != NULL);
541  DEV_ASSERT(config != NULL);
542 
543  status_t status = STATUS_ERROR;
544  uint8_t index;
545 
546  /* Define CAN PAL over FLEXCAN */
547  #if defined(CAN_OVER_FLEXCAN)
548  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
549  {
551 
552  index = CAN_FindFlexCANState(instance->instIdx);
553 
554  /* If Rx FIFO is enabled, buffer 0 (zero) can only be used for reception */
555  DEV_ASSERT((s_flexcanRxFifoState[index].rxFifoEn == false) || (buffIdx != 0U));
556  /* Check buffer index to avoid overflow */
558 
559  flexcan_data_info_t dataInfo = {
561  .data_length = message->length,
562 #if FEATURE_CAN_HAS_FD
563  .fd_enable = config->enableFD,
564  .fd_padding = config->fdPadding,
565  .enable_brs = config->enableBRS,
566 #endif
567  .is_remote = config->isRemote
568  };
569 
570  /* Save buffer config for later use */
571  s_hwObjConfigs[index][buffIdx] = config;
572 
573  /* Compute virtual buffer index */
574  if (s_flexcanRxFifoState[index].rxFifoEn)
575  {
576  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
577  }
578 
579  /* Configure FlexCAN MB for transmission */
580  status = FLEXCAN_DRV_ConfigRemoteResponseMb((uint8_t) instance->instIdx,
581  (uint8_t) buffIdx,
582  &dataInfo,
583  message->id,
584  message->data);
585  }
586  #endif
587 
588  return status;
589 }
590 
591 /*FUNCTION**********************************************************************
592  *
593  * Function Name : CAN_ConfigRxBuff
594  * Description : Configures a buffer for reception.
595  *
596  * Implements : CAN_ConfigRxBuff_Activity
597  *END**************************************************************************/
598 status_t CAN_ConfigRxBuff(const can_instance_t * const instance,
599  uint32_t buffIdx,
600  const can_buff_config_t *config,
601  uint32_t acceptedId)
602 {
603  DEV_ASSERT(instance != NULL);
604  DEV_ASSERT(config != NULL);
605 
606  status_t status = STATUS_ERROR;
607  uint8_t index;
608 
609  /* Define CAN PAL over FLEXCAN */
610  #if defined(CAN_OVER_FLEXCAN)
611  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
612  {
614 
615  index = CAN_FindFlexCANState(instance->instIdx);
616 
617  /* If Rx FIFO is enabled, buffer 0 (zero) is configured at init time */
618  DEV_ASSERT((s_flexcanRxFifoState[index].rxFifoEn == false) || (buffIdx != 0U));
619  /* Check buffer index to avoid overflow */
621 
622  flexcan_data_info_t dataInfo = {
624  .data_length = (config->enableFD ? (uint32_t) 64U : (uint32_t) 8U),
626  .fd_enable = config->enableFD,
627  .fd_padding = config->fdPadding,
628  .enable_brs = config->enableBRS,
629 #endif
630  .is_remote = config->isRemote
631  };
632 
633  /* Save buffer config for later use */
634  s_hwObjConfigs[index][buffIdx] = config;
635 
636  /* Compute virtual buffer index */
637  if (s_flexcanRxFifoState[index].rxFifoEn)
638  {
639  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
640  }
641 
642  /* Configure FlexCAN MB for reception */
643  status = FLEXCAN_DRV_ConfigRxMb((uint8_t) instance->instIdx,
644  (uint8_t) buffIdx,
645  &dataInfo,
646  acceptedId);
647  }
648  #endif
649 
650  return status;
651 }
652 
653 /*FUNCTION**********************************************************************
654  *
655  * Function Name : CAN_Send
656  * Description : Sends a CAN frame using the specified buffer.
657  *
658  * Implements : CAN_Send_Activity
659  *END**************************************************************************/
660 status_t CAN_Send(const can_instance_t * const instance,
661  uint32_t buffIdx,
662  const can_message_t *message)
663 {
664  DEV_ASSERT(instance != NULL);
665  DEV_ASSERT(message != NULL);
666 
667  status_t status = STATUS_ERROR;
668  uint8_t index;
669 
670  /* Define CAN PAL over FLEXCAN */
671  #if defined(CAN_OVER_FLEXCAN)
672  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
673  {
675 
676  index = CAN_FindFlexCANState(instance->instIdx);
677 
678  /* If Rx FIFO is enabled, buffer 0 (zero) can only be used for reception */
679  DEV_ASSERT((s_flexcanRxFifoState[index].rxFifoEn == false) || (buffIdx != 0U));
680  /* Check buffer index to avoid overflow */
682 
683  flexcan_data_info_t dataInfo = {
684  .msg_id_type = (flexcan_msgbuff_id_type_t) s_hwObjConfigs[index][buffIdx]->idType,
685  .data_length = message->length,
687  .fd_enable = s_hwObjConfigs[index][buffIdx]->enableFD,
688  .fd_padding = s_hwObjConfigs[index][buffIdx]->fdPadding,
689  .enable_brs = s_hwObjConfigs[index][buffIdx]->enableBRS,
690 #endif
691  .is_remote = s_hwObjConfigs[index][buffIdx]->isRemote
692  };
693 
694  /* Compute virtual buffer index */
695  if (s_flexcanRxFifoState[index].rxFifoEn)
696  {
697  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
698  }
699 
700  status = FLEXCAN_DRV_Send((uint8_t) instance->instIdx,
701  (uint8_t) buffIdx,
702  &dataInfo,
703  message->id,
704  message->data);
705  }
706  #endif
707 
708  return status;
709 }
710 
711 /*FUNCTION**********************************************************************
712  *
713  * Function Name : CAN_SendBlocking
714  * Description : Sends a CAN frame using the specified buffer,
715  * in a blocking manner.
716  *
717  * Implements : CAN_SendBlocking_Activity
718  *END**************************************************************************/
719 status_t CAN_SendBlocking(const can_instance_t * const instance,
720  uint32_t buffIdx,
721  const can_message_t *message,
722  uint32_t timeoutMs)
723 {
724  DEV_ASSERT(instance != NULL);
725  DEV_ASSERT(message != NULL);
726 
727  status_t status = STATUS_ERROR;
728  uint8_t index;
729 
730  /* Define CAN PAL over FLEXCAN */
731  #if defined(CAN_OVER_FLEXCAN)
732  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
733  {
735 
736  index = CAN_FindFlexCANState(instance->instIdx);
737 
738  /* If Rx FIFO is enabled, buffer 0 (zero) can only be used for reception */
739  DEV_ASSERT((s_flexcanRxFifoState[index].rxFifoEn == false) || (buffIdx != 0U));
740  /* Check buffer index to avoid overflow */
742 
743  flexcan_data_info_t dataInfo = {
744  .msg_id_type = (flexcan_msgbuff_id_type_t) s_hwObjConfigs[index][buffIdx]->idType,
745  .data_length = message->length,
747  .fd_enable = s_hwObjConfigs[index][buffIdx]->enableFD,
748  .fd_padding = s_hwObjConfigs[index][buffIdx]->fdPadding,
749  .enable_brs = s_hwObjConfigs[index][buffIdx]->enableBRS,
750 #endif
751  .is_remote = s_hwObjConfigs[index][buffIdx]->isRemote
752  };
753 
754  /* Compute virtual buffer index */
755  if (s_flexcanRxFifoState[index].rxFifoEn)
756  {
757  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
758  }
759 
760  status = FLEXCAN_DRV_SendBlocking((uint8_t) instance->instIdx,
761  (uint8_t) buffIdx,
762  &dataInfo,
763  message->id,
764  message->data,
765  timeoutMs);
766  }
767  #endif
768 
769  return status;
770 }
771 
772 /*FUNCTION**********************************************************************
773  *
774  * Function Name : CAN_Receive
775  * Description : Receives a CAN frame using the specified message buffer.
776  *
777  * Implements : CAN_Receive_Activity
778  *END**************************************************************************/
779 status_t CAN_Receive(const can_instance_t * const instance,
780  uint32_t buffIdx,
781  can_message_t *message)
782 {
783  DEV_ASSERT(instance != NULL);
784  DEV_ASSERT(message != NULL);
785 
786  status_t status = STATUS_ERROR;
787  uint8_t index;
788 
789  /* Define CAN PAL over FLEXCAN */
790  #if defined(CAN_OVER_FLEXCAN)
791  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
792  {
793  /* Check buffer index to avoid overflow */
796 
797  index = CAN_FindFlexCANState(instance->instIdx);
798 
799  /* If Rx FIFO is enabled, buffer 0 (zero) is used to read frames received in FIFO */
800  if ((s_flexcanRxFifoState[index].rxFifoEn == true) && (buffIdx == 0U))
801  {
802  status = FLEXCAN_DRV_RxFifo((uint8_t) instance->instIdx,
803  (flexcan_msgbuff_t *) message);
804  }
805  else
806  {
807  /* Compute virtual buffer index */
808  if (s_flexcanRxFifoState[index].rxFifoEn)
809  {
810  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
811  }
812 
813  status = FLEXCAN_DRV_Receive((uint8_t) instance->instIdx,
814  (uint8_t) buffIdx,
815  (flexcan_msgbuff_t *) message);
816  }
817  }
818  #endif
819 
820  return status;
821 }
822 
823 /*FUNCTION**********************************************************************
824  *
825  * Function Name : CAN_ReceiveBlocking
826  * Description : Receives a CAN frame using the specified buffer,
827  * in a blocking manner.
828  *
829  * Implements : CAN_ReceiveBlocking_Activity
830  *END**************************************************************************/
832  uint32_t buffIdx,
833  can_message_t *message,
834  uint32_t timeoutMs)
835 {
836  DEV_ASSERT(instance != NULL);
837  DEV_ASSERT(message != NULL);
838 
839  status_t status = STATUS_ERROR;
840  uint8_t index;
841 
842  /* Define CAN PAL over FLEXCAN */
843  #if defined(CAN_OVER_FLEXCAN)
844  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
845  {
846  /* Check buffer index to avoid overflow */
849 
850  index = CAN_FindFlexCANState(instance->instIdx);
851 
852  /* If Rx FIFO is enabled, buffer 0 (zero) is used to read frames received in FIFO */
853  if ((s_flexcanRxFifoState[index].rxFifoEn == true) && (buffIdx == 0U))
854  {
855  status = FLEXCAN_DRV_RxFifoBlocking((uint8_t) instance->instIdx,
856  (flexcan_msgbuff_t *) message,
857  timeoutMs);
858  }
859  else
860  {
861  /* Compute virtual buffer index */
862  if (s_flexcanRxFifoState[index].rxFifoEn)
863  {
864  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
865  }
866 
867  status = FLEXCAN_DRV_ReceiveBlocking((uint8_t) instance->instIdx,
868  (uint8_t) buffIdx,
869  (flexcan_msgbuff_t *) message,
870  timeoutMs);
871  }
872  }
873  #endif
874 
875  return status;
876 }
877 
878 /*FUNCTION**********************************************************************
879  *
880  * Function Name : CAN_AbortTransfer
881  * Description : This function ends a non-blocking CAN transfer early.
882  *
883  * Implements : CAN_AbortTransfer_Activity
884  *END**************************************************************************/
886  uint32_t buffIdx)
887 {
888  DEV_ASSERT(instance != NULL);
889 
890  status_t status = STATUS_ERROR;
891  uint8_t index;
892 
893  /* Define CAN PAL over FLEXCAN */
894  #if defined(CAN_OVER_FLEXCAN)
895  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
896  {
897  /* Check buffer index to avoid overflow */
900 
901  index = CAN_FindFlexCANState(instance->instIdx);
902 
903  /* Compute virtual buffer index */
904  if (s_flexcanRxFifoState[index].rxFifoEn)
905  {
906  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
907  }
908 
909  status = FLEXCAN_DRV_AbortTransfer((uint8_t) instance->instIdx,
910  buffIdx);
911  }
912  #endif
913 
914  return status;
915 }
916 
917 /*FUNCTION**********************************************************************
918  *
919  * Function Name : CAN_SetRxFilter
920  * Description : Configures an ID filter for a specific reception buffer.
921  *
922  * Implements : CAN_SetRxFilter_Activity
923  *END**************************************************************************/
924 status_t CAN_SetRxFilter(const can_instance_t * const instance,
925  can_msg_id_type_t idType,
926  uint32_t buffIdx,
927  uint32_t mask)
928 {
929  DEV_ASSERT(instance != NULL);
930 
931  status_t status = STATUS_ERROR;
932  uint8_t index;
933 
934  /* Define CAN PAL over FLEXCAN */
935  #if defined(CAN_OVER_FLEXCAN)
936  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
937  {
939 
940  index = CAN_FindFlexCANState(instance->instIdx);
941 
942  /* If Rx FIFO is enabled, buffer 0 (zero) filters are configured at init time */
943  DEV_ASSERT((s_flexcanRxFifoState[index].rxFifoEn == false) || (buffIdx != 0U));
944  (void) index;
945  /* Check buffer index to avoid overflow */
947 
948  FLEXCAN_DRV_SetRxMaskType((uint8_t) instance->instIdx,
950  status = FLEXCAN_DRV_SetRxIndividualMask((uint8_t) instance->instIdx,
951  (flexcan_msgbuff_id_type_t) idType,
952  (uint8_t) buffIdx,
953  mask);
954  }
955  #endif
956 
957  return status;
958 }
959 
960 /*FUNCTION**********************************************************************
961  *
962  * Function Name : CAN_GetTransferStatus
963  * Description : Returns the state of the previous CAN transfer.
964  *
965  * Implements : CAN_GetTransferStatus_Activity
966  *END**************************************************************************/
968  uint32_t buffIdx)
969 {
970  DEV_ASSERT(instance != NULL);
971 
972  status_t status = STATUS_ERROR;
973  uint8_t index;
974 
975  /* Define CAN PAL over FLEXCAN */
976  #if defined(CAN_OVER_FLEXCAN)
977  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
978  {
979  /* Check buffer index to avoid overflow */
982 
983  index = CAN_FindFlexCANState(instance->instIdx);
984 
985  /* Compute virtual buffer index */
986  if ((s_flexcanRxFifoState[index].rxFifoEn) && (buffIdx != 0U))
987  {
988  buffIdx += CAN_GetVirtualBuffIdx(s_flexcanRxFifoState[index].numIdFilters);
989  }
990 
991  status = FLEXCAN_DRV_GetTransferStatus((uint8_t) instance->instIdx,
992  (uint8_t) buffIdx);
993  }
994  #endif
995 
996  return status;
997 }
998 
999 /*FUNCTION**********************************************************************
1000  *
1001  * Function Name : CAN_InstallEventCallback
1002  * Description : Installs a callback function for the IRQ handler.
1003  *
1004  * Implements : CAN_InstallEventCallback_Activity
1005  *END**************************************************************************/
1007  can_callback_t callback,
1008  void *callbackParam)
1009 {
1010  DEV_ASSERT(instance != NULL);
1011 
1012  status_t status = STATUS_ERROR;
1013  uint8_t index;
1014 
1015  /* Define CAN PAL over FLEXCAN */
1016  #if defined(CAN_OVER_FLEXCAN)
1017  if (instance->instType == CAN_INST_TYPE_FLEXCAN)
1018  {
1019  if (callback != NULL)
1020  {
1021  DEV_ASSERT(instance->instIdx < CAN_INSTANCE_COUNT);
1022 
1023  index = CAN_FindFlexCANState(instance->instIdx);
1024 
1025  /* Save user callback */
1026  userCallbacks[index] = callback;
1027  /* Install internal FlexCAN callback */
1028  FLEXCAN_DRV_InstallEventCallback((uint8_t) instance->instIdx,
1029  CAN_InternalCallback,
1030  callbackParam);
1031  }
1032  else
1033  {
1034  /* Uninstall internal FlexCAN callback */
1035  FLEXCAN_DRV_InstallEventCallback((uint8_t) instance->instIdx,
1036  NULL,
1037  callbackParam);
1038  }
1039 
1040  status = STATUS_SUCCESS;
1041  }
1042  #endif
1043 
1044  return status;
1045 }
1046 
1047 /*******************************************************************************
1048  * EOF
1049  ******************************************************************************/
#define FEATURE_CAN_HAS_FD
void * extension
Definition: can_pal.h:128
status_t CAN_Receive(const can_instance_t *const instance, uint32_t buffIdx, can_message_t *message)
Receives a CAN frame using the specified message buffer.
Definition: can_pal.c:779
status_t CAN_AbortTransfer(const can_instance_t *const instance, uint32_t buffIdx)
Ends a non-blocking CAN transfer early.
Definition: can_pal.c:885
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.
void FLEXCAN_DRV_GetBitrateFD(uint8_t instance, flexcan_time_segment_t *bitrate)
Gets the FlexCAN bit rate for the data phase of FD frames (BRS enabled).
status_t FLEXCAN_DRV_Deinit(uint8_t instance)
Shuts down a FlexCAN instance.
Internal driver state information.
flexcan_msgbuff_id_type_t
FlexCAN Message Buffer ID type Implements : flexcan_msgbuff_id_type_t_Class.
can_inst_type_t instType
flexcan_operation_modes_t flexcanMode
can_time_segment_t dataBitrate
Definition: can_pal.h:127
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.
flexcan_time_segment_t bitrate
uint32_t maxBuffNum
Definition: can_pal.h:121
uint32_t preDivider
Definition: can_pal.h:66
status_t CAN_GetTransferStatus(const can_instance_t *const instance, uint32_t buffIdx)
Returns the state of the previous CAN transfer.
Definition: can_pal.c:967
flexcan_rx_fifo_id_filter_num_t num_id_filters
flexcan_clk_source_t
FlexCAN PE clock sources Implements : flexcan_clk_source_t_Class.
status_t FLEXCAN_DRV_RxFifo(uint8_t instance, flexcan_msgbuff_t *data)
Receives a CAN frame using the message FIFO.
flexcan_rx_fifo_id_filter_num_t
FlexCAN Rx FIFO filters number Implements : flexcan_rx_fifo_id_filter_num_t_Class.
status_t CAN_ConfigRxBuff(const can_instance_t *const instance, uint32_t buffIdx, const can_buff_config_t *config, uint32_t acceptedId)
Configures a buffer for reception.
Definition: can_pal.c:598
can_msg_id_type_t
CAN Message Buffer ID type Implements : can_msg_id_type_t_Class.
Definition: can_pal.h:81
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.
status_t FLEXCAN_DRV_GetTransferStatus(uint8_t instance, uint8_t mb_idx)
Returns whether the previous FlexCAN transfer has finished.
flexcan_msgbuff_id_type_t msg_id_type
flexcan_event_type_t
The type of the event which occurred when the callback was invoked. Implements : flexcan_event_type_t...
can_operation_modes_t mode
Definition: can_pal.h:122
void FLEXCAN_DRV_InstallEventCallback(uint8_t instance, flexcan_callback_t callback, void *callbackParam)
Installs a callback function for the IRQ handler.
uint32_t phaseSeg2
Definition: can_pal.h:65
#define CAN_INSTANCE_COUNT
Definition: S32K118.h:840
#define DEV_ASSERT(x)
Definition: devassert.h:77
status_t CAN_InstallEventCallback(const can_instance_t *const instance, can_callback_t callback, void *callbackParam)
Installs a callback function for the IRQ handler.
Definition: can_pal.c:1006
uint8_t length
Definition: can_pal.h:113
uint8_t data[64]
Definition: can_pal.h:112
#define FEATURE_CAN_MAX_MB_NUM
status_t FLEXCAN_DRV_AbortTransfer(uint8_t instance, uint8_t mb_idx)
Ends a non-blocking FlexCAN transfer early.
void FLEXCAN_DRV_SetRxMaskType(uint8_t instance, flexcan_rx_mask_type_t type)
Sets the Rx masking type.
status_t CAN_ConfigTxBuff(const can_instance_t *const instance, uint32_t buffIdx, const can_buff_config_t *config)
Configures a buffer for transmission.
Definition: can_pal.c:472
FlexCAN bitrate related structures Implements : flexcan_time_segment_t_Class.
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.
status_t CAN_Deinit(const can_instance_t *const instance)
De-initializes the CAN module.
Definition: can_pal.c:358
status_t CAN_SendBlocking(const can_instance_t *const instance, uint32_t buffIdx, const can_message_t *message, uint32_t timeoutMs)
Sends a CAN frame using the specified buffer, in a blocking manner.
Definition: can_pal.c:719
status_t FLEXCAN_DRV_ConfigRemoteResponseMb(uint8_t instance, uint8_t mb_idx, const flexcan_data_info_t *tx_info, uint32_t msg_id, const uint8_t *mb_data)
Configures a transmit message buffer for remote frame response.
void(* can_callback_t)(uint32_t instance, can_event_t eventType, uint32_t objIdx, void *driverState)
Definition: callbacks.h:158
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:44
Structure storing PAL instance information.
CAN buffer configuration Implements : can_buff_config_t_Class.
Definition: can_pal.h:97
status_t CAN_GetBitrate(const can_instance_t *const instance, can_bitrate_phase_t phase, can_time_segment_t *bitTiming)
Returns the CAN bitrate.
Definition: can_pal.c:432
static uint8_t CAN_AllocateState(bool *isAllocated, uint32_t *instanceMapping, uint32_t instance, uint8_t numberOfinstances)
Definition: can_pal.c:114
uint32_t rJumpwidth
Definition: can_pal.h:67
FlexCAN message buffer structure Implements : flexcan_msgbuff_t_Class.
status_t CAN_SetBitrate(const can_instance_t *const instance, can_bitrate_phase_t phase, const can_time_segment_t *bitTiming)
Configures the CAN bitrate.
Definition: can_pal.c:392
can_clk_source_t peClkSrc
Definition: can_pal.h:123
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.
CAN controller configuration Implements : can_user_config_t_Class.
Definition: can_pal.h:119
can_msg_id_type_t idType
Definition: can_pal.h:102
status_t CAN_Send(const can_instance_t *const instance, uint32_t buffIdx, const can_message_t *message)
Sends a CAN frame using the specified buffer.
Definition: can_pal.c:660
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.
CAN message format Implements : can_message_t_Class.
Definition: can_pal.h:109
CAN bit timing variables Implements : can_time_segment_t_Class.
Definition: can_pal.h:62
flexcan_time_segment_t bitrate_cbt
flexcan_rxfifo_transfer_type_t transfer_type
can_fd_payload_size_t payloadSize
Definition: can_pal.h:125
can_bitrate_phase_t
CAN bitrate phase (nominal/data) Implements : can_bitrate_phase_t_Class.
Definition: can_pal.h:73
uint32_t id
Definition: can_pal.h:111
can_time_segment_t nominalBitrate
Definition: can_pal.h:126
uint8_t fdPadding
Definition: can_pal.h:100
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 the data phase of FD frames (BRS enabled).
status_t CAN_SetRxFilter(const can_instance_t *const instance, can_msg_id_type_t idType, uint32_t buffIdx, uint32_t mask)
Configures an ID filter for a specific reception buffer.
Definition: can_pal.c:924
uint32_t propSeg
Definition: can_pal.h:63
FlexCAN data info from user Implements : flexcan_data_info_t_Class.
status_t FLEXCAN_DRV_Init(uint8_t instance, flexcan_state_t *state, const flexcan_user_config_t *data)
Initializes the FlexCAN peripheral.
flexcan_fd_payload_size_t
FlexCAN payload sizes Implements : flexcan_fd_payload_size_t_Class.
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 mask (standard or extended).
status_t CAN_ConfigRemoteResponseBuff(const can_instance_t *const instance, uint32_t buffIdx, const can_buff_config_t *config, const can_message_t *message)
Configures a transmit buffer for remote frame response.
Definition: can_pal.c:535
status_t CAN_ReceiveBlocking(const can_instance_t *const instance, uint32_t buffIdx, can_message_t *message, uint32_t timeoutMs)
Receives a CAN frame using the specified buffer, in a blocking manner.
Definition: can_pal.c:831
void FLEXCAN_DRV_SetBitrate(uint8_t instance, const flexcan_time_segment_t *bitrate)
Sets the FlexCAN bit rate for standard frames or the arbitration phase of FD frames.
uint32_t phaseSeg1
Definition: can_pal.h:64
flexcan_clk_source_t pe_clock
FlexCAN configuration.
status_t CAN_Init(const can_instance_t *const instance, const can_user_config_t *config)
Initializes the CAN module.
Definition: can_pal.c:251
flexcan_operation_modes_t
FlexCAN operation modes Implements : flexcan_operation_modes_t_Class.
void FLEXCAN_DRV_GetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate)
Gets the FlexCAN bit rate for standard frames or the arbitration phase of FD frames.
static void CAN_FreeState(bool *isAllocated, const uint32_t *instanceMapping, uint32_t instance, uint8_t numberOfinstances)
Definition: can_pal.c:139