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 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  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 16 /**< RX Buffer Size in Bytes (Power of 2) */
  50. #endif
  51. #ifndef TX_BUFFER_SIZE
  52. #define TX_BUFFER_SIZE 128 /**< 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. void serialWriteUnsigned8(uint8_t uart, uint8_t value) {
  287. char buff[4] = { '0', '0', '0', '\0' };
  288. uint8_t pos = sizeof(buff) - 2;
  289. while (value > 0) {
  290. buff[pos--] = '0' + (value % 10);
  291. value /= 10;
  292. }
  293. uint8_t start = 0;
  294. while ((start < (sizeof(buff) - 2)) && (buff[start] == '0')) {
  295. start++;
  296. }
  297. serialWriteString(uart, buff + start);
  298. }
  299. void serialWriteUnsigned16(uint8_t uart, uint16_t value) {
  300. char buff[6] = { '0', '0', '0', '0', '0', '\0' };
  301. uint8_t pos = sizeof(buff) - 2;
  302. while (value > 0) {
  303. buff[pos--] = '0' + (value % 10);
  304. value /= 10;
  305. }
  306. uint8_t start = 0;
  307. while ((start < (sizeof(buff) - 2)) && (buff[start] == '0')) {
  308. start++;
  309. }
  310. serialWriteString(uart, buff + start);
  311. }
  312. void serialWriteUnsigned32(uint8_t uart, uint32_t value) {
  313. char buff[11] = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '\0' };
  314. uint8_t pos = sizeof(buff) - 2;
  315. while (value > 0) {
  316. buff[pos--] = '0' + (value % 10);
  317. value /= 10;
  318. }
  319. uint8_t start = 0;
  320. while ((start < (sizeof(buff) - 2)) && (buff[start] == '0')) {
  321. start++;
  322. }
  323. serialWriteString(uart, buff + start);
  324. }
  325. void serialWriteUnsigned64(uint8_t uart, uint64_t value) {
  326. char buff[21] = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
  327. '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '\0' };
  328. uint8_t pos = sizeof(buff) - 2;
  329. while (value > 0) {
  330. buff[pos--] = '0' + (value % 10);
  331. value /= 10;
  332. }
  333. uint8_t start = 0;
  334. while ((start < (sizeof(buff) - 2)) && (buff[start] == '0')) {
  335. start++;
  336. }
  337. serialWriteString(uart, buff + start);
  338. }
  339. uint8_t serialTxBufferFull(uint8_t uart) {
  340. if (uart >= UART_COUNT)
  341. return 0;
  342. return (((txWrite[uart] + 1) == txRead[uart]) || ((txRead[uart] == 0) && ((txWrite[uart] + 1) == TX_BUFFER_SIZE)));
  343. }
  344. uint8_t serialTxBufferEmpty(uint8_t uart) {
  345. if (uart >= UART_COUNT)
  346. return 0;
  347. if (txRead[uart] != txWrite[uart]) {
  348. return 0;
  349. } else {
  350. return 1;
  351. }
  352. }
  353. void serialReceiveInterrupt(uint8_t uart) {
  354. rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
  355. if (rxWrite[uart] < (RX_BUFFER_SIZE - 1)) {
  356. rxWrite[uart]++;
  357. } else {
  358. rxWrite[uart] = 0;
  359. }
  360. #ifdef FLOWCONTROL
  361. rxBufferElements[uart]++;
  362. if ((flow[uart] == 1) && (rxBufferElements[uart] >= (RX_BUFFER_SIZE - FLOWMARK))) {
  363. sendThisNext[uart] = XOFF;
  364. flow[uart] = 0;
  365. if (shouldStartTransmission[uart]) {
  366. shouldStartTransmission[uart] = 0;
  367. *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]); // Enable Interrupt
  368. *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
  369. }
  370. }
  371. #endif
  372. }
  373. void serialTransmitInterrupt(uint8_t uart) {
  374. #ifdef FLOWCONTROL
  375. if (sendThisNext[uart]) {
  376. *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
  377. sendThisNext[uart] = 0;
  378. } else {
  379. #endif
  380. if (txRead[uart] != txWrite[uart]) {
  381. *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
  382. if (txRead[uart] < (TX_BUFFER_SIZE -1)) {
  383. txRead[uart]++;
  384. } else {
  385. txRead[uart] = 0;
  386. }
  387. } else {
  388. shouldStartTransmission[uart] = 1;
  389. *serialRegisters[uart][SERIALB] &= ~(1 << serialBits[uart][SERIALUDRIE]); // Disable Interrupt
  390. }
  391. #ifdef FLOWCONTROL
  392. }
  393. #endif
  394. }
  395. ISR(SERIALRECIEVEINTERRUPT) { // Receive complete
  396. serialReceiveInterrupt(0);
  397. }
  398. ISR(SERIALTRANSMITINTERRUPT) { // Data register empty
  399. serialTransmitInterrupt(0);
  400. }
  401. #if UART_COUNT > 1
  402. ISR(SERIALRECIEVEINTERRUPT1) { // Receive complete
  403. serialReceiveInterrupt(1);
  404. }
  405. ISR(SERIALTRANSMITINTERRUPT1) { // Data register empty
  406. serialTransmitInterrupt(1);
  407. }
  408. #endif
  409. #if UART_COUNT > 2
  410. ISR(SERIALRECIEVEINTERRUPT2) { // Receive complete
  411. serialReceiveInterrupt(2);
  412. }
  413. ISR(SERIALTRANSMITINTERRUPT2) { // Data register empty
  414. serialTransmitInterrupt(2);
  415. }
  416. #endif
  417. #if UART_COUNT > 3
  418. ISR(SERIALRECIEVEINTERRUPT3) { // Receive complete
  419. serialReceiveInterrupt(3);
  420. }
  421. ISR(SERIALTRANSMITINTERRUPT3) { // Data register empty
  422. serialTransmitInterrupt(3);
  423. }
  424. #endif
  425. /** @} */