ChibiOS/HAL  6.1.0
hal_mac.c
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 
17 /**
18  * @file hal_mac.c
19  * @brief MAC Driver code.
20  *
21  * @addtogroup MAC
22  * @{
23  */
24 
25 #include "hal.h"
26 
27 #if (HAL_USE_MAC == TRUE) || defined(__DOXYGEN__)
28 
29 /*===========================================================================*/
30 /* Driver local definitions. */
31 /*===========================================================================*/
32 
33 #if (MAC_USE_ZERO_COPY == TRUE) && (MAC_SUPPORTS_ZERO_COPY == FALSE)
34 #error "MAC_USE_ZERO_COPY not supported by this implementation"
35 #endif
36 
37 /*===========================================================================*/
38 /* Driver exported variables. */
39 /*===========================================================================*/
40 
41 /*===========================================================================*/
42 /* Driver local variables and types. */
43 /*===========================================================================*/
44 
45 /*===========================================================================*/
46 /* Driver local functions. */
47 /*===========================================================================*/
48 
49 /*===========================================================================*/
50 /* Driver interrupt handlers. */
51 /*===========================================================================*/
52 
53 /*===========================================================================*/
54 /* Driver exported functions. */
55 /*===========================================================================*/
56 
57 /**
58  * @brief MAC Driver initialization.
59  * @note This function is implicitly invoked by @p halInit(), there is
60  * no need to explicitly initialize the driver.
61  *
62  * @init
63  */
64 void macInit(void) {
65 
66  mac_lld_init();
67 }
68 
69 /**
70  * @brief Initialize the standard part of a @p MACDriver structure.
71  *
72  * @param[out] macp pointer to the @p MACDriver object
73  *
74  * @init
75  */
76 void macObjectInit(MACDriver *macp) {
77 
78  macp->state = MAC_STOP;
79  macp->config = NULL;
82 #if MAC_USE_EVENTS == TRUE
84 #endif
85 }
86 
87 /**
88  * @brief Configures and activates the MAC peripheral.
89  *
90  * @param[in] macp pointer to the @p MACDriver object
91  * @param[in] config pointer to the @p MACConfig object
92  *
93  * @api
94  */
95 void macStart(MACDriver *macp, const MACConfig *config) {
96 
97  osalDbgCheck((macp != NULL) && (config != NULL));
98 
99  osalSysLock();
100  osalDbgAssert(macp->state == MAC_STOP,
101  "invalid state");
102  macp->config = config;
103  mac_lld_start(macp);
104  macp->state = MAC_ACTIVE;
105  osalSysUnlock();
106 }
107 
108 /**
109  * @brief Deactivates the MAC peripheral.
110  *
111  * @param[in] macp pointer to the @p MACDriver object
112  *
113  * @api
114  */
115 void macStop(MACDriver *macp) {
116 
117  osalDbgCheck(macp != NULL);
118 
119  osalSysLock();
120 
121  osalDbgAssert((macp->state == MAC_STOP) || (macp->state == MAC_ACTIVE),
122  "invalid state");
123 
124  mac_lld_stop(macp);
125  macp->config = NULL;
126  macp->state = MAC_STOP;
127 
128  osalSysUnlock();
129 }
130 
131 /**
132  * @brief Allocates a transmission descriptor.
133  * @details One of the available transmission descriptors is locked and
134  * returned. If a descriptor is not currently available then the
135  * invoking thread is queued until one is freed.
136  *
137  * @param[in] macp pointer to the @p MACDriver object
138  * @param[out] tdp pointer to a @p MACTransmitDescriptor structure
139  * @param[in] timeout the number of ticks before the operation timeouts,
140  * the following special values are allowed:
141  * - @a TIME_IMMEDIATE immediate timeout.
142  * - @a TIME_INFINITE no timeout.
143  * .
144  * @return The operation status.
145  * @retval MSG_OK the descriptor was obtained.
146  * @retval MSG_TIMEOUT the operation timed out, descriptor not initialized.
147  *
148  * @api
149  */
152  sysinterval_t timeout) {
153  msg_t msg;
154 
155  osalDbgCheck((macp != NULL) && (tdp != NULL));
156  osalDbgAssert(macp->state == MAC_ACTIVE, "not active");
157 
158  while (((msg = mac_lld_get_transmit_descriptor(macp, tdp)) != MSG_OK) &&
159  (timeout > (sysinterval_t)0)) {
160  osalSysLock();
161  msg = osalThreadEnqueueTimeoutS(&macp->tdqueue, timeout);
162  if (msg == MSG_TIMEOUT) {
163  osalSysUnlock();
164  break;
165  }
166  osalSysUnlock();
167  }
168  return msg;
169 }
170 
171 /**
172  * @brief Releases a transmit descriptor and starts the transmission of the
173  * enqueued data as a single frame.
174  *
175  * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
176  *
177  * @api
178  */
180 
181  osalDbgCheck(tdp != NULL);
182 
184 }
185 
186 /**
187  * @brief Waits for a received frame.
188  * @details Stops until a frame is received and buffered. If a frame is
189  * not immediately available then the invoking thread is queued
190  * until one is received.
191  *
192  * @param[in] macp pointer to the @p MACDriver object
193  * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
194  * @param[in] timeout the number of ticks before the operation timeouts,
195  * the following special values are allowed:
196  * - @a TIME_IMMEDIATE immediate timeout.
197  * - @a TIME_INFINITE no timeout.
198  * .
199  * @return The operation status.
200  * @retval MSG_OK the descriptor was obtained.
201  * @retval MSG_TIMEOUT the operation timed out, descriptor not initialized.
202  *
203  * @api
204  */
207  sysinterval_t timeout) {
208  msg_t msg;
209 
210  osalDbgCheck((macp != NULL) && (rdp != NULL));
211  osalDbgAssert(macp->state == MAC_ACTIVE, "not active");
212 
213  while (((msg = mac_lld_get_receive_descriptor(macp, rdp)) != MSG_OK)) {
214  osalSysLock();
215  msg = osalThreadEnqueueTimeoutS(&macp->rdqueue, timeout);
216  if (msg == MSG_TIMEOUT) {
217  osalSysUnlock();
218  break;
219  }
220  osalSysUnlock();
221  }
222  return msg;
223 }
224 
225 /**
226  * @brief Releases a receive descriptor.
227  * @details The descriptor and its buffer are made available for more incoming
228  * frames.
229  *
230  * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
231  *
232  * @api
233  */
235 
236  osalDbgCheck(rdp != NULL);
237 
239 }
240 
241 /**
242  * @brief Updates and returns the link status.
243  *
244  * @param[in] macp pointer to the @p MACDriver object
245  * @return The link status.
246  * @retval true if the link is active.
247  * @retval false if the link is down.
248  *
249  * @api
250  */
252 
253  osalDbgCheck(macp != NULL);
254  osalDbgAssert(macp->state == MAC_ACTIVE, "not active");
255 
256  return mac_lld_poll_link_status(macp);
257 }
258 
259 #endif /* HAL_USE_MAC == TRUE */
260 
261 /** @} */
void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp)
Releases a receive descriptor.
Definition: hal_mac.c:234
msg_t macWaitTransmitDescriptor(MACDriver *macp, MACTransmitDescriptor *tdp, sysinterval_t timeout)
Allocates a transmission descriptor.
Definition: hal_mac.c:150
threads_queue_t tdqueue
Transmit semaphore.
Definition: hal_mac_lld.h:91
void mac_lld_init(void)
Low level MAC initialization.
Definition: hal_mac_lld.c:69
void macStart(MACDriver *macp, const MACConfig *config)
Configures and activates the MAC peripheral.
Definition: hal_mac.c:95
HAL subsystem header.
static void osalSysUnlock(void)
Leaves a critical zone from thread context.
Definition: osal.h:540
static void osalEventObjectInit(event_source_t *esp)
Initializes an event source object.
Definition: osal.h:665
event_source_t rdevent
Receive event.
Definition: hal_mac_lld.h:100
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp)
Releases a receive descriptor.
Definition: hal_mac_lld.c:184
int32_t msg_t
Type of a message.
Definition: osal.h:160
macstate_t state
Driver state.
Definition: hal_mac_lld.h:83
msg_t macWaitReceiveDescriptor(MACDriver *macp, MACReceiveDescriptor *rdp, sysinterval_t timeout)
Waits for a received frame.
Definition: hal_mac.c:205
bool mac_lld_poll_link_status(MACDriver *macp)
Updates and returns the link status.
Definition: hal_mac_lld.c:200
Structure representing a MAC driver.
Definition: hal_mac_lld.h:79
void macObjectInit(MACDriver *macp)
Initialize the standard part of a MACDriver structure.
Definition: hal_mac.c:76
#define osalDbgCheck(c)
Function parameters check.
Definition: osal.h:278
msg_t mac_lld_get_receive_descriptor(MACDriver *macp, MACReceiveDescriptor *rdp)
Returns a receive descriptor.
Definition: hal_mac_lld.c:166
Structure representing a transmit descriptor.
Definition: hal_mac_lld.h:108
msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, MACTransmitDescriptor *tdp)
Returns a transmission descriptor.
Definition: hal_mac_lld.c:132
void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp)
Releases a transmit descriptor and starts the transmission of the enqueued data as a single frame...
Definition: hal_mac.c:179
bool macPollLinkStatus(MACDriver *macp)
Updates and returns the link status.
Definition: hal_mac.c:251
uint32_t sysinterval_t
Type of system time interval.
Definition: osal.h:170
const MACConfig * config
Current configuration data.
Definition: hal_mac_lld.h:87
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp)
Releases a transmit descriptor and starts the transmission of the enqueued data as a single frame...
Definition: hal_mac_lld.c:149
msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout)
Enqueues the caller thread.
Definition: osal.c:277
void mac_lld_start(MACDriver *macp)
Configures and activates the MAC peripheral.
Definition: hal_mac_lld.c:84
void mac_lld_stop(MACDriver *macp)
Deactivates the MAC peripheral.
Definition: hal_mac_lld.c:105
threads_queue_t rdqueue
Receive semaphore.
Definition: hal_mac_lld.h:95
static void osalSysLock(void)
Enters a critical zone from thread context.
Definition: osal.h:530
Driver configuration structure.
Definition: hal_mac_lld.h:68
Structure representing a receive descriptor.
Definition: hal_mac_lld.h:123
#define osalDbgAssert(c, remark)
Condition assertion.
Definition: osal.h:258
void macInit(void)
MAC Driver initialization.
Definition: hal_mac.c:64
void macStop(MACDriver *macp)
Deactivates the MAC peripheral.
Definition: hal_mac.c:115
static void osalThreadQueueObjectInit(threads_queue_t *tqp)
Initializes a threads queue object.
Definition: osal.h:653