1 /*
2 * @ : Copyright (c) 2021 Phytium Information Technology, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0.
5 *
6 * @Date: 2021-04-29 10:40:47
7 * @LastEditTime: 2021-04-29 10:40:47
8 * @Description: Description of file
9 * @Modify History:
10 * * * Ver Who Date Changes
11 * * ----- ------ -------- --------------------------------------
12 */
13
14 #include "ft_can.h"
15 #include "ft_can_hw.h"
16 #include "ft_assert.h"
17 #include "ft_types.h"
18
FCan_SetHandler(FCan_t * Can_p,u32 HandlerType,FCan_irqHandler_t IrqCallBackFunc,void * IrqCallBackRef)19 ft_error_t FCan_SetHandler(FCan_t *Can_p, u32 HandlerType, FCan_irqHandler_t IrqCallBackFunc, void *IrqCallBackRef)
20 {
21 ft_error_t status = FCAN_SUCCESS;
22 Ft_assertNonvoid(Can_p != NULL);
23 Ft_assertNonvoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
24 switch (HandlerType)
25 {
26 case FCAN_HANDLER_SEND:
27 Can_p->SendHandler = IrqCallBackFunc;
28 Can_p->SendRef = IrqCallBackRef;
29 break;
30 case FCAN_HANDLER_RECV:
31 Can_p->RecvHandler = IrqCallBackFunc;
32 Can_p->RecvRef = IrqCallBackRef;
33 break;
34 case FCAN_HANDLER_ERROR:
35 Can_p->ErrorHandler = IrqCallBackFunc;
36 Can_p->ErrorRef = IrqCallBackRef;
37 break;
38 default:
39 status = FCAN_FAILURE;
40 }
41
42 return status;
43 }
44
FCan_TxInterrupt(FCan_t * Can_p)45 static void FCan_TxInterrupt(FCan_t *Can_p)
46 {
47 FCan_Config_t *Config_p = &Can_p->Config;
48 FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_TEIC_MASK | FCAN_INTR_REIC_MASK);
49
50 if (0 != Can_p->TxFifoCnt)
51 {
52 Can_p->TxFifoCnt--;
53 FCan_ClearBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
54 FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_TXREQ_MASK);
55 FCan_SetBit(Config_p->CanBaseAddress, FCAN_CTRL_OFFSET, FCAN_CTRL_XFER_MASK);
56 }
57 else
58 {
59 if (Can_p->SendHandler)
60 {
61 Can_p->SendHandler(Can_p->SendRef);
62 }
63 }
64 }
65
FCan_ErrorInterrupt(FCan_t * Can_p)66 static void FCan_ErrorInterrupt(FCan_t *Can_p)
67 {
68 if (Can_p->ErrorHandler)
69 {
70 Can_p->ErrorHandler(Can_p->ErrorRef);
71 }
72 }
73
FCan_RxInterrupt(FCan_t * Can_p)74 static void FCan_RxInterrupt(FCan_t *Can_p)
75 {
76 if (Can_p->RecvHandler)
77 {
78 Can_p->RecvHandler(Can_p->RecvRef);
79 }
80 }
81
FCan_IntrHandler(void * InstancePtr)82 void FCan_IntrHandler(void *InstancePtr)
83 {
84 u32 Irq;
85 FCan_t *Can_p = (FCan_t *)InstancePtr;
86 FCan_Config_t *Config_p;
87 Ft_assertVoid(Can_p != NULL);
88 Ft_assertVoid(Can_p->IsReady == FT_COMPONENT_IS_READLY);
89 Config_p = &Can_p->Config;
90 Irq = FCan_ReadReg(Config_p->CanBaseAddress, FCAN_INTR_OFFSET);
91
92 if (0 == Irq)
93 {
94 return;
95 }
96
97 /* Check for the type of error interrupt and Processing it */
98 if (Irq & FCAN_INTR_TEIS_MASK)
99 {
100 Irq &= ~FCAN_INTR_REIS_MASK;
101 FCan_TxInterrupt(Can_p);
102 }
103
104 if (Irq & (FCAN_INTR_EIS_MASK | FCAN_INTR_RFIS_MASK |
105 FCAN_INTR_BOIS_MASK | FCAN_INTR_PEIS_MASK | FCAN_INTR_PWIS_MASK))
106 {
107 FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, (FCAN_INTR_EIC_MASK | FCAN_INTR_RFIC_MASK | FCAN_INTR_BOIC_MASK | FCAN_INTR_PEIC_MASK | FCAN_INTR_PWIC_MASK));
108 FCan_ErrorInterrupt(Can_p);
109 }
110
111 if (Irq & FCAN_INTR_REIS_MASK)
112 {
113 FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_REIE_MASK);
114 FCan_RxInterrupt(Can_p);
115 FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_REIC_MASK);
116 FCan_SetBit(Config_p->CanBaseAddress, FCAN_INTR_OFFSET, FCAN_INTR_REIE_MASK);
117 }
118 }
119