1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8
9 #ifndef HPM_MBX_DRV_H
10 #define HPM_MBX_DRV_H
11 #include "hpm_common.h"
12 #include "hpm_mbx_regs.h"
13
14 /**
15 * @brief MBX driver APIs
16 * @defgroup mbx_interface MBX driver APIs
17 * @ingroup io_interfaces
18 * @{
19 */
20
21 /*
22 * @brief Bus access responses
23 */
24 typedef enum {
25 no_bus_error_no_wait = 0,
26 generate_bus_error = 1,
27 } mbx_bus_access_resp_t;
28
29 /*
30 * @brief MBX specific status
31 */
32 enum {
33 status_mbx_not_available = MAKE_STATUS(status_group_mbx, 2),
34 };
35
36 #define MBX_CR_ALL_INTERRUPTS_MASK (MBX_CR_TFMAIE_MASK | MBX_CR_RFMAIE_MASK \
37 | MBX_CR_RFMFIE_MASK | MBX_CR_TWMEIE_MASK)
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * @brief Set bus access response
45 *
46 * @param[in] ptr MBX base address
47 * @param[in] resp response value type
48 */
mbx_set_bus_access_response(MBX_Type * ptr,mbx_bus_access_resp_t resp)49 static inline void mbx_set_bus_access_response(MBX_Type *ptr, mbx_bus_access_resp_t resp)
50 {
51 ptr->CR = (ptr->CR & ~(MBX_CR_BARCTL_MASK)) | MBX_CR_BARCTL_SET(resp);
52 }
53
54 /**
55 * @brief Enable interrupt with mask
56 *
57 * @param[in] ptr MBX base address
58 * @param[in] mask Mask of interrupts to be enabled
59 */
mbx_enable_intr(MBX_Type * ptr,uint8_t mask)60 static inline void mbx_enable_intr(MBX_Type *ptr, uint8_t mask)
61 {
62 ptr->CR |= mask;
63 }
64
65 /**
66 * @brief Disable interrupt with mask
67 *
68 * @param[in] ptr MBX base address
69 * @param[in] mask Mask of interrupts to be disabled
70 */
mbx_disable_intr(MBX_Type * ptr,uint8_t mask)71 static inline void mbx_disable_intr(MBX_Type *ptr, uint8_t mask)
72 {
73 ptr->CR &= ~mask;
74 }
75
76 /**
77 * @brief Empty fifo
78 *
79 * @param[in] ptr MBX base address
80 */
mbx_empty_txfifo(MBX_Type * ptr)81 static inline void mbx_empty_txfifo(MBX_Type *ptr)
82 {
83 ptr->CR |= MBX_CR_TXRESET_MASK;
84 }
85
86 /**
87 * @brief Initialization
88 *
89 * @param[in] ptr MBX base address
90 */
mbx_init(MBX_Type * ptr)91 static inline void mbx_init(MBX_Type *ptr)
92 {
93 mbx_empty_txfifo(ptr);
94 mbx_disable_intr(ptr, MBX_CR_ALL_INTERRUPTS_MASK);
95 }
96
97 /**
98 * @brief Send message
99 *
100 * @param[in] ptr MBX base address
101 * @param[in] msg Message data in 32 bits
102 *
103 * @return status_success if everything is okay
104 */
mbx_send_message(MBX_Type * ptr,uint32_t msg)105 static inline hpm_stat_t mbx_send_message(MBX_Type *ptr, uint32_t msg)
106 {
107 if (ptr->SR & MBX_SR_TWME_MASK) {
108 ptr->TXREG = msg;
109 return status_success;
110 }
111 return status_mbx_not_available;
112 }
113
114
115 /**
116 * @brief Retrieve message
117 *
118 * @param[in] ptr MBX base address
119 * @param[out] msg Pointer to buffer to save message data
120 *
121 * @return status_success if everything is okay
122 */
mbx_retrieve_message(MBX_Type * ptr,uint32_t * msg)123 static inline hpm_stat_t mbx_retrieve_message(MBX_Type *ptr, uint32_t *msg)
124 {
125 if (ptr->SR & MBX_SR_RWMV_MASK) {
126 *msg = ptr->RXREG;
127 return status_success;
128 }
129 return status_mbx_not_available;
130 }
131
132 /**
133 * @brief Send message to fifo
134 *
135 * @param[in] ptr MBX base address
136 * @param[in] msg Pointer to message array to be sent
137 * @param[in] count Number of 32-bit data to be sent
138 *
139 * @return status_success if everything is okay
140 * @return status_not_available if fifo is full
141 */
mbx_send_fifo(MBX_Type * ptr,uint32_t * msg,uint32_t count)142 static inline hpm_stat_t mbx_send_fifo(MBX_Type *ptr, uint32_t *msg, uint32_t count)
143 {
144 uint32_t i;
145 hpm_stat_t status = status_success;
146 for (i = 0; i < 4; i++) {
147 if (ptr->SR & MBX_SR_TFMA_MASK) {
148 ptr->TXWRD[0] = MBX_TXWRD_TXFIFO_SET(*(msg + i));
149 count--;
150 if (!count) {
151 break;
152 }
153 } else {
154 status = status_mbx_not_available;
155 break;
156 }
157 }
158 return status;
159 }
160
161
162
163 /**
164 * @brief Retrieve data from fifo
165 *
166 * @param[in] ptr MBX base address
167 * @param[out] msg Pointer of buffer to receive data
168 * @param[in] count Number of 32-bit data to be retrieved
169 *
170 * @return status_success if everything is okay
171 * @return status_mbx_not_available if fifo is empty
172 */
mbx_retrieve_fifo(MBX_Type * ptr,uint32_t * msg,uint32_t count)173 static inline hpm_stat_t mbx_retrieve_fifo(MBX_Type *ptr, uint32_t *msg, uint32_t count)
174 {
175 uint32_t i;
176 hpm_stat_t status = status_success;
177 for (i = 0; i < 4; i++) {
178 if (ptr->SR & MBX_SR_RFMA_MASK) {
179 *(msg + i) = (ptr->RXWRD[0] & MBX_RXWRD_RXFIFO_MASK) >> MBX_RXWRD_RXFIFO_SHIFT;
180 count--;
181 if (!count) {
182 break;
183 }
184 } else {
185 status = status_mbx_not_available;
186 break;
187 }
188 }
189 return status;
190 }
191
192 #ifdef __cplusplus
193 }
194 #endif
195 /**
196 * @}
197 */
198 #endif /* HPM_MBX_DRV_H */
199