|
ChibiOS/RT
2.5.1 |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 00003 2011,2012 Giovanni Di Sirio. 00004 00005 This file is part of ChibiOS/RT. 00006 00007 ChibiOS/RT is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 ChibiOS/RT is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 /** 00022 * @file mac.c 00023 * @brief MAC Driver code. 00024 * 00025 * @addtogroup MAC 00026 * @{ 00027 */ 00028 00029 #include "ch.h" 00030 #include "hal.h" 00031 00032 #if HAL_USE_MAC || defined(__DOXYGEN__) 00033 00034 /*===========================================================================*/ 00035 /* Driver local definitions. */ 00036 /*===========================================================================*/ 00037 00038 /*===========================================================================*/ 00039 /* Driver exported variables. */ 00040 /*===========================================================================*/ 00041 00042 /*===========================================================================*/ 00043 /* Driver local variables. */ 00044 /*===========================================================================*/ 00045 00046 /*===========================================================================*/ 00047 /* Driver local functions. */ 00048 /*===========================================================================*/ 00049 00050 /*===========================================================================*/ 00051 /* Driver interrupt handlers. */ 00052 /*===========================================================================*/ 00053 00054 /*===========================================================================*/ 00055 /* Driver exported functions. */ 00056 /*===========================================================================*/ 00057 00058 /** 00059 * @brief MAC Driver initialization. 00060 * @note This function is implicitly invoked by @p halInit(), there is 00061 * no need to explicitly initialize the driver. 00062 * 00063 * @init 00064 */ 00065 void macInit(void) { 00066 00067 mac_lld_init(); 00068 } 00069 00070 /** 00071 * @brief Initialize the standard part of a @p MACDriver structure. 00072 * 00073 * @param[out] macp pointer to the @p MACDriver object 00074 * 00075 * @init 00076 */ 00077 void macObjectInit(MACDriver *macp) { 00078 00079 macp->state = MAC_STOP; 00080 macp->config = NULL; 00081 chSemInit(&macp->tdsem, 0); 00082 chSemInit(&macp->rdsem, 0); 00083 #if MAC_USE_EVENTS 00084 chEvtInit(&macp->rdevent); 00085 #endif 00086 } 00087 00088 /** 00089 * @brief Configures and activates the MAC peripheral. 00090 * 00091 * @param[in] macp pointer to the @p MACDriver object 00092 * @param[in] config pointer to the @p MACConfig object 00093 * 00094 * @api 00095 */ 00096 void macStart(MACDriver *macp, const MACConfig *config) { 00097 00098 chDbgCheck((macp != NULL) && (config != NULL), "macStart"); 00099 00100 chSysLock(); 00101 chDbgAssert(macp->state == MAC_STOP, 00102 "macStart(), #1", "invalid state"); 00103 macp->config = config; 00104 mac_lld_start(macp); 00105 macp->state = MAC_ACTIVE; 00106 chSysUnlock(); 00107 } 00108 00109 /** 00110 * @brief Deactivates the MAC peripheral. 00111 * 00112 * @param[in] macp pointer to the @p MACDriver object 00113 * 00114 * @api 00115 */ 00116 void macStop(MACDriver *macp) { 00117 00118 chDbgCheck(macp != NULL, "macStop"); 00119 00120 chSysLock(); 00121 chDbgAssert((macp->state == MAC_STOP) || (macp->state == MAC_ACTIVE), 00122 "macStop(), #1", "invalid state"); 00123 mac_lld_stop(macp); 00124 macp->state = MAC_STOP; 00125 chSysUnlock(); 00126 } 00127 00128 /** 00129 * @brief Allocates a transmission descriptor. 00130 * @details One of the available transmission descriptors is locked and 00131 * returned. If a descriptor is not currently available then the 00132 * invoking thread is queued until one is freed. 00133 * 00134 * @param[in] macp pointer to the @p MACDriver object 00135 * @param[out] tdp pointer to a @p MACTransmitDescriptor structure 00136 * @param[in] time the number of ticks before the operation timeouts, 00137 * the following special values are allowed: 00138 * - @a TIME_IMMEDIATE immediate timeout. 00139 * - @a TIME_INFINITE no timeout. 00140 * . 00141 * @return The operation status. 00142 * @retval RDY_OK the descriptor was obtained. 00143 * @retval RDY_TIMEOUT the operation timed out, descriptor not initialized. 00144 * 00145 * @api 00146 */ 00147 msg_t macWaitTransmitDescriptor(MACDriver *macp, 00148 MACTransmitDescriptor *tdp, 00149 systime_t time) { 00150 msg_t msg; 00151 systime_t now; 00152 00153 chDbgCheck((macp != NULL) && (tdp != NULL), "macWaitTransmitDescriptor"); 00154 chDbgAssert(macp->state == MAC_ACTIVE, "macWaitTransmitDescriptor(), #1", 00155 "not active"); 00156 00157 while (((msg = mac_lld_get_transmit_descriptor(macp, tdp)) != RDY_OK) && 00158 (time > 0)) { 00159 chSysLock(); 00160 now = chTimeNow(); 00161 if ((msg = chSemWaitTimeoutS(&macp->tdsem, time)) == RDY_TIMEOUT) { 00162 chSysUnlock(); 00163 break; 00164 } 00165 if (time != TIME_INFINITE) 00166 time -= (chTimeNow() - now); 00167 chSysUnlock(); 00168 } 00169 return msg; 00170 } 00171 00172 /** 00173 * @brief Releases a transmit descriptor and starts the transmission of the 00174 * enqueued data as a single frame. 00175 * 00176 * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure 00177 * 00178 * @api 00179 */ 00180 void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp) { 00181 00182 chDbgCheck((tdp != NULL), "macReleaseTransmitDescriptor"); 00183 00184 mac_lld_release_transmit_descriptor(tdp); 00185 } 00186 00187 /** 00188 * @brief Waits for a received frame. 00189 * @details Stops until a frame is received and buffered. If a frame is 00190 * not immediately available then the invoking thread is queued 00191 * until one is received. 00192 * 00193 * @param[in] macp pointer to the @p MACDriver object 00194 * @param[out] rdp pointer to a @p MACReceiveDescriptor structure 00195 * @param[in] time the number of ticks before the operation timeouts, 00196 * the following special values are allowed: 00197 * - @a TIME_IMMEDIATE immediate timeout. 00198 * - @a TIME_INFINITE no timeout. 00199 * . 00200 * @return The operation status. 00201 * @retval RDY_OK the descriptor was obtained. 00202 * @retval RDY_TIMEOUT the operation timed out, descriptor not initialized. 00203 * 00204 * @api 00205 */ 00206 msg_t macWaitReceiveDescriptor(MACDriver *macp, 00207 MACReceiveDescriptor *rdp, 00208 systime_t time) { 00209 msg_t msg; 00210 systime_t now; 00211 00212 chDbgCheck((macp != NULL) && (rdp != NULL), "macWaitReceiveDescriptor"); 00213 chDbgAssert(macp->state == MAC_ACTIVE, "macWaitReceiveDescriptor(), #1", 00214 "not active"); 00215 00216 while (((msg = mac_lld_get_receive_descriptor(macp, rdp)) != RDY_OK) && 00217 (time > 0)) { 00218 chSysLock(); 00219 now = chTimeNow(); 00220 if ((msg = chSemWaitTimeoutS(&macp->rdsem, time)) == RDY_TIMEOUT) { 00221 chSysUnlock(); 00222 break; 00223 } 00224 if (time != TIME_INFINITE) 00225 time -= (chTimeNow() - now); 00226 chSysUnlock(); 00227 } 00228 return msg; 00229 } 00230 00231 /** 00232 * @brief Releases a receive descriptor. 00233 * @details The descriptor and its buffer are made available for more incoming 00234 * frames. 00235 * 00236 * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure 00237 * 00238 * @api 00239 */ 00240 void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) { 00241 00242 chDbgCheck((rdp != NULL), "macReleaseReceiveDescriptor"); 00243 00244 mac_lld_release_receive_descriptor(rdp); 00245 } 00246 00247 /** 00248 * @brief Updates and returns the link status. 00249 * 00250 * @param[in] macp pointer to the @p MACDriver object 00251 * @return The link status. 00252 * @retval TRUE if the link is active. 00253 * @retval FALSE if the link is down. 00254 * 00255 * @api 00256 */ 00257 bool_t macPollLinkStatus(MACDriver *macp) { 00258 00259 chDbgCheck((macp != NULL), "macPollLinkStatus"); 00260 chDbgAssert(macp->state == MAC_ACTIVE, "macPollLinkStatus(), #1", 00261 "not active"); 00262 00263 return mac_lld_poll_link_status(macp); 00264 } 00265 00266 #endif /* HAL_USE_MAC */ 00267 00268 /** @} */