ChibiOS  21.6.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  osalSysLock();
159 
160  while ((msg = mac_lld_get_transmit_descriptor(macp, tdp)) != MSG_OK) {
161  msg = osalThreadEnqueueTimeoutS(&macp->tdqueue, timeout);
162  if (msg == MSG_TIMEOUT) {
163  break;
164  }
165  }
166 
167  osalSysUnlock();
168 
169  return msg;
170 }
171 
172 /**
173  * @brief Releases a transmit descriptor and starts the transmission of the
174  * enqueued data as a single frame.
175  *
176  * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
177  *
178  * @api
179  */
181 
182  osalDbgCheck(tdp != NULL);
183 
185 }
186 
187 /**
188  * @brief Waits for a received frame.
189  * @details Stops until a frame is received and buffered. If a frame is
190  * not immediately available then the invoking thread is queued
191  * until one is received.
192  *
193  * @param[in] macp pointer to the @p MACDriver object
194  * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
195  * @param[in] timeout the number of ticks before the operation timeouts,
196  * the following special values are allowed:
197  * - @a TIME_IMMEDIATE immediate timeout.
198  * - @a TIME_INFINITE no timeout.
199  * .
200  * @return The operation status.
201  * @retval MSG_OK the descriptor was obtained.
202  * @retval MSG_TIMEOUT the operation timed out, descriptor not initialized.
203  *
204  * @api
205  */
208  sysinterval_t timeout) {
209  msg_t msg;
210 
211  osalDbgCheck((macp != NULL) && (rdp != NULL));
212  osalDbgAssert(macp->state == MAC_ACTIVE, "not active");
213 
214  osalSysLock();
215 
216  while (((msg = mac_lld_get_receive_descriptor(macp, rdp)) != MSG_OK)) {
217  msg = osalThreadEnqueueTimeoutS(&macp->rdqueue, timeout);
218  if (msg == MSG_TIMEOUT) {
219  break;
220  }
221  }
222 
223  osalSysUnlock();
224 
225  return msg;
226 }
227 
228 /**
229  * @brief Releases a receive descriptor.
230  * @details The descriptor and its buffer are made available for more incoming
231  * frames.
232  *
233  * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
234  *
235  * @api
236  */
238 
239  osalDbgCheck(rdp != NULL);
240 
242 }
243 
244 /**
245  * @brief Updates and returns the link status.
246  *
247  * @param[in] macp pointer to the @p MACDriver object
248  * @return The link status.
249  * @retval true if the link is active.
250  * @retval false if the link is down.
251  *
252  * @api
253  */
255 
256  osalDbgCheck(macp != NULL);
257  osalDbgAssert(macp->state == MAC_ACTIVE, "not active");
258 
259  return mac_lld_poll_link_status(macp);
260 }
261 
262 #endif /* HAL_USE_MAC == TRUE */
263 
264 /** @} */
macPollLinkStatus
bool macPollLinkStatus(MACDriver *macp)
Updates and returns the link status.
Definition: hal_mac.c:254
mac_lld_init
void mac_lld_init(void)
Low level MAC initialization.
Definition: hal_mac_lld.c:69
mac_lld_release_transmit_descriptor
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
mac_lld_start
void mac_lld_start(MACDriver *macp)
Configures and activates the MAC peripheral.
Definition: hal_mac_lld.c:84
mac_lld_stop
void mac_lld_stop(MACDriver *macp)
Deactivates the MAC peripheral.
Definition: hal_mac_lld.c:105
MACReceiveDescriptor
Structure representing a receive descriptor.
Definition: hal_mac_lld.h:123
MACConfig
Driver configuration structure.
Definition: hal_mac_lld.h:68
hal.h
HAL subsystem header.
macReleaseTransmitDescriptor
void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp)
Releases a transmit descriptor and starts the transmission of the enqueued data as a single frame.
Definition: hal_mac.c:180
osalSysUnlock
static void osalSysUnlock(void)
Leaves a critical zone from thread context.
Definition: osal.h:611
macInit
void macInit(void)
MAC Driver initialization.
Definition: hal_mac.c:64
MACDriver::rdqueue
threads_queue_t rdqueue
Receive semaphore.
Definition: hal_mac_lld.h:95
osalEventObjectInit
static void osalEventObjectInit(event_source_t *esp)
Initializes an event source object.
Definition: osal.h:737
macWaitReceiveDescriptor
msg_t macWaitReceiveDescriptor(MACDriver *macp, MACReceiveDescriptor *rdp, sysinterval_t timeout)
Waits for a received frame.
Definition: hal_mac.c:206
msg_t
int32_t msg_t
Definition: chearly.h:88
mac_lld_release_receive_descriptor
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp)
Releases a receive descriptor.
Definition: hal_mac_lld.c:184
macReleaseReceiveDescriptor
void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp)
Releases a receive descriptor.
Definition: hal_mac.c:237
macWaitTransmitDescriptor
msg_t macWaitTransmitDescriptor(MACDriver *macp, MACTransmitDescriptor *tdp, sysinterval_t timeout)
Allocates a transmission descriptor.
Definition: hal_mac.c:150
macObjectInit
void macObjectInit(MACDriver *macp)
Initialize the standard part of a MACDriver structure.
Definition: hal_mac.c:76
mac_lld_get_receive_descriptor
msg_t mac_lld_get_receive_descriptor(MACDriver *macp, MACReceiveDescriptor *rdp)
Returns a receive descriptor.
Definition: hal_mac_lld.c:166
MACDriver::config
const MACConfig * config
Current configuration data.
Definition: hal_mac_lld.h:87
MACTransmitDescriptor
Structure representing a transmit descriptor.
Definition: hal_mac_lld.h:108
MACDriver::tdqueue
threads_queue_t tdqueue
Transmit semaphore.
Definition: hal_mac_lld.h:91
MACDriver::rdevent
event_source_t rdevent
Receive event.
Definition: hal_mac_lld.h:100
MSG_OK
#define MSG_OK
Normal wakeup message.
Definition: chschd.h:39
osalThreadEnqueueTimeoutS
msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout)
Enqueues the caller thread.
Definition: osal.c:277
osalDbgCheck
#define osalDbgCheck(c)
Function parameters check.
Definition: osal.h:284
macStart
void macStart(MACDriver *macp, const MACConfig *config)
Configures and activates the MAC peripheral.
Definition: hal_mac.c:95
MACDriver::state
macstate_t state
Driver state.
Definition: hal_mac_lld.h:83
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
osalSysLock
static void osalSysLock(void)
Enters a critical zone from thread context.
Definition: osal.h:601
MSG_TIMEOUT
#define MSG_TIMEOUT
Wakeup caused by a timeout condition.
Definition: chschd.h:40
MACDriver
Structure representing a MAC driver.
Definition: hal_mac_lld.h:79
MAC_ACTIVE
@ MAC_ACTIVE
Definition: hal_mac.h:70
osalDbgAssert
#define osalDbgAssert(c, remark)
Condition assertion.
Definition: osal.h:264
MAC_STOP
@ MAC_STOP
Definition: hal_mac.h:69
mac_lld_poll_link_status
bool mac_lld_poll_link_status(MACDriver *macp)
Updates and returns the link status.
Definition: hal_mac_lld.c:200
macStop
void macStop(MACDriver *macp)
Deactivates the MAC peripheral.
Definition: hal_mac.c:115
osalThreadQueueObjectInit
static void osalThreadQueueObjectInit(threads_queue_t *tqp)
Initializes a threads queue object.
Definition: osal.h:725
mac_lld_get_transmit_descriptor
msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, MACTransmitDescriptor *tdp)
Returns a transmission descriptor.
Definition: hal_mac_lld.c:132