Naze32 clone with Frysky receiver
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

serial.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * serial.c
  3. *
  4. * Copyright (c) 2012, 2013, Thomas Buck <xythobuz@me.com>
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * - Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  20. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  21. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  22. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  23. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  25. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  26. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include <avr/io.h>
  31. #include <avr/interrupt.h>
  32. #include <stdint.h>
  33. #include "serial.h"
  34. #include "serial_device.h"
  35. /** \addtogroup uart UART Library
  36. * UART Library enabling you to control all available
  37. * UART Modules. With XON/XOFF Flow Control and buffered
  38. * Receiving and Transmitting.
  39. * @{
  40. */
  41. /** \file serial.c
  42. * UART Library Implementation
  43. */
  44. /** If you define this, a '\\r' (CR) will be put in front of a '\\n' (LF) when sending a byte.
  45. * Binary Communication will then be impossible!
  46. */
  47. // #define SERIALINJECTCR
  48. #ifndef RX_BUFFER_SIZE
  49. #define RX_BUFFER_SIZE 32 /**< RX Buffer Size in Bytes (Power of 2) */
  50. #endif
  51. #ifndef TX_BUFFER_SIZE
  52. #define TX_BUFFER_SIZE 32 /**< TX Buffer Size in Bytes (Power of 2) */
  53. #endif
  54. /** Defining this enables incoming XON XOFF (sends XOFF if rx buff is full) */
  55. #define FLOWCONTROL
  56. #define FLOWMARK 5 /**< Space remaining to trigger xoff/xon */
  57. #define XON 0x11 /**< XON Value */
  58. #define XOFF 0x13 /**< XOFF Value */
  59. #if (RX_BUFFER_SIZE < 2) || (TX_BUFFER_SIZE < 2)
  60. #error SERIAL BUFFER TOO SMALL!
  61. #endif
  62. #ifdef FLOWCONTROL
  63. #if (RX_BUFFER_SIZE < 8) || (TX_BUFFER_SIZE < 8)
  64. #error SERIAL BUFFER TOO SMALL!
  65. #endif
  66. #endif
  67. #if ((RX_BUFFER_SIZE + TX_BUFFER_SIZE) * UART_COUNT) >= (RAMEND - 0x60)
  68. #error SERIAL BUFFER TOO LARGE!
  69. #endif
  70. // serialRegisters
  71. #define SERIALDATA 0
  72. #define SERIALB 1
  73. #define SERIALC 2
  74. #define SERIALA 3
  75. #define SERIALUBRRH 4
  76. #define SERIALUBRRL 5
  77. // serialBits
  78. #define SERIALUCSZ0 0
  79. #define SERIALUCSZ1 1
  80. #define SERIALRXCIE 2
  81. #define SERIALRXEN 3
  82. #define SERIALTXEN 4
  83. #define SERIALUDRIE 5
  84. #define SERIALUDRE 6
  85. uint8_t volatile rxBuffer[UART_COUNT][RX_BUFFER_SIZE];
  86. uint8_t volatile txBuffer[UART_COUNT][TX_BUFFER_SIZE];
  87. uint16_t volatile rxRead[UART_COUNT];
  88. uint16_t volatile rxWrite[UART_COUNT];
  89. uint16_t volatile txRead[UART_COUNT];
  90. uint16_t volatile txWrite[UART_COUNT];
  91. uint8_t volatile shouldStartTransmission[UART_COUNT];
  92. #ifdef FLOWCONTROL
  93. uint8_t volatile sendThisNext[UART_COUNT];
  94. uint8_t volatile flow[UART_COUNT];
  95. uint8_t volatile rxBufferElements[UART_COUNT];
  96. #endif
  97. uint8_t serialAvailable(void) {
  98. return UART_COUNT;
  99. }
  100. void serialInit(uint8_t uart, uint16_t baud) {
  101. if (uart >= UART_COUNT)
  102. return;
  103. // Initialize state variables
  104. rxRead[uart] = 0;
  105. rxWrite[uart] = 0;
  106. txRead[uart] = 0;
  107. txWrite[uart] = 0;
  108. shouldStartTransmission[uart] = 1;
  109. #ifdef FLOWCONTROL
  110. sendThisNext[uart] = 0;
  111. flow[uart] = 1;
  112. rxBufferElements[uart] = 0;
  113. #endif
  114. // Default Configuration: 8N1
  115. *serialRegisters[uart][SERIALC] = (1 << serialBits[uart][SERIALUCSZ0]) | (1 << serialBits[uart][SERIALUCSZ1]);
  116. // Set baudrate
  117. #if SERIALBAUDBIT == 8
  118. *serialRegisters[uart][SERIALUBRRH] = (baud >> 8);
  119. *serialRegisters[uart][SERIALUBRRL] = baud;
  120. #else
  121. *serialBaudRegisters[uart] = baud;
  122. #endif
  123. *serialRegisters[uart][SERIALB] = (1 << serialBits[uart][SERIALRXCIE]); // Enable Interrupts
  124. *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALRXEN]) | (1 << serialBits[uart][SERIALTXEN]); // Enable Receiver/Transmitter
  125. }
  126. void serialClose(uint8_t uart) {
  127. if (uart >= UART_COUNT)
  128. return;
  129. uint8_t sreg = SREG;
  130. sei();
  131. while (!serialTxBufferEmpty(uart));
  132. while (*serialRegisters[uart][SERIALB] & (1 << serialBits[uart][SERIALUDRIE])); // Wait while Transmit Interrupt is on
  133. cli();
  134. *serialRegisters[uart][SERIALB] = 0;
  135. *serialRegisters[uart][SERIALC] = 0;
  136. SREG = sreg;
  137. }
  138. #ifdef FLOWCONTROL
  139. void setFlow(uint8_t uart, uint8_t on) {
  140. if (uart >= UART_COUNT)
  141. return;
  142. if (flow[uart] != on) {
  143. if (on == 1) {
  144. // Send XON
  145. while (sendThisNext[uart] != 0);
  146. sendThisNext[uart] = XON;
  147. flow[uart] = 1;
  148. if (shouldStartTransmission[uart]) {
  149. shouldStartTransmission[uart] = 0;
  150. *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]);
  151. *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
  152. }
  153. } else {
  154. // Send XOFF
  155. sendThisNext[uart] = XOFF;
  156. flow[uart] = 0;
  157. if (shouldStartTransmission[uart]) {
  158. shouldStartTransmission[uart] = 0;
  159. *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]);
  160. *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
  161. }
  162. }
  163. // Wait till it's transmitted
  164. while (*serialRegisters[uart][SERIALB] & (1 << serialBits[uart][SERIALUDRIE]));
  165. }
  166. }
  167. #endif
  168. // ---------------------
  169. // | Reception |
  170. // ---------------------
  171. uint8_t serialHasChar(uint8_t uart) {
  172. if (uart >= UART_COUNT)
  173. return 0;
  174. if (rxRead[uart] != rxWrite[uart]) { // True if char available
  175. return 1;
  176. } else {
  177. return 0;
  178. }
  179. }
  180. uint8_t serialGetBlocking(uint8_t uart) {
  181. if (uart >= UART_COUNT)
  182. return 0;
  183. while(!serialHasChar(uart));
  184. return serialGet(uart);
  185. }
  186. uint8_t serialGet(uint8_t uart) {
  187. if (uart >= UART_COUNT)
  188. return 0;
  189. uint8_t c;
  190. #ifdef FLOWCONTROL
  191. rxBufferElements[uart]--;
  192. if ((flow[uart] == 0) && (rxBufferElements[uart] <= FLOWMARK)) {
  193. while (sendThisNext[uart] != 0);
  194. sendThisNext[uart] = XON;
  195. flow[uart] = 1;
  196. if (shouldStartTransmission[uart]) {
  197. shouldStartTransmission[uart] = 0;
  198. *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]); // Enable Interrupt
  199. *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
  200. }
  201. }
  202. #endif
  203. if (rxRead[uart] != rxWrite[uart]) {
  204. c = rxBuffer[uart][rxRead[uart]];
  205. rxBuffer[uart][rxRead[uart]] = 0;
  206. if (rxRead[uart] < (RX_BUFFER_SIZE - 1)) {
  207. rxRead[uart]++;
  208. } else {
  209. rxRead[uart] = 0;
  210. }
  211. return c;
  212. } else {
  213. return 0;
  214. }
  215. }
  216. uint8_t serialRxBufferFull(uint8_t uart) {
  217. if (uart >= UART_COUNT)
  218. return 0;
  219. return (((rxWrite[uart] + 1) == rxRead[uart]) || ((rxRead[uart] == 0) && ((rxWrite[uart] + 1) == RX_BUFFER_SIZE)));
  220. }
  221. uint8_t serialRxBufferEmpty(uint8_t uart) {
  222. if (uart >= UART_COUNT)
  223. return 0;
  224. if (rxRead[uart] != rxWrite[uart]) {
  225. return 0;
  226. } else {
  227. return 1;
  228. }
  229. }
  230. // ----------------------
  231. // | Transmission |
  232. // ----------------------
  233. void serialWrite(uint8_t uart, uint8_t data) {
  234. if (uart >= UART_COUNT)
  235. return;
  236. #ifdef SERIALINJECTCR
  237. if (data == '\n') {
  238. serialWrite(uart, '\r');
  239. }
  240. #endif
  241. while (serialTxBufferFull(uart));
  242. txBuffer[uart][txWrite[uart]] = data;
  243. if (txWrite[uart] < (TX_BUFFER_SIZE - 1)) {
  244. txWrite[uart]++;
  245. } else {
  246. txWrite[uart] = 0;
  247. }
  248. if (shouldStartTransmission[uart]) {
  249. shouldStartTransmission[uart] = 0;
  250. *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]); // Enable Interrupt
  251. *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
  252. }
  253. }
  254. void serialWriteString(uint8_t uart, const char *data) {
  255. if (uart >= UART_COUNT)
  256. return;
  257. if (data == 0) {
  258. serialWriteString(uart, "NULL");
  259. } else {
  260. while (*data != '\0') {
  261. serialWrite(uart, *data++);
  262. }
  263. }
  264. }
  265. void serialWriteHex(uint8_t uart, uint8_t value) {
  266. char buff[3] = { 0, 0, '\0' };
  267. if (value >= 16) {
  268. buff[0] = value / 16;
  269. value = value % 16;
  270. }
  271. buff[1] = value;
  272. if ((buff[0] >= 0) && (buff[0] <= 9)) {
  273. buff[0] += '0';
  274. } else {
  275. buff[0] -= 10;
  276. buff[0] += 'A';
  277. }
  278. if ((buff[1] >= 0) && (buff[1] <= 9)) {
  279. buff[1] += '0';
  280. } else {
  281. buff[1] -= 10;
  282. buff[1] += 'A';
  283. }
  284. serialWriteString(uart, buff);
  285. }
  286. uint8_t serialTxBufferFull(uint8_t uart) {
  287. if (uart >= UART_COUNT)
  288. return 0;
  289. return (((txWrite[uart] + 1) == txRead[uart]) || ((txRead[uart] == 0) && ((txWrite[uart] + 1) == TX_BUFFER_SIZE)));
  290. }
  291. uint8_t serialTxBufferEmpty(uint8_t uart) {
  292. if (uart >= UART_COUNT)
  293. return 0;
  294. if (txRead[uart] != txWrite[uart]) {
  295. return 0;
  296. } else {
  297. return 1;
  298. }
  299. }
  300. void serialReceiveInterrupt(uint8_t uart) {
  301. rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
  302. if (rxWrite[uart] < (RX_BUFFER_SIZE - 1)) {
  303. rxWrite[uart]++;
  304. } else {
  305. rxWrite[uart] = 0;
  306. }
  307. #ifdef FLOWCONTROL
  308. rxBufferElements[uart]++;
  309. if ((flow[uart] == 1) && (rxBufferElements[uart] >= (RX_BUFFER_SIZE - FLOWMARK))) {
  310. sendThisNext[uart] = XOFF;
  311. flow[uart] = 0;
  312. if (shouldStartTransmission[uart]) {
  313. shouldStartTransmission[uart] = 0;
  314. *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]); // Enable Interrupt
  315. *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
  316. }
  317. }
  318. #endif
  319. }
  320. void serialTransmitInterrupt(uint8_t uart) {
  321. #ifdef FLOWCONTROL
  322. if (sendThisNext[uart]) {
  323. *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
  324. sendThisNext[uart] = 0;
  325. } else {
  326. #endif
  327. if (txRead[uart] != txWrite[uart]) {
  328. *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
  329. if (txRead[uart] < (TX_BUFFER_SIZE -1)) {
  330. txRead[uart]++;
  331. } else {
  332. txRead[uart] = 0;
  333. }
  334. } else {
  335. shouldStartTransmission[uart] = 1;
  336. *serialRegisters[uart][SERIALB] &= ~(1 << serialBits[uart][SERIALUDRIE]); // Disable Interrupt
  337. }
  338. #ifdef FLOWCONTROL
  339. }
  340. #endif
  341. }
  342. ISR(SERIALRECIEVEINTERRUPT) { // Receive complete
  343. serialReceiveInterrupt(0);
  344. }
  345. ISR(SERIALTRANSMITINTERRUPT) { // Data register empty
  346. serialTransmitInterrupt(0);
  347. }
  348. #if UART_COUNT > 1
  349. ISR(SERIALRECIEVEINTERRUPT1) { // Receive complete
  350. serialReceiveInterrupt(1);
  351. }
  352. ISR(SERIALTRANSMITINTERRUPT1) { // Data register empty
  353. serialTransmitInterrupt(1);
  354. }
  355. #endif
  356. #if UART_COUNT > 2
  357. ISR(SERIALRECIEVEINTERRUPT2) { // Receive complete
  358. serialReceiveInterrupt(2);
  359. }
  360. ISR(SERIALTRANSMITINTERRUPT2) { // Data register empty
  361. serialTransmitInterrupt(2);
  362. }
  363. #endif
  364. #if UART_COUNT > 3
  365. ISR(SERIALRECIEVEINTERRUPT3) { // Receive complete
  366. serialReceiveInterrupt(3);
  367. }
  368. ISR(SERIALTRANSMITINTERRUPT3) { // Data register empty
  369. serialTransmitInterrupt(3);
  370. }
  371. #endif
  372. /** @} */