usartavr.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353
  1. /*
  2. * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. * The 9-bit communication had been contributed by Brett Abbott,
  33. * Digital Telemetry Limited.
  34. *
  35. * Dave Smart contributed the synchronous mode support.
  36. */
  37. /*!
  38. * \file arch/avr/dev/usartavr.c
  39. * \brief AVR USART support.
  40. *
  41. * \verbatim
  42. * $Id: usartavr.c 5472 2013-12-06 00:16:28Z olereinhardt $
  43. * \endverbatim
  44. */
  45. #include <sys/atom.h>
  46. #include <sys/event.h>
  47. #include <sys/timer.h>
  48. #include <dev/irqreg.h>
  49. #include <dev/usartavr.h>
  50. #ifdef NUTTRACER
  51. #include <sys/tracer.h>
  52. #endif
  53. /*!
  54. * \addtogroup xgUsartAvr
  55. */
  56. /*@{*/
  57. /* \brief ASCII code for software flow control, starts transmitter. */
  58. #define ASCII_XON 0x11
  59. /* \brief ASCII code for software flow control, stops transmitter. */
  60. #define ASCII_XOFF 0x13
  61. /* \brief XON transmit pending flag. */
  62. #define XON_PENDING 0x10
  63. /* \brief XOFF transmit pending flag. */
  64. #define XOFF_PENDING 0x20
  65. /* \brief XOFF sent flag. */
  66. #define XOFF_SENT 0x40
  67. /* \brief XOFF received flag. */
  68. #define XOFF_RCVD 0x80
  69. /*!
  70. * \brief Receiver error flags.
  71. */
  72. static ureg_t rx_errors;
  73. /*!
  74. * \brief Enables software flow control if not equal zero.
  75. */
  76. static ureg_t flow_control;
  77. /*!
  78. * \brief Transmit address frame, if not zero.
  79. */
  80. static ureg_t tx_aframe;
  81. #ifdef UART_HDX_BIT
  82. /* define in cfg/modem.h */
  83. #ifdef UART_HDX_FLIP_BIT /* same as RTS toggle by Windows NT driver */
  84. #define UART_HDX_TX cbi
  85. #define UART_HDX_RX sbi
  86. #else /* previous usage by Ethernut */
  87. #define UART_HDX_TX sbi
  88. #define UART_HDX_RX cbi
  89. #endif
  90. #endif
  91. #ifdef UART_HDX_BIT
  92. /*!
  93. * \brief Enables half duplex control if not equal zero.
  94. *
  95. * This variable exists only if the hardware configuration defines a
  96. * port bit to switch between receive and transmit mode.
  97. */
  98. static ureg_t hdx_control;
  99. #endif
  100. #ifdef UART_RTS_BIT
  101. /*!
  102. * \brief Enables RTS control if not equal zero.
  103. *
  104. * This variable exists only if the hardware configuration defines a
  105. * port bit to control the RTS signal.
  106. */
  107. static ureg_t rts_control;
  108. #endif
  109. #ifdef UART_CTS_BIT
  110. /*!
  111. * \brief Enables CTS sense if not equal zero.
  112. *
  113. * This variable exists only if the hardware configuration defines a
  114. * port bit to sense the CTS signal.
  115. */
  116. static ureg_t cts_sense;
  117. #endif
  118. #ifdef UART_CTS_BIT
  119. /*!
  120. * \brief USARTn CTS sense interrupt handler.
  121. *
  122. * This interrupt routine is called when the CTS line level is low.
  123. * Typical line drivers negate the signal, thus driving our port
  124. * low when CTS is active.
  125. *
  126. * This routine exists only if the hardware configuration defines a
  127. * port bit to sense the CTS signal.
  128. */
  129. static void AvrUsartCts(void *arg)
  130. {
  131. /* Enable transmit interrupt. */
  132. sbi(UCSRnB, UDRIE);
  133. /* Disable CTS sense interrupt. */
  134. cbi(EIMSK, UART_CTS_BIT);
  135. }
  136. #endif
  137. #ifdef UART_HDX_BIT
  138. /*
  139. * \brief USARTn transmit complete interrupt handler.
  140. *
  141. * Used with half duplex communication to switch from tranmit to receive
  142. * mode after the last character has been transmitted.
  143. *
  144. * This routine exists only if the hardware configuration defines a
  145. * port bit to switch between receive and transmit mode.
  146. *
  147. * \param arg Pointer to the transmitter ring buffer.
  148. */
  149. static void AvrUsartTxComplete(void *arg)
  150. {
  151. register RINGBUF *rbf = (RINGBUF *) arg;
  152. /*
  153. * Check if half duplex mode has been enabled and if all characters
  154. * had been sent out.
  155. */
  156. if (hdx_control && rbf->rbf_cnt == 0) {
  157. /* Switch to receiver mode. */
  158. UART_HDX_RX(UART_HDX_PORT, UART_HDX_BIT);
  159. }
  160. }
  161. #endif
  162. /*
  163. * \brief USARTn transmit data register empty interrupt handler.
  164. *
  165. * \param arg Pointer to the transmitter ring buffer.
  166. */
  167. #ifdef USE_USART
  168. SIGNAL( SIG_AVRUART_DATA ) {
  169. register RINGBUF *rbf = &dcb_usart.dcb_tx_rbf;
  170. #else
  171. static void AvrUsartTxEmpty(void *arg) {
  172. register RINGBUF *rbf = (RINGBUF *) arg;
  173. #endif
  174. register uint8_t *cp = rbf->rbf_tail;
  175. #ifdef NUTTRACER
  176. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_ENTER,TRACE_INT_UART_TXEMPTY);
  177. #endif
  178. #ifndef UART_NO_SW_FLOWCONTROL
  179. /*
  180. * Process pending software flow controls first.
  181. */
  182. if (flow_control & (XON_PENDING | XOFF_PENDING)) {
  183. if (flow_control & XON_PENDING) {
  184. outb(UDRn, ASCII_XOFF);
  185. flow_control |= XOFF_SENT;
  186. } else {
  187. outb(UDRn, ASCII_XON);
  188. flow_control &= ~XOFF_SENT;
  189. }
  190. flow_control &= ~(XON_PENDING | XOFF_PENDING);
  191. #ifdef NUTTRACER
  192. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_TXEMPTY);
  193. #endif
  194. return;
  195. }
  196. if (flow_control & XOFF_RCVD) {
  197. /*
  198. * If XOFF has been received, we disable the transmit interrupts
  199. * and return without sending anything.
  200. */
  201. cbi(UCSRnB, UDRIE);
  202. #ifdef NUTTRACER
  203. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_TXEMPTY);
  204. #endif
  205. return;
  206. }
  207. #endif /* UART_NO_SW_FLOWCONTROL */
  208. if (rbf->rbf_cnt) {
  209. #ifdef UART_CTS_BIT
  210. /*
  211. * If CTS has been disabled, we disable the transmit interrupts
  212. * and return without sending anything.
  213. */
  214. if (cts_sense && bit_is_set(UART_CTS_PIN, UART_CTS_BIT)) {
  215. cbi(UCSRnB, UDRIE);
  216. sbi(EIMSK, UART_CTS_BIT);
  217. #ifdef NUTTRACER
  218. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_TXEMPTY);
  219. #endif
  220. return;
  221. }
  222. #endif
  223. rbf->rbf_cnt--;
  224. /*
  225. * The data sheet doesn't exactly tell us, if this bit is retained
  226. * or cleared after the character has been sent out. So we do it
  227. * the save way.
  228. */
  229. if (tx_aframe) {
  230. sbi(UCSRnB, TXB8);
  231. } else {
  232. cbi(UCSRnB, TXB8);
  233. }
  234. /*
  235. * Start transmission of the next character.
  236. */
  237. outb(UDRn, *cp);
  238. /*
  239. * Wrap around the buffer pointer if we reached its end.
  240. */
  241. if (++cp == rbf->rbf_last) {
  242. cp = rbf->rbf_start;
  243. }
  244. rbf->rbf_tail = cp;
  245. if (rbf->rbf_cnt == rbf->rbf_lwm) {
  246. NutEventPostFromIrq(&rbf->rbf_que);
  247. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_WRITE);
  248. }
  249. }
  250. /*
  251. * Nothing left to transmit, disable interrupt.
  252. */
  253. else {
  254. cbi(UCSRnB, UDRIE);
  255. rbf->rbf_cnt = 0;
  256. NutEventPostFromIrq(&rbf->rbf_que);
  257. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_WRITE);
  258. }
  259. #ifdef NUTTRACER
  260. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_TXEMPTY);
  261. #endif
  262. }
  263. /*
  264. * \brief USARTn receive complete interrupt handler.
  265. *
  266. *
  267. * \param arg Pointer to the receiver ring buffer.
  268. */
  269. #ifdef USE_USART
  270. SIGNAL( SIG_AVRUART_RECV ){
  271. register RINGBUF *rbf = &dcb_usart.dcb_rx_rbf;
  272. #else
  273. static void AvrUsartRxComplete(void *arg) {
  274. register RINGBUF *rbf = (RINGBUF *) arg;
  275. #endif
  276. register size_t cnt;
  277. register uint8_t ch;
  278. #ifdef NUTTRACER
  279. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_ENTER,TRACE_INT_UART_RXCOMPL);
  280. #endif
  281. #ifdef UART_READMULTIBYTE
  282. register uint8_t postEvent = 0;
  283. do {
  284. #endif
  285. /*
  286. * We read the received character as early as possible to avoid overflows
  287. * caused by interrupt latency. However, reading the error flags must come
  288. * first, because reading the ATmega128 data register clears the status.
  289. */
  290. rx_errors |= inb(UCSRnA);
  291. ch = inb(UDRn);
  292. #ifndef UART_NO_SW_FLOWCONTROL
  293. /*
  294. * Handle software handshake. We have to do this before checking the
  295. * buffer, because flow control must work in write-only mode, where
  296. * there is no receive buffer.
  297. */
  298. if (flow_control) {
  299. /* XOFF character disables transmit interrupts. */
  300. if (ch == ASCII_XOFF) {
  301. cbi(UCSRnB, UDRIE);
  302. flow_control |= XOFF_RCVD;
  303. #ifdef NUTTRACER
  304. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);
  305. #endif
  306. return;
  307. }
  308. /* XON enables transmit interrupts. */
  309. else if (ch == ASCII_XON) {
  310. sbi(UCSRnB, UDRIE);
  311. flow_control &= ~XOFF_RCVD;
  312. #ifdef NUTTRACER
  313. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);
  314. #endif
  315. return;
  316. }
  317. }
  318. #endif
  319. /*
  320. * Check buffer overflow.
  321. */
  322. cnt = rbf->rbf_cnt;
  323. if (cnt >= rbf->rbf_siz) {
  324. rx_errors |= _BV(DOR);
  325. #ifdef NUTTRACER
  326. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);
  327. #endif
  328. return;
  329. }
  330. /* Wake up waiting threads if this is the first byte in the buffer. */
  331. if (cnt++ == 0){
  332. #ifdef UART_READMULTIBYTE
  333. // we do this later, to get the other bytes in time..
  334. postEvent = 1;
  335. #else
  336. NutEventPostFromIrq(&rbf->rbf_que);
  337. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_READ);
  338. #endif
  339. }
  340. #ifndef UART_NO_SW_FLOWCONTROL
  341. /*
  342. * Check the high watermark for software handshake. If the number of
  343. * buffered bytes is above this mark, then send XOFF.
  344. */
  345. else if (flow_control) {
  346. if(cnt >= rbf->rbf_hwm) {
  347. if((flow_control & XOFF_SENT) == 0) {
  348. if (inb(UCSRnA) & _BV(UDRE)) {
  349. outb(UDRn, ASCII_XOFF);
  350. flow_control |= XOFF_SENT;
  351. flow_control &= ~XOFF_PENDING;
  352. } else {
  353. flow_control |= XOFF_PENDING;
  354. }
  355. }
  356. }
  357. }
  358. #endif
  359. #ifdef UART_RTS_BIT
  360. /*
  361. * Check the high watermark for hardware handshake. If the number of
  362. * buffered bytes is above this mark, then disable RTS.
  363. */
  364. else if (rts_control && cnt >= rbf->rbf_hwm) {
  365. sbi(UART_RTS_PORT, UART_RTS_BIT);
  366. }
  367. #endif
  368. /*
  369. * Store the character and increment and the ring buffer pointer.
  370. */
  371. *rbf->rbf_head++ = ch;
  372. if (rbf->rbf_head == rbf->rbf_last) {
  373. rbf->rbf_head = rbf->rbf_start;
  374. }
  375. /* Update the ring buffer counter. */
  376. rbf->rbf_cnt = cnt;
  377. #ifdef UART_READMULTIBYTE
  378. } while ( inb(UCSRnA) & _BV(RXC) ); // byte in buffer?
  379. // Eventually post event to wake thread
  380. if (postEvent) {
  381. NutEventPostFromIrq(&rbf->rbf_que);
  382. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_READ);
  383. }
  384. #endif
  385. #ifdef NUTTRACER
  386. TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);
  387. #endif
  388. }
  389. /*!
  390. * \brief Carefully enable USART hardware functions.
  391. *
  392. * Always enable transmitter and receiver, even on read-only or
  393. * write-only mode. So we can support software flow control.
  394. */
  395. static void AvrUsartEnable(void)
  396. {
  397. NutEnterCritical();
  398. outb(UCSRnB, _BV(RXCIE) | _BV(UDRIE) | _BV(RXEN) | _BV(TXEN));
  399. #ifdef UART_HDX_BIT
  400. if (hdx_control) {
  401. /* Enable transmit complete interrupt. */
  402. sbi(UCSRnB, TXCIE);
  403. }
  404. #endif
  405. NutExitCritical();
  406. }
  407. /*!
  408. * \brief Carefully disable USART hardware functions.
  409. */
  410. static void AvrUsartDisable(void)
  411. {
  412. /*
  413. * Disable USART interrupts.
  414. */
  415. NutEnterCritical();
  416. cbi(UCSRnB, RXCIE);
  417. cbi(UCSRnB, TXCIE);
  418. cbi(UCSRnB, UDRIE);
  419. NutExitCritical();
  420. /*
  421. * Allow incoming or outgoing character to finish.
  422. */
  423. NutDelay(10);
  424. /*
  425. * Disable USART transmit and receive.
  426. */
  427. cbi(UCSRnB, RXEN);
  428. cbi(UCSRnB, TXEN);
  429. }
  430. /*!
  431. * \brief Query the USART hardware for the selected speed.
  432. *
  433. * This function is called by ioctl function of the upper level USART
  434. * driver through the USARTDCB jump table.
  435. *
  436. * \return The currently selected baudrate.
  437. */
  438. static uint32_t AvrUsartGetSpeed(void)
  439. {
  440. uint32_t fct;
  441. uint16_t sv = (uint16_t) inb(UBRRnL);
  442. #ifdef __AVR_ENHANCED__
  443. sv |= ((uint16_t) inb(UBRRnH) << 8);
  444. /* Synchronous mode. */
  445. if (bit_is_set(UCSRnC, UMSEL)) {
  446. fct = 2UL;
  447. }
  448. /* Double rate mode. */
  449. else if (bit_is_set(UCSRnA, U2X)) {
  450. fct = 8UL;
  451. }
  452. /* Normal mode. */
  453. else {
  454. fct = 16UL;
  455. }
  456. #else
  457. fct = 16UL;
  458. #endif
  459. return NutGetCpuClock() / (fct * ((uint32_t) sv + 1UL));
  460. }
  461. /*!
  462. * \brief Set the USART hardware bit rate.
  463. *
  464. * This function is called by ioctl function of the upper level USART
  465. * driver through the USARTDCB jump table.
  466. *
  467. * \param rate Number of bits per second.
  468. *
  469. * \return 0 on success, -1 otherwise.
  470. */
  471. static int AvrUsartSetSpeed(uint32_t rate)
  472. {
  473. uint16_t sv;
  474. AvrUsartDisable();
  475. /*
  476. * Modified Robert Hildebrand's refined calculation.
  477. */
  478. #ifdef __AVR_ENHANCED__
  479. if (bit_is_clear(UCSRnC, UMSEL)) {
  480. if (bit_is_set(UCSRnA, U2X)) {
  481. rate <<= 2;
  482. } else {
  483. rate <<= 3;
  484. }
  485. }
  486. #else
  487. rate <<= 3;
  488. #endif
  489. sv = (uint16_t) ((NutGetCpuClock() / rate + 1UL) / 2UL) - 1;
  490. outb(UBRRnL, (uint8_t) sv);
  491. #ifdef __AVR_ENHANCED__
  492. outb(UBRRnH, (uint8_t) (sv >> 8));
  493. #endif
  494. AvrUsartEnable();
  495. return 0;
  496. }
  497. /*!
  498. * \brief Query the USART hardware for the number of data bits.
  499. *
  500. * This function is called by ioctl function of the upper level USART
  501. * driver through the USARTDCB jump table.
  502. *
  503. * \return The number of data bits set.
  504. */
  505. static uint8_t AvrUsartGetDataBits(void)
  506. {
  507. if (bit_is_set(UCSRnB, UCSZ2)) {
  508. return 9;
  509. }
  510. #ifdef __AVR_ENHANCED__
  511. if (bit_is_set(UCSRnC, UCSZ1)) {
  512. if (bit_is_set(UCSRnC, UCSZ0)) {
  513. return 8;
  514. } else {
  515. return 7;
  516. }
  517. } else if (bit_is_set(UCSRnC, UCSZ0)) {
  518. return 6;
  519. }
  520. return 5;
  521. #else
  522. return 8;
  523. #endif
  524. }
  525. /*!
  526. * \brief Set the USART hardware to the number of data bits.
  527. *
  528. * This function is called by ioctl function of the upper level USART
  529. * driver through the USARTDCB jump table.
  530. *
  531. * \return 0 on success, -1 otherwise.
  532. */
  533. static int AvrUsartSetDataBits(uint8_t bits)
  534. {
  535. AvrUsartDisable();
  536. cbi(UCSRnB, UCSZ2);
  537. #ifdef __AVR_ENHANCED__
  538. cbi(UCSRnC, UCSZ0);
  539. cbi(UCSRnC, UCSZ1);
  540. switch (bits) {
  541. case 6:
  542. sbi(UCSRnC, UCSZ0);
  543. break;
  544. case 9:
  545. sbi(UCSRnB, UCSZ2);
  546. case 8:
  547. sbi(UCSRnC, UCSZ0);
  548. case 7:
  549. sbi(UCSRnC, UCSZ1);
  550. break;
  551. }
  552. #else
  553. if(bits == 9) {
  554. sbi(UCSRnB, UCSZ2);
  555. }
  556. #endif
  557. AvrUsartEnable();
  558. /*
  559. * Verify the result.
  560. */
  561. if (AvrUsartGetDataBits() != bits) {
  562. return -1;
  563. }
  564. return 0;
  565. }
  566. /*!
  567. * \brief Query the USART hardware for the parity mode.
  568. *
  569. * This routine is called by ioctl function of the upper level USART
  570. * driver through the USARTDCB jump table.
  571. *
  572. * \return Parity mode, either 0 (disabled), 1 (odd) or 2 (even).
  573. */
  574. static uint8_t AvrUsartGetParity(void)
  575. {
  576. #ifdef __AVR_ENHANCED__
  577. if (bit_is_set(UCSRnC, UPM1)) {
  578. if (bit_is_set(UCSRnC, UPM0)) {
  579. return 1;
  580. } else {
  581. return 2;
  582. }
  583. }
  584. #endif
  585. return 0;
  586. }
  587. /*!
  588. * \brief Set the USART hardware to the specified parity mode.
  589. *
  590. * This routine is called by ioctl function of the upper level USART
  591. * driver through the USARTDCB jump table.
  592. *
  593. * \param mode 0 (disabled), 1 (odd) or 2 (even)
  594. *
  595. * \return 0 on success, -1 otherwise.
  596. */
  597. static int AvrUsartSetParity(uint8_t mode)
  598. {
  599. #ifdef __AVR_ENHANCED__
  600. AvrUsartDisable();
  601. switch (mode) {
  602. case 0:
  603. cbi(UCSRnC, UPM0);
  604. cbi(UCSRnC, UPM1);
  605. break;
  606. case 1:
  607. sbi(UCSRnC, UPM0);
  608. sbi(UCSRnC, UPM1);
  609. break;
  610. case 2:
  611. cbi(UCSRnC, UPM0);
  612. sbi(UCSRnC, UPM1);
  613. break;
  614. }
  615. AvrUsartEnable();
  616. #endif
  617. /*
  618. * Verify the result.
  619. */
  620. if (AvrUsartGetParity() != mode) {
  621. return -1;
  622. }
  623. return 0;
  624. }
  625. /*!
  626. * \brief Query the USART hardware for the number of stop bits.
  627. *
  628. * This routine is called by ioctl function of the upper level USART
  629. * driver through the USARTDCB jump table.
  630. *
  631. * \return The number of stop bits set, either 1 or 2.
  632. */
  633. static uint8_t AvrUsartGetStopBits(void)
  634. {
  635. #ifdef __AVR_ENHANCED__
  636. if (bit_is_set(UCSRnC, USBS)) {
  637. return 2;
  638. }
  639. #endif
  640. return 1;
  641. }
  642. /*!
  643. * \brief Set the USART hardware to the number of stop bits.
  644. *
  645. * This routine is called by ioctl function of the upper level USART
  646. * driver through the USARTDCB jump table.
  647. *
  648. * \return 0 on success, -1 otherwise.
  649. */
  650. static int AvrUsartSetStopBits(uint8_t bits)
  651. {
  652. #ifdef __AVR_ENHANCED__
  653. AvrUsartDisable();
  654. if (bits == 1) {
  655. cbi(UCSRnC, USBS);
  656. } else if (bits == 2) {
  657. sbi(UCSRnC, USBS);
  658. }
  659. AvrUsartEnable();
  660. #endif
  661. /*
  662. * Verify the result.
  663. */
  664. if (AvrUsartGetStopBits() != bits) {
  665. return -1;
  666. }
  667. return 0;
  668. }
  669. /*!
  670. * \brief Query the USART hardware status.
  671. *
  672. * \return Status flags.
  673. */
  674. static uint32_t AvrUsartGetStatus(void)
  675. {
  676. uint32_t rc = 0;
  677. /*
  678. * Set receiver error flags.
  679. */
  680. if ((rx_errors & _BV(FE)) != 0) {
  681. rc |= UART_FRAMINGERROR;
  682. }
  683. if ((rx_errors & _BV(DOR)) != 0) {
  684. rc |= UART_OVERRUNERROR;
  685. }
  686. #ifdef __AVR_ENHANCED__
  687. if ((rx_errors & _BV(UPE)) != 0) {
  688. rc |= UART_PARITYERROR;
  689. }
  690. #endif
  691. /*
  692. * Determine software handshake status. The flow control status may
  693. * change during interrupt, but this doesn't really hurt us.
  694. */
  695. if (flow_control) {
  696. if (flow_control & XOFF_SENT) {
  697. rc |= UART_RXDISABLED;
  698. }
  699. if (flow_control & XOFF_RCVD) {
  700. rc |= UART_TXDISABLED;
  701. }
  702. }
  703. #ifdef UART_RTS_BIT
  704. /*
  705. * Determine hardware handshake control status.
  706. */
  707. if (bit_is_set(UART_RTS_PORT, UART_RTS_BIT)) {
  708. rc |= UART_RTSDISABLED;
  709. if (rts_control) {
  710. rc |= UART_TXDISABLED;
  711. }
  712. } else {
  713. rc |= UART_RTSENABLED;
  714. }
  715. #endif
  716. #ifdef UART_CTS_BIT
  717. /*
  718. * Determine hardware handshake sense status.
  719. */
  720. if (bit_is_set(UART_CTS_PIN, UART_CTS_BIT)) {
  721. rc |= UART_CTSDISABLED;
  722. if (cts_sense) {
  723. rc |= UART_RXDISABLED;
  724. }
  725. } else {
  726. rc |= UART_CTSENABLED;
  727. }
  728. #endif
  729. #ifdef UART_DTR_BIT
  730. /*
  731. * Determine DTS status.
  732. */
  733. if ( bit_is_set( UART_DTR_PORT, UART_DTR_BIT ) ) {
  734. rc |= UART_DTRENABLED;
  735. } else {
  736. rc |= UART_DTRDISABLED;
  737. }
  738. #endif
  739. /*
  740. * If transmitter and receiver haven't been detected disabled by any
  741. * of the checks above, then they are probably enabled.
  742. */
  743. if ((rc & UART_RXDISABLED) == 0) {
  744. rc |= UART_RXENABLED;
  745. }
  746. if ((rc & UART_TXDISABLED) == 0) {
  747. rc |= UART_TXENABLED;
  748. }
  749. /*
  750. * Process multidrop setting.
  751. */
  752. if (tx_aframe) {
  753. rc |= UART_TXADDRFRAME;
  754. } else {
  755. rc |= UART_TXNORMFRAME;
  756. }
  757. #ifdef __AVR_ENHANCED__
  758. if (bit_is_set(UCSRnA, MPCM)) {
  759. rc |= UART_RXADDRFRAME;
  760. } else {
  761. rc |= UART_RXNORMFRAME;
  762. }
  763. #else
  764. rc |= UART_RXNORMFRAME;
  765. #endif
  766. return rc;
  767. }
  768. /*!
  769. * \brief Set the USART hardware status.
  770. *
  771. * \param flags Status flags.
  772. *
  773. * \return 0 on success, -1 otherwise.
  774. */
  775. static int AvrUsartSetStatus(uint32_t flags)
  776. {
  777. /*
  778. * Process software handshake control.
  779. */
  780. if (flow_control) {
  781. /* Access to the flow control status must be atomic. */
  782. NutEnterCritical();
  783. /*
  784. * Enabling or disabling the receiver means to behave like
  785. * having sent a XON or XOFF character resp.
  786. */
  787. if (flags & UART_RXENABLED) {
  788. flow_control &= ~XOFF_SENT;
  789. } else if (flags & UART_RXDISABLED) {
  790. flow_control |= XOFF_SENT;
  791. }
  792. /*
  793. * Enabling or disabling the transmitter means to behave like
  794. * having received a XON or XOFF character resp.
  795. */
  796. if (flags & UART_TXENABLED) {
  797. flow_control &= ~XOFF_RCVD;
  798. } else if (flags & UART_TXDISABLED) {
  799. flow_control |= XOFF_RCVD;
  800. }
  801. NutExitCritical();
  802. }
  803. #ifdef UART_RTS_BIT
  804. /*
  805. * Process hardware handshake control.
  806. */
  807. if (rts_control) {
  808. if (flags & UART_RXDISABLED) {
  809. sbi(UART_RTS_PORT, UART_RTS_BIT);
  810. }
  811. if (flags & UART_RXENABLED) {
  812. cbi(UART_RTS_PORT, UART_RTS_BIT);
  813. }
  814. }
  815. if (flags & UART_RTSDISABLED) {
  816. sbi(UART_RTS_PORT, UART_RTS_BIT);
  817. }
  818. if (flags & UART_RTSENABLED) {
  819. cbi(UART_RTS_PORT, UART_RTS_BIT);
  820. }
  821. #endif
  822. #ifdef UART_DTR_BIT
  823. if ( flags & UART_DTRDISABLED ) {
  824. sbi(UART_DTR_DDR, UART_DTR_BIT);
  825. sbi(UART_DTR_PORT, UART_DTR_BIT);
  826. }
  827. if ( flags & UART_DTRENABLED ) {
  828. sbi(UART_DTR_DDR, UART_DTR_BIT);
  829. cbi(UART_DTR_PORT, UART_DTR_BIT);
  830. }
  831. #endif
  832. /*
  833. * Process multidrop setting.
  834. */
  835. if (flags & UART_TXADDRFRAME) {
  836. tx_aframe = 1;
  837. }
  838. if (flags & UART_TXNORMFRAME) {
  839. tx_aframe = 0;
  840. }
  841. #ifdef __AVR_ENHANCED__
  842. if (flags & UART_RXADDRFRAME) {
  843. sbi(UCSRnA, MPCM);
  844. }
  845. if (flags & UART_RXNORMFRAME) {
  846. cbi(UCSRnA, MPCM);
  847. }
  848. #endif
  849. /*
  850. * Clear UART receive errors.
  851. */
  852. if (flags & UART_FRAMINGERROR) {
  853. rx_errors &= ~_BV(FE);
  854. }
  855. if (flags & UART_OVERRUNERROR) {
  856. rx_errors &= ~_BV(DOR);
  857. }
  858. #ifdef __AVR_ENHANCED__
  859. if (flags & UART_PARITYERROR) {
  860. rx_errors &= ~_BV(UPE);
  861. }
  862. #endif
  863. /*
  864. * Verify the result.
  865. */
  866. if ((AvrUsartGetStatus() & ~UART_ERRORS) != flags) {
  867. return -1;
  868. }
  869. return 0;
  870. }
  871. /*!
  872. * \brief Query the USART hardware for synchronous mode.
  873. *
  874. * This function is called by ioctl function of the upper level USART
  875. * driver through the USARTDCB jump table.
  876. *
  877. * \return Or-ed combination of \ref UART_SYNC, \ref UART_MASTER,
  878. * \ref UART_NCLOCK and \ref UART_HIGHSPEED.
  879. */
  880. static uint8_t AvrUsartGetClockMode(void)
  881. {
  882. uint8_t rc = 0;
  883. #ifdef __AVR_ENHANCED__
  884. if (bit_is_set(UCSRnC, UMSEL)) {
  885. rc |= UART_SYNC;
  886. if (bit_is_set(DDRE, 2)) {
  887. rc |= UART_MASTER;
  888. }
  889. if (bit_is_set(UCSRnC, UCPOL)) {
  890. rc |= UART_NCLOCK;
  891. }
  892. } else if (bit_is_set(UCSRnA, U2X)) {
  893. rc |= UART_HIGHSPEED;
  894. }
  895. #endif
  896. return rc;
  897. }
  898. /*!
  899. * \brief Set asynchronous or synchronous mode.
  900. *
  901. * This function is called by ioctl function of the upper level USART
  902. * driver through the USARTDCB jump table.
  903. *
  904. * \param mode Must be an or-ed combination of USART_SYNC, USART_MASTER,
  905. * USART_NCLOCK and USART_HIGHSPEED.
  906. *
  907. * \return 0 on success, -1 otherwise.
  908. */
  909. static int AvrUsartSetClockMode(uint8_t mode)
  910. {
  911. #ifdef __AVR_ENHANCED__
  912. AvrUsartDisable();
  913. /*
  914. * Handle synchronous mode.
  915. */
  916. if (mode & UART_SYNC) {
  917. if (mode & UART_MASTER) {
  918. /* Enable master mode. */
  919. sbi(DDRE, 2);
  920. } else {
  921. /* Disable master mode. */
  922. cbi(DDRE, 2);
  923. }
  924. if (mode & UART_NCLOCK) {
  925. /* Enable negated clock. */
  926. sbi(UCSRnC, UCPOL);
  927. } else {
  928. /* Disable negated clock. */
  929. cbi(UCSRnC, UCPOL);
  930. }
  931. /* Disable high speed. */
  932. cbi(UCSRnA, U2X);
  933. /* Enable synchronous mode. */
  934. sbi(UCSRnC, UMSEL);
  935. }
  936. /*
  937. * Handle asynchronous mode.
  938. */
  939. else {
  940. if (mode & UART_HIGHSPEED) {
  941. /* Enable high speed. */
  942. sbi(UCSRnA, U2X);
  943. } else {
  944. /* Disable high speed. */
  945. cbi(UCSRnA, U2X);
  946. }
  947. /* Disable negated clock. */
  948. cbi(UCSRnC, UCPOL);
  949. /* Disable synchronous mode. */
  950. cbi(UCSRnC, UMSEL);
  951. }
  952. AvrUsartEnable();
  953. #endif
  954. /*
  955. * Verify the result.
  956. */
  957. if (AvrUsartGetClockMode() != mode) {
  958. return -1;
  959. }
  960. return 0;
  961. }
  962. /*!
  963. * \brief Query flow control mode.
  964. *
  965. * This routine is called by ioctl function of the upper level USART
  966. * driver through the USARTDCB jump table.
  967. *
  968. * \return See UsartIOCtl().
  969. */
  970. static uint32_t AvrUsartGetFlowControl(void)
  971. {
  972. uint32_t rc = 0;
  973. if (flow_control) {
  974. rc |= USART_MF_XONXOFF;
  975. } else {
  976. rc &= ~USART_MF_XONXOFF;
  977. }
  978. #ifdef UART_RTS_BIT
  979. if (rts_control) {
  980. rc |= USART_MF_RTSCONTROL;
  981. } else {
  982. rc &= ~USART_MF_RTSCONTROL;
  983. }
  984. #endif
  985. #ifdef UART_CTS_BIT
  986. if (cts_sense) {
  987. rc |= USART_MF_CTSSENSE;
  988. } else {
  989. rc &= ~USART_MF_CTSSENSE;
  990. }
  991. #endif
  992. #ifdef UART_HDX_BIT
  993. if (hdx_control) {
  994. rc |= USART_MF_HALFDUPLEX;
  995. } else {
  996. rc &= ~USART_MF_HALFDUPLEX;
  997. }
  998. #endif
  999. return rc;
  1000. }
  1001. /*!
  1002. * \brief Set flow control mode.
  1003. *
  1004. * This function is called by ioctl function of the upper level USART
  1005. * driver through the USARTDCB jump table.
  1006. *
  1007. * \param flags See UsartIOCtl().
  1008. *
  1009. * \return 0 on success, -1 otherwise.
  1010. */
  1011. static int AvrUsartSetFlowControl(uint32_t flags)
  1012. {
  1013. /*
  1014. * Set software handshake mode.
  1015. */
  1016. if (flags & USART_MF_XONXOFF) {
  1017. if(flow_control == 0) {
  1018. NutEnterCritical();
  1019. flow_control = 1 | XOFF_SENT; /* force XON to be sent on next read */
  1020. NutExitCritical();
  1021. }
  1022. } else {
  1023. NutEnterCritical();
  1024. flow_control = 0;
  1025. NutExitCritical();
  1026. }
  1027. #ifdef UART_RTS_BIT
  1028. /*
  1029. * Set RTS control mode.
  1030. */
  1031. if (flags & USART_MF_RTSCONTROL) {
  1032. sbi(UART_RTS_PORT, UART_RTS_BIT);
  1033. sbi(UART_RTS_DDR, UART_RTS_BIT);
  1034. rts_control = 1;
  1035. } else if (rts_control) {
  1036. rts_control = 0;
  1037. cbi(UART_RTS_DDR, UART_RTS_BIT);
  1038. }
  1039. #endif
  1040. #ifdef UART_CTS_BIT
  1041. /*
  1042. * Set CTS sense mode.
  1043. */
  1044. if (flags & USART_MF_CTSSENSE) {
  1045. /* Register CTS sense interrupt. */
  1046. if (NutRegisterIrqHandler(&UART_CTS_SIGNAL, AvrUsartCts, 0)) {
  1047. return -1;
  1048. }
  1049. sbi(UART_CTS_PORT, UART_CTS_BIT);
  1050. cbi(UART_CTS_DDR, UART_CTS_BIT);
  1051. cts_sense = 1;
  1052. } else if (cts_sense) {
  1053. cts_sense = 0;
  1054. /* Deregister CTS sense interrupt. */
  1055. NutRegisterIrqHandler(&UART_CTS_SIGNAL, 0, 0);
  1056. cbi(UART_CTS_DDR, UART_CTS_BIT);
  1057. }
  1058. #endif
  1059. #ifdef UART_HDX_BIT
  1060. /*
  1061. * Set half duplex mode.
  1062. */
  1063. if (flags & USART_MF_HALFDUPLEX) {
  1064. /* Register transmit complete interrupt. */
  1065. if (NutRegisterIrqHandler(&sig_UART_TRANS, AvrUsartTxComplete, &dcb_usart.dcb_tx_rbf)) {
  1066. return -1;
  1067. }
  1068. /* Initially enable the receiver. */
  1069. UART_HDX_RX(UART_HDX_PORT, UART_HDX_BIT);
  1070. sbi(UART_HDX_DDR, UART_HDX_BIT);
  1071. hdx_control = 1;
  1072. /* Enable transmit complete interrupt. */
  1073. sbi(UCSRnB, TXCIE);
  1074. } else if (hdx_control) {
  1075. hdx_control = 0;
  1076. /* disable transmit complete interrupt */
  1077. cbi(UCSRnB, TXCIE);
  1078. /* Deregister transmit complete interrupt. */
  1079. NutRegisterIrqHandler(&sig_UART_TRANS, 0, 0);
  1080. cbi(UART_HDX_DDR, UART_HDX_BIT);
  1081. }
  1082. #endif
  1083. /*
  1084. * Verify the result.
  1085. */
  1086. if (AvrUsartGetFlowControl() != flags) {
  1087. return -1;
  1088. }
  1089. return 0;
  1090. }
  1091. /*!
  1092. * \brief Start the USART transmitter hardware.
  1093. *
  1094. * The upper level USART driver will call this function through the
  1095. * USARTDCB jump table each time it added one or more bytes to the
  1096. * transmit buffer.
  1097. */
  1098. static void AvrUsartTxStart(void)
  1099. {
  1100. #ifdef UART_HDX_BIT
  1101. if (hdx_control) {
  1102. /* Enable half duplex transmitter. */
  1103. UART_HDX_TX(UART_HDX_PORT, UART_HDX_BIT);
  1104. }
  1105. #endif
  1106. /* Enable transmit interrupts. */
  1107. sbi(UCSRnB, UDRIE);
  1108. }
  1109. /*!
  1110. * \brief Start the USART receiver hardware.
  1111. *
  1112. * The upper level USART driver will call this function through the
  1113. * USARTDCB jump table each time it removed enough bytes from the
  1114. * receive buffer. Enough means, that the number of bytes left in
  1115. * the buffer is below the low watermark.
  1116. */
  1117. static void AvrUsartRxStart(void)
  1118. {
  1119. /*
  1120. * Do any required software flow control.
  1121. */
  1122. if (flow_control && (flow_control & XOFF_SENT) != 0) {
  1123. NutEnterCritical();
  1124. if (inb(UCSRnA) & _BV(UDRE)) {
  1125. outb(UDRn, ASCII_XON);
  1126. flow_control &= ~XON_PENDING;
  1127. } else {
  1128. flow_control |= XON_PENDING;
  1129. }
  1130. flow_control &= ~(XOFF_SENT | XOFF_PENDING);
  1131. NutExitCritical();
  1132. }
  1133. #ifdef UART_RTS_BIT
  1134. if (rts_control) {
  1135. /* Enable RTS. */
  1136. cbi(UART_RTS_PORT, UART_RTS_BIT);
  1137. }
  1138. #endif
  1139. }
  1140. /*
  1141. * \brief Initialize the USART hardware driver.
  1142. *
  1143. * This function is called during device registration by the upper level
  1144. * USART driver through the USARTDCB jump table.
  1145. *
  1146. * \return 0 on success, -1 otherwise.
  1147. */
  1148. static int AvrUsartInit(void)
  1149. {
  1150. #ifndef USE_USART
  1151. /*
  1152. * Register receive and transmit interrupts.
  1153. */
  1154. if (NutRegisterIrqHandler(&sig_UART_RECV, AvrUsartRxComplete, &dcb_usart.dcb_rx_rbf))
  1155. return -1;
  1156. if (NutRegisterIrqHandler(&sig_UART_DATA, AvrUsartTxEmpty, &dcb_usart.dcb_tx_rbf)) {
  1157. NutRegisterIrqHandler(&sig_UART_RECV, 0, 0);
  1158. return -1;
  1159. }
  1160. #endif
  1161. #ifdef UART_RTS_BIT
  1162. sbi(UART_RTS_DDR, UART_RTS_BIT);
  1163. #endif
  1164. #ifdef UART_DTR_BIT
  1165. sbi(UART_DTR_DDR, UART_DTR_BIT);
  1166. #endif
  1167. return 0;
  1168. }
  1169. /*
  1170. * \brief Deinitialize the USART hardware driver.
  1171. *
  1172. * This function is called during device deregistration by the upper
  1173. * level USART driver through the USARTDCB jump table.
  1174. *
  1175. * \return 0 on success, -1 otherwise.
  1176. */
  1177. static int AvrUsartDeinit(void)
  1178. {
  1179. #ifndef USE_USART
  1180. /* Deregister receive and transmit interrupts. */
  1181. NutRegisterIrqHandler(&sig_UART_RECV, 0, 0);
  1182. NutRegisterIrqHandler(&sig_UART_DATA, 0, 0);
  1183. #endif
  1184. /*
  1185. * Disabling flow control shouldn't be required here, because it's up
  1186. * to the upper level to do this on the last close or during
  1187. * deregistration.
  1188. */
  1189. #ifdef UART_HDX_BIT
  1190. /* Deregister transmit complete interrupt. */
  1191. if (hdx_control) {
  1192. hdx_control = 0;
  1193. NutRegisterIrqHandler(&sig_UART_TRANS, 0, 0);
  1194. }
  1195. #endif
  1196. #ifdef UART_CTS_BIT
  1197. if (cts_sense) {
  1198. cts_sense = 0;
  1199. cbi(UART_CTS_DDR, UART_CTS_BIT);
  1200. /* Deregister CTS sense interrupt. */
  1201. NutRegisterIrqHandler(&UART_CTS_SIGNAL, 0, 0);
  1202. }
  1203. #endif
  1204. #ifdef UART_RTS_BIT
  1205. if (rts_control) {
  1206. rts_control = 0;
  1207. cbi(UART_RTS_DDR, UART_RTS_BIT);
  1208. }
  1209. #endif
  1210. #ifdef UART_DTR_BIT
  1211. cbi(UART_DTR_DDR, UART_DTR_BIT);
  1212. #endif
  1213. return 0;
  1214. }
  1215. /*@}*/