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