|
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 uart.c 00023 * @brief UART Driver code. 00024 * 00025 * @addtogroup UART 00026 * @{ 00027 */ 00028 00029 #include "ch.h" 00030 #include "hal.h" 00031 00032 #if HAL_USE_UART || 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 exported functions. */ 00052 /*===========================================================================*/ 00053 00054 /** 00055 * @brief UART Driver initialization. 00056 * @note This function is implicitly invoked by @p halInit(), there is 00057 * no need to explicitly initialize the driver. 00058 * 00059 * @init 00060 */ 00061 void uartInit(void) { 00062 00063 uart_lld_init(); 00064 } 00065 00066 /** 00067 * @brief Initializes the standard part of a @p UARTDriver structure. 00068 * 00069 * @param[out] uartp pointer to the @p UARTDriver object 00070 * 00071 * @init 00072 */ 00073 void uartObjectInit(UARTDriver *uartp) { 00074 00075 uartp->state = UART_STOP; 00076 uartp->txstate = UART_TX_IDLE; 00077 uartp->rxstate = UART_RX_IDLE; 00078 uartp->config = NULL; 00079 /* Optional, user-defined initializer.*/ 00080 #if defined(UART_DRIVER_EXT_INIT_HOOK) 00081 UART_DRIVER_EXT_INIT_HOOK(uartp); 00082 #endif 00083 } 00084 00085 /** 00086 * @brief Configures and activates the UART peripheral. 00087 * 00088 * @param[in] uartp pointer to the @p UARTDriver object 00089 * @param[in] config pointer to the @p UARTConfig object 00090 * 00091 * @api 00092 */ 00093 void uartStart(UARTDriver *uartp, const UARTConfig *config) { 00094 00095 chDbgCheck((uartp != NULL) && (config != NULL), "uartStart"); 00096 00097 chSysLock(); 00098 chDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY), 00099 "uartStart(), #1", "invalid state"); 00100 00101 uartp->config = config; 00102 uart_lld_start(uartp); 00103 uartp->state = UART_READY; 00104 chSysUnlock(); 00105 } 00106 00107 /** 00108 * @brief Deactivates the UART peripheral. 00109 * 00110 * @param[in] uartp pointer to the @p UARTDriver object 00111 * 00112 * @api 00113 */ 00114 void uartStop(UARTDriver *uartp) { 00115 00116 chDbgCheck(uartp != NULL, "uartStop"); 00117 00118 chSysLock(); 00119 chDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY), 00120 "uartStop(), #1", "invalid state"); 00121 00122 uart_lld_stop(uartp); 00123 uartp->state = UART_STOP; 00124 uartp->txstate = UART_TX_IDLE; 00125 uartp->rxstate = UART_RX_IDLE; 00126 chSysUnlock(); 00127 } 00128 00129 /** 00130 * @brief Starts a transmission on the UART peripheral. 00131 * @note The buffers are organized as uint8_t arrays for data sizes below 00132 * or equal to 8 bits else it is organized as uint16_t arrays. 00133 * 00134 * @param[in] uartp pointer to the @p UARTDriver object 00135 * @param[in] n number of data frames to send 00136 * @param[in] txbuf the pointer to the transmit buffer 00137 * 00138 * @api 00139 */ 00140 void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) { 00141 00142 chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL), 00143 "uartStartSend"); 00144 00145 chSysLock(); 00146 chDbgAssert((uartp->state == UART_READY) && (uartp->txstate == UART_TX_IDLE), 00147 "uartStartSend(), #1", "not active"); 00148 00149 uart_lld_start_send(uartp, n, txbuf); 00150 uartp->txstate = UART_TX_ACTIVE; 00151 chSysUnlock(); 00152 } 00153 00154 /** 00155 * @brief Starts a transmission on the UART peripheral. 00156 * @note The buffers are organized as uint8_t arrays for data sizes below 00157 * or equal to 8 bits else it is organized as uint16_t arrays. 00158 * @note This function has to be invoked from a lock zone. 00159 * 00160 * @param[in] uartp pointer to the @p UARTDriver object 00161 * @param[in] n number of data frames to send 00162 * @param[in] txbuf the pointer to the transmit buffer 00163 * 00164 * @iclass 00165 */ 00166 void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) { 00167 00168 chDbgCheckClassI(); 00169 chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL), 00170 "uartStartSendI"); 00171 chDbgAssert((uartp->state == UART_READY) && 00172 (uartp->txstate != UART_TX_ACTIVE), 00173 "uartStartSendI(), #1", "not active"); 00174 00175 uart_lld_start_send(uartp, n, txbuf); 00176 uartp->txstate = UART_TX_ACTIVE; 00177 } 00178 00179 /** 00180 * @brief Stops any ongoing transmission. 00181 * @note Stopping a transmission also suppresses the transmission callbacks. 00182 * 00183 * @param[in] uartp pointer to the @p UARTDriver object 00184 * 00185 * @return The number of data frames not transmitted by the 00186 * stopped transmit operation. 00187 * @retval 0 There was no transmit operation in progress. 00188 * 00189 * @api 00190 */ 00191 size_t uartStopSend(UARTDriver *uartp) { 00192 size_t n; 00193 00194 chDbgCheck(uartp != NULL, "uartStopSend"); 00195 00196 chSysLock(); 00197 chDbgAssert(uartp->state == UART_READY, "uartStopSend(), #1", "not active"); 00198 00199 if (uartp->txstate == UART_TX_ACTIVE) { 00200 n = uart_lld_stop_send(uartp); 00201 uartp->txstate = UART_TX_IDLE; 00202 } 00203 else 00204 n = 0; 00205 chSysUnlock(); 00206 return n; 00207 } 00208 00209 /** 00210 * @brief Stops any ongoing transmission. 00211 * @note Stopping a transmission also suppresses the transmission callbacks. 00212 * @note This function has to be invoked from a lock zone. 00213 * 00214 * @param[in] uartp pointer to the @p UARTDriver object 00215 * 00216 * @return The number of data frames not transmitted by the 00217 * stopped transmit operation. 00218 * @retval 0 There was no transmit operation in progress. 00219 * 00220 * @iclass 00221 */ 00222 size_t uartStopSendI(UARTDriver *uartp) { 00223 00224 chDbgCheckClassI(); 00225 chDbgCheck(uartp != NULL, "uartStopSendI"); 00226 chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active"); 00227 00228 if (uartp->txstate == UART_TX_ACTIVE) { 00229 size_t n = uart_lld_stop_send(uartp); 00230 uartp->txstate = UART_TX_IDLE; 00231 return n; 00232 } 00233 return 0; 00234 } 00235 00236 /** 00237 * @brief Starts a receive operation on the UART peripheral. 00238 * @note The buffers are organized as uint8_t arrays for data sizes below 00239 * or equal to 8 bits else it is organized as uint16_t arrays. 00240 * 00241 * @param[in] uartp pointer to the @p UARTDriver object 00242 * @param[in] n number of data frames to send 00243 * @param[in] rxbuf the pointer to the receive buffer 00244 * 00245 * @api 00246 */ 00247 void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) { 00248 00249 chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL), 00250 "uartStartReceive"); 00251 00252 chSysLock(); 00253 chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE), 00254 "uartStartReceive(), #1", "not active"); 00255 00256 uart_lld_start_receive(uartp, n, rxbuf); 00257 uartp->rxstate = UART_RX_ACTIVE; 00258 chSysUnlock(); 00259 } 00260 00261 /** 00262 * @brief Starts a receive operation on the UART peripheral. 00263 * @note The buffers are organized as uint8_t arrays for data sizes below 00264 * or equal to 8 bits else it is organized as uint16_t arrays. 00265 * @note This function has to be invoked from a lock zone. 00266 * 00267 * @param[in] uartp pointer to the @p UARTDriver object 00268 * @param[in] n number of data frames to send 00269 * @param[out] rxbuf the pointer to the receive buffer 00270 * 00271 * @iclass 00272 */ 00273 void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) { 00274 00275 chDbgCheckClassI(); 00276 chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL), 00277 "uartStartReceiveI"); 00278 chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE), 00279 "uartStartReceiveI(), #1", "not active"); 00280 00281 uart_lld_start_receive(uartp, n, rxbuf); 00282 uartp->rxstate = UART_RX_ACTIVE; 00283 } 00284 00285 /** 00286 * @brief Stops any ongoing receive operation. 00287 * @note Stopping a receive operation also suppresses the receive callbacks. 00288 * 00289 * @param[in] uartp pointer to the @p UARTDriver object 00290 * 00291 * @return The number of data frames not received by the 00292 * stopped receive operation. 00293 * @retval 0 There was no receive operation in progress. 00294 * 00295 * @api 00296 */ 00297 size_t uartStopReceive(UARTDriver *uartp) { 00298 size_t n; 00299 00300 chDbgCheck(uartp != NULL, "uartStopReceive"); 00301 00302 chSysLock(); 00303 chDbgAssert(uartp->state == UART_READY, 00304 "uartStopReceive(), #1", "not active"); 00305 00306 if (uartp->rxstate == UART_RX_ACTIVE) { 00307 n = uart_lld_stop_receive(uartp); 00308 uartp->rxstate = UART_RX_IDLE; 00309 } 00310 else 00311 n = 0; 00312 chSysUnlock(); 00313 return n; 00314 } 00315 00316 /** 00317 * @brief Stops any ongoing receive operation. 00318 * @note Stopping a receive operation also suppresses the receive callbacks. 00319 * @note This function has to be invoked from a lock zone. 00320 * 00321 * @param[in] uartp pointer to the @p UARTDriver object 00322 * 00323 * @return The number of data frames not received by the 00324 * stopped receive operation. 00325 * @retval 0 There was no receive operation in progress. 00326 * 00327 * @iclass 00328 */ 00329 size_t uartStopReceiveI(UARTDriver *uartp) { 00330 00331 chDbgCheckClassI(); 00332 chDbgCheck(uartp != NULL, "uartStopReceiveI"); 00333 chDbgAssert(uartp->state == UART_READY, 00334 "uartStopReceiveI(), #1", "not active"); 00335 00336 if (uartp->rxstate == UART_RX_ACTIVE) { 00337 size_t n = uart_lld_stop_receive(uartp); 00338 uartp->rxstate = UART_RX_IDLE; 00339 return n; 00340 } 00341 return 0; 00342 } 00343 00344 #endif /* HAL_USE_UART */ 00345 00346 /** @} */