1 /*
2  * @ : Copyright (c) 2021 Phytium Information Technology, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0.
5  *
6  * @Date: 2021-04-07 09:53:07
7  * @LastEditTime: 2021-05-25 16:49:42
8  * @Description:  This files is for uart irq functions
9  *
10  * @Modify History:
11  *  Ver   Who        Date         Changes
12  * ----- ------     --------    --------------------------------------
13  */
14 
15 #include "ft_uart.h"
16 
17 extern u32 FUart_SendBuffer(Ft_Uart *UartPtr);
18 extern u32 FUart_ReceiveBuffer(Ft_Uart *UartPtr);
19 
20 static void FUart_receiveErrorHandler(Ft_Uart *UartPtr, u32 InterruptStatus);
21 static void FUart_receiveDataHandler(Ft_Uart *UartPtr);
22 static void FUart_receiveTimeoutHandler(Ft_Uart *UartPtr);
23 static void FUart_sendDataHandler(Ft_Uart *UartPtr, u32 InterruptStatus);
24 
25 /**
26  * @name: FUart_GetInterruptMask
27  * @msg:  此函数获取所有串口中断的mask。
28  * @param {Ft_Uart} *UartPtr
29  * @return {u32} mask
30  */
FUart_GetInterruptMask(Ft_Uart * UartPtr)31 u32 FUart_GetInterruptMask(Ft_Uart *UartPtr)
32 {
33     Ft_assertNonvoid(UartPtr != NULL);
34 
35     return FT_UART_ReadReg(UartPtr->Config.BaseAddress, UARTIMSC_OFFSET);
36 }
37 
FUart_SetInterruptMask(Ft_Uart * UartPtr,u32 Mask)38 void FUart_SetInterruptMask(Ft_Uart *UartPtr, u32 Mask)
39 {
40     u32 TempMask = Mask;
41     Ft_assertVoid(UartPtr != NULL);
42 
43     TempMask &= UARTIMSC_ALLM;
44 
45     FT_UART_WriteReg(UartPtr->Config.BaseAddress, UARTIMSC_OFFSET, TempMask);
46 }
47 
48 /**
49  * @name: FUart_SetHandler
50  * @msg:  设置中断回调函数
51  * @param {*}
52  * @return {*}
53  */
FUart_SetHandler(Ft_Uart * UartPtr,FUart_Handler_t FuncPtr,void * Args)54 void FUart_SetHandler(Ft_Uart *UartPtr, FUart_Handler_t FuncPtr,
55                       void *Args)
56 {
57     Ft_assertVoid(UartPtr != NULL);
58     Ft_assertVoid(FuncPtr != NULL);
59     Ft_assertVoid(UartPtr->IsReady == FT_COMPONENT_IS_READLY);
60 
61     UartPtr->Handler = FuncPtr;
62     UartPtr->Args = Args;
63 }
64 
65 /**
66  * @name: FUart_InterruptHandler
67  * @msg:  串口中断函数入口
68  * @param {Ft_Uart} *UartPtr
69  * @return {*}
70  */
FUart_InterruptHandler(Ft_Uart * UartPtr)71 void FUart_InterruptHandler(Ft_Uart *UartPtr)
72 {
73     u32 RegValue = 0;
74     Ft_assertVoid(UartPtr != NULL);
75     Ft_assertVoid(UartPtr->IsReady == FT_COMPONENT_IS_READLY);
76     //Ft_printf("FUart_InterruptHandler %x\r\n", UartPtr);
77     RegValue = FT_UART_ReadReg(UartPtr->Config.BaseAddress, UARTIMSC_OFFSET);
78 
79     RegValue &= FT_UART_ReadReg(UartPtr->Config.BaseAddress, UARTMIS_OFFSET);
80 
81     if ((RegValue & ((u32)UARTMIS_RXMIS)) != (u32)0)
82     {
83         /* Received data interrupt */
84         FUart_receiveDataHandler(UartPtr);
85     }
86 
87     if ((RegValue & ((u32)UARTMIS_TXMIS)) != (u32)0)
88     {
89         /* Transmit data interrupt */
90         FUart_sendDataHandler(UartPtr, RegValue);
91     }
92 
93     if (((RegValue) & ((u32)UARTMIS_OEMIS | (u32)UARTMIS_BEMIS | (u32)UARTMIS_PEMIS | (u32)UARTMIS_FEMIS)) != (u32)0)
94     {
95         /* Received Error Status interrupt */
96         FUart_receiveErrorHandler(UartPtr, RegValue);
97     }
98 
99     if ((RegValue & ((u32)UARTMIS_RTMIS)) != (u32)0)
100     {
101         /* Received Timeout interrupt */
102         FUart_receiveTimeoutHandler(UartPtr);
103     }
104 
105     if (((RegValue) & ((u32)UARTMIS_DSRMMIS | (u32)UARTMIS_DCDMMIS | (u32)UARTMIS_CTSMMIS | (u32)UARTMIS_RIMMIS)) != (u32)0)
106     {
107         /* Modem status interrupt */
108     }
109 
110     /* Clear the interrupt status. */
111     FT_UART_WriteReg(UartPtr->Config.BaseAddress, UARTICR_OFFSET,
112                      RegValue);
113 }
114 
FUart_receiveErrorHandler(Ft_Uart * UartPtr,u32 InterruptStatus)115 static void FUart_receiveErrorHandler(Ft_Uart *UartPtr, u32 InterruptStatus)
116 {
117     UartPtr->rxbs_error = 0;
118 
119     if (((InterruptStatus) & ((u32)UARTMIS_OEMIS | (u32)UARTMIS_BEMIS | (u32)UARTMIS_PEMIS | (u32)UARTMIS_FEMIS)) != 0)
120     {
121         UartPtr->rxbs_error = 1;
122     }
123 
124     (void)FUart_ReceiveBuffer(UartPtr);
125 
126     if (0 == UartPtr->rxbs_error)
127     {
128         if (UartPtr->Handler)
129         {
130             UartPtr->Handler(UartPtr->Args, FUART_EVENT_RECV_ERROR, UartPtr->ReceiveBuffer.RequestedBytes - UartPtr->ReceiveBuffer.RemainingBytes);
131         }
132     }
133 }
134 
FUart_receiveDataHandler(Ft_Uart * UartPtr)135 static void FUart_receiveDataHandler(Ft_Uart *UartPtr)
136 {
137     if ((u32)0 != UartPtr->ReceiveBuffer.RemainingBytes)
138     {
139         (void)FUart_ReceiveBuffer(UartPtr);
140     }
141 
142     if ((u32)0 == UartPtr->ReceiveBuffer.RemainingBytes)
143     {
144         if (UartPtr->Handler)
145         {
146             UartPtr->Handler(UartPtr->Args, FUART_EVENT_RECV_DATA, UartPtr->ReceiveBuffer.RequestedBytes - UartPtr->ReceiveBuffer.RemainingBytes);
147         }
148     }
149 }
150 
FUart_receiveTimeoutHandler(Ft_Uart * UartPtr)151 static void FUart_receiveTimeoutHandler(Ft_Uart *UartPtr)
152 {
153     u32 Event;
154 
155     if ((u32)0 != UartPtr->ReceiveBuffer.RemainingBytes)
156     {
157         (void)FUart_ReceiveBuffer(UartPtr);
158     }
159 
160     if ((u32)0 == UartPtr->ReceiveBuffer.RemainingBytes)
161     {
162         Event = FUART_EVENT_RECV_TOUT;
163     }
164     else
165     {
166         Event = FUART_EVENT_RECV_DATA;
167     }
168 
169     if (UartPtr->Handler)
170     {
171         UartPtr->Handler(UartPtr->Args, Event, UartPtr->ReceiveBuffer.RequestedBytes - UartPtr->ReceiveBuffer.RemainingBytes);
172     }
173 }
174 
FUart_sendDataHandler(Ft_Uart * UartPtr,u32 InterruptStatus)175 static void FUart_sendDataHandler(Ft_Uart *UartPtr, u32 InterruptStatus)
176 {
177     u32 RegValue;
178     if (UartPtr->SendBuffer.RemainingBytes == (u32)0)
179     {
180         //<! close send isr
181         RegValue = FT_UART_ReadReg(UartPtr->Config.BaseAddress, UARTIMSC_OFFSET);
182         RegValue &= ~UARTIMSC_TXIM;
183         FT_UART_WriteReg(UartPtr->Config.BaseAddress, UARTIMSC_OFFSET, RegValue);
184         if (UartPtr->Handler)
185         {
186             UartPtr->Handler(UartPtr->Args, FUART_EVENT_RECV_DATA, UartPtr->ReceiveBuffer.RequestedBytes - UartPtr->ReceiveBuffer.RemainingBytes);
187         }
188     }
189     else if (InterruptStatus & UARTMIS_TXMIS)
190     {
191         FUart_SendBuffer(UartPtr);
192     }
193     else
194     {
195     }
196 }
197