usartat91.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485
  1. /*
  2. * Copyright 2001-2006 by egnite Software GmbH
  3. * Copyright 2009 by egnite GmbH
  4. *
  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. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. Neither the name of the copyright holders nor the names of
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  30. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * For additional information see http://www.ethernut.de/
  34. */
  35. /*
  36. * $Id: usartat91.c 5472 2013-12-06 00:16:28Z olereinhardt $
  37. *
  38. * Revision 1.01 2009/09/20 ulrichprinz
  39. * Added support for using DBGU as limited standard USART.
  40. */
  41. #include <cfg/clock.h>
  42. #ifdef UART_USES_NPL
  43. #include <dev/npl.h>
  44. #endif
  45. #include <sys/atom.h>
  46. #include <sys/event.h>
  47. #include <sys/timer.h>
  48. #include <dev/irqreg.h>
  49. #include <dev/usartat91.h>
  50. /*
  51. ** Initial USART settings.
  52. */
  53. #ifndef UART_INIT_BAUDRATE
  54. #define UART_INIT_BAUDRATE 115200
  55. #endif
  56. /*
  57. ** Add empty placeholders for undefined pin configurations.
  58. */
  59. #ifndef UART_RXTX_PINS_ENABLE
  60. #define UART_RXTX_PINS_ENABLE()
  61. #endif
  62. #ifndef UART_HDX_PIN_ENABLE
  63. #define UART_HDX_PIN_ENABLE()
  64. #endif
  65. #ifndef UART_HDX_RX
  66. #define UART_HDX_RX()
  67. #endif
  68. #ifndef UART_HDX_TX
  69. #define UART_HDX_TX()
  70. #endif
  71. #ifndef UART_RTS_PIN_ENABLE
  72. #define UART_RTS_PIN_ENABLE()
  73. #endif
  74. #ifndef UART_RTS_ON
  75. #define UART_RTS_ON()
  76. #endif
  77. #ifndef UART_RTS_OFF
  78. #define UART_RTS_OFF()
  79. #endif
  80. #ifndef UART_CTS_PIN_ENABLE
  81. #define UART_CTS_PIN_ENABLE()
  82. #endif
  83. #ifndef UART_CTS_IS_ON
  84. #define UART_CTS_IS_ON() (1)
  85. #endif
  86. #ifndef UART_MODEM_PINS_ENABLE
  87. #define UART_MODEM_PINS_ENABLE()
  88. #endif
  89. /*
  90. ** GPIO controlled half duplex pin.
  91. */
  92. #if defined(UART_HDX_BIT) && defined(UART_HDX_PIO_ID)
  93. #undef UART_HDX_RX
  94. #undef UART_HDX_TX
  95. #undef UART_HDX_PIN_ENABLE
  96. #undef GPIO_ID
  97. #define GPIO_ID UART_HDX_PIO_ID
  98. #include <cfg/arch/porttran.h>
  99. static INLINE void UART_HDX_PIN_ENABLE(void) {
  100. GPIO_ENABLE(UART_HDX_BIT);
  101. GPIO_OUTPUT(UART_HDX_BIT);
  102. }
  103. #ifdef UART_HDX_FLIP_BIT
  104. static INLINE void UART_HDX_RX(void) { GPIO_SET_HI(UART_HDX_BIT); }
  105. static INLINE void UART_HDX_TX(void) { GPIO_SET_LO(UART_HDX_BIT); }
  106. #else
  107. static INLINE void UART_HDX_RX(void) { GPIO_SET_LO(UART_HDX_BIT); }
  108. static INLINE void UART_HDX_TX(void) { GPIO_SET_HI(UART_HDX_BIT); }
  109. #endif
  110. #elif defined(UART_USES_NPL)
  111. #undef UART_HDX_RX
  112. #undef UART_HDX_TX
  113. #if US_ID == US1_ID
  114. #define UART_HDX_RX() if (inr(NPL_RSCR) & NPL_RSUS1P) sbi(NPL_RSCR, NPL_RSRTS_BIT)
  115. #define UART_HDX_TX() if (inr(NPL_RSCR) & NPL_RSUS1P) cbi(NPL_RSCR, NPL_RSRTS_BIT)
  116. #else
  117. #define UART_HDX_RX() if ((inr(NPL_RSCR) & NPL_RSUS1P) == 0) sbi(NPL_RSCR, NPL_RSRTS_BIT)
  118. #define UART_HDX_TX() if ((inr(NPL_RSCR) & NPL_RSUS1P) == 0) cbi(NPL_RSCR, NPL_RSRTS_BIT)
  119. #endif
  120. #endif /* UART_HDX_BIT */
  121. /*
  122. ** GPIO controlled RTS pin.
  123. */
  124. #if defined(UART_RTS_BIT) && defined(UART_RTS_PIO_ID)
  125. #undef UART_RTS_ON
  126. #undef UART_RTS_OFF
  127. #undef UART_RTS_PIN_ENABLE
  128. #undef GPIO_ID
  129. #define GPIO_ID UART_RTS_PIO_ID
  130. #include <cfg/arch/porttran.h>
  131. static INLINE void UART_RTS_PIN_ENABLE(void) { \
  132. GPIO_ENABLE(UART_RTS_BIT); \
  133. GPIO_OUTPUT(UART_RTS_BIT); \
  134. }
  135. #ifdef UART_RTS_FLIP_BIT
  136. static INLINE void UART_RTS_ON(void) { GPIO_SET_HI(UART_RTS_BIT); }
  137. static INLINE void UART_RTS_OFF(void) { GPIO_SET_LO(UART_RTS_BIT); }
  138. #else
  139. static INLINE void UART_RTS_ON(void) { GPIO_SET_LO(UART_RTS_BIT); }
  140. static INLINE void UART_RTS_OFF(void) { GPIO_SET_HI(UART_RTS_BIT); }
  141. #endif
  142. #elif defined(UART_USES_NPL)
  143. #undef UART_RTS_ON
  144. #undef UART_RTS_OFF
  145. #if US_ID == US1_ID
  146. #define UART_RTS_ON() if (inr(NPL_RSCR) & NPL_RSUS1P) sbi(NPL_RSCR, NPL_RSRTS_BIT)
  147. #define UART_RTS_OFF() if (inr(NPL_RSCR) & NPL_RSUS1P) cbi(NPL_RSCR, NPL_RSRTS_BIT)
  148. #else
  149. #define UART_RTS_ON() if ((inr(NPL_RSCR) & NPL_RSUS1P) == 0) sbi(NPL_RSCR, NPL_RSRTS_BIT)
  150. #define UART_RTS_OFF() if ((inr(NPL_RSCR) & NPL_RSUS1P) == 0) cbi(NPL_RSCR, NPL_RSRTS_BIT)
  151. #endif
  152. #endif
  153. /*
  154. ** GPIO monitored CTS pin.
  155. */
  156. #if defined(UART_CTS_BIT) && defined(UART_CTS_PIO_ID)
  157. #undef UART_CTS_IS_ON
  158. #undef UART_CTS_PIN_ENABLE
  159. #undef GPIO_ID
  160. #define GPIO_ID UART_CTS_PIO_ID
  161. #include <cfg/arch/porttran.h>
  162. #ifdef UART_CTS_FLIP_BIT
  163. static INLINE int UART_CTS_IS_ON(void) { return GPIO_GET(UART_CTS_BIT); }
  164. #else
  165. static INLINE int UART_CTS_IS_ON(void) { return !GPIO_GET(UART_CTS_BIT); }
  166. #endif
  167. static INLINE void UART_CTS_PIN_ENABLE(void) { \
  168. GPIO_ENABLE(UART_CTS_BIT); \
  169. GPIO_INPUT(UART_CTS_BIT); \
  170. GPIO_PULLUP_ON(UART_CTS_BIT); \
  171. }
  172. #elif defined(UART_USES_NPL)
  173. #undef UART_CTS_IS_ON
  174. static INLINE int UART_CTS_IS_ON(void) {
  175. outw(NPL_SCR, NPL_RSCTS);
  176. return bit_is_set(NPL_SLR, NPL_RSCTS_BIT);
  177. }
  178. #endif
  179. /*
  180. ** Determine if we use built-in hardware handshake.
  181. */
  182. #if !defined(USE_BUILT_IN_HARDWARE_HANDSHAKE)
  183. #if defined(UART_HARDWARE_HANDSHAKE) && \
  184. defined(US_MODE_HWHANDSHAKE) && \
  185. !defined(UART_RTS_BIT) && \
  186. !defined(UART_CTS_BIT) && \
  187. !defined(UART_USES_NPL)
  188. #define USE_BUILT_IN_HARDWARE_HANDSHAKE 1
  189. #else
  190. #define USE_BUILT_IN_HARDWARE_HANDSHAKE 0
  191. #endif
  192. #endif
  193. /*
  194. ** Determine if we use built-in half duplex mode.
  195. */
  196. #if !defined(USE_BUILT_IN_HALF_DUPLEX)
  197. #if defined(UART_HARDWARE_HANDSHAKE) && !defined(UART_HDX_BIT) && !defined(UART_USES_NPL)
  198. #define USE_BUILT_IN_HALF_DUPLEX 1
  199. #else
  200. #define USE_BUILT_IN_HALF_DUPLEX 0
  201. #endif
  202. #endif
  203. /* Some function renaming for IRQ handling on uarts
  204. * that do not have a separate IRQ instance but a
  205. * merged one with others like DBU on SYS-IRQ or
  206. * external uarts on GPIO-IRQs
  207. */
  208. #if (US_ID==SYSC_ID)
  209. #define NutUartIrqRegister NutRegisterSysIrqHandler
  210. #define NutUartIrqEnable NutSysIrqEnable
  211. #define NutUartIrqDisable NutSysIrqDisable
  212. #else
  213. #define NutUartIrqRegister NutRegisterIrqHandler
  214. #define NutUartIrqEnable NutIrqEnable
  215. #define NutUartIrqDisable NutIrqDisable
  216. #endif
  217. /*!
  218. * \addtogroup xgNutArchArmAt91Us
  219. */
  220. /*@{*/
  221. /* \brief ASCII code for software flow control, starts transmitter. */
  222. #define ASCII_XON 0x11
  223. /* \brief ASCII code for software flow control, stops transmitter. */
  224. #define ASCII_XOFF 0x13
  225. /* \brief XON transmit pending flag. */
  226. #define XON_PENDING 0x10
  227. /* \brief XOFF transmit pending flag. */
  228. #define XOFF_PENDING 0x20
  229. /* \brief XOFF sent flag. */
  230. #define XOFF_SENT 0x40
  231. /* \brief XOFF received flag. */
  232. #define XOFF_RCVD 0x80
  233. /*!
  234. * \brief Receiver error flags.
  235. */
  236. static unsigned int rx_errors;
  237. /*!
  238. * \brief Enables software flow control if not equal zero.
  239. */
  240. static uint_fast8_t flow_control;
  241. /*!
  242. * \brief Transmit address frame, if not zero.
  243. */
  244. static uint_fast8_t tx_aframe;
  245. /*!
  246. * \brief Half duplex control flag.
  247. *
  248. * Set to 1 if half duplex is enabled. Contains zero otherwise.
  249. */
  250. static uint_fast8_t hdx_control;
  251. /*!
  252. * \brief Enables RTS control if not equal zero.
  253. *
  254. * This variable exists only if the hardware configuration defines a
  255. * port bit to control the RTS signal.
  256. */
  257. static uint_fast8_t rts_control;
  258. /*!
  259. * \brief Enables CTS sense if not equal zero.
  260. *
  261. * This variable exists only if the hardware configuration defines a
  262. * port bit to sense the CTS signal.
  263. */
  264. static uint_fast8_t cts_sense;
  265. #if defined(UART_CTS_BIT) || defined(UART_USES_NPL)
  266. /*!
  267. * \brief USARTn CTS sense interrupt handler.
  268. *
  269. * This interrupt routine is called when the CTS line level is low.
  270. * Typical line drivers negate the signal, thus driving our port
  271. * low when CTS is active.
  272. *
  273. * This routine exists only if the hardware configuration defines a
  274. * port bit to sense the CTS signal.
  275. */
  276. static void At91UsartCts(void *arg)
  277. {
  278. /* Disable CTS sense interrupt. */
  279. #if defined(UART_USES_NPL)
  280. NplIrqDisable(&sig_RSCTS);
  281. /* Enable transmit interrupt. */
  282. outr(USARTn_BASE + US_IER_OFF, US_TXRDY);
  283. #else
  284. if (UART_CTS_IS_ON()) {
  285. GpioIrqDisable(&UART_CTS_SIGNAL, UART_CTS_BIT);
  286. /* Enable transmit interrupt. */
  287. outr(USARTn_BASE + US_IER_OFF, US_TXRDY);
  288. }
  289. #endif
  290. }
  291. #endif
  292. #if USE_BUILT_IN_HALF_DUPLEX == 0
  293. /*
  294. * \brief USARTn transmitter empty interrupt handler.
  295. *
  296. * Used with half duplex communication to switch from tranmit to receive
  297. * mode after the last character has been transmitted.
  298. *
  299. * \param arg Pointer to the transmitter ring buffer.
  300. */
  301. static void At91UsartTxEmpty(RINGBUF *rbf)
  302. {
  303. /*
  304. * Check if half duplex mode has been enabled and if all characters
  305. * had been sent out.
  306. */
  307. if (hdx_control && (rbf->rbf_cnt == 0)) {
  308. /*
  309. * Switch to receiver mode:
  310. * Enable USART receive, disable transmit.
  311. * Disable TX-Empty IRQ
  312. */
  313. outr(USARTn_BASE + US_CR_OFF, US_RXEN | US_TXDIS);
  314. #if defined(UART_HDX_BIT) || defined(UART_USES_NPL)
  315. UART_HDX_RX();
  316. #endif
  317. }
  318. }
  319. #endif
  320. /*
  321. * \brief USARTn transmitter ready interrupt handler.
  322. *
  323. * \param rbf Pointer to the transmitter ring buffer.
  324. */
  325. static void At91UsartTxReady(RINGBUF *rbf)
  326. {
  327. register uint8_t *cp = rbf->rbf_tail;
  328. /*
  329. * Process pending software flow controls first.
  330. */
  331. if (flow_control & (XON_PENDING | XOFF_PENDING)) {
  332. if (flow_control & XON_PENDING) {
  333. outr(USARTn_BASE + US_THR_OFF, ASCII_XOFF);
  334. flow_control |= XOFF_SENT;
  335. } else {
  336. outr(USARTn_BASE + US_THR_OFF, ASCII_XON);
  337. flow_control &= ~XOFF_SENT;
  338. }
  339. flow_control &= ~(XON_PENDING | XOFF_PENDING);
  340. return;
  341. }
  342. if (flow_control & XOFF_RCVD) {
  343. /*
  344. * If XOFF has been received, we disable the transmit interrupts
  345. * and return without sending anything.
  346. */
  347. outr(USARTn_BASE + US_IDR_OFF, US_TXRDY);
  348. return;
  349. }
  350. /*
  351. * Check if we have more bytes to transmit.
  352. */
  353. if (rbf->rbf_cnt) {
  354. #if defined(UART_CTS_BIT) || defined(UART_USES_NPL)
  355. /*
  356. * If CTS has been disabled, we disable the transmit interrupts,
  357. * enable CTS interrupts and return without sending anything.
  358. */
  359. if (cts_sense && !UART_CTS_IS_ON()) {
  360. outr(USARTn_BASE + US_IDR_OFF, US_TXRDY);
  361. #if defined(UART_CTS_BIT)
  362. GpioIrqEnable(&UART_CTS_SIGNAL, UART_CTS_BIT);
  363. #else
  364. NplIrqEnable(&sig_RSCTS);
  365. #endif
  366. return;
  367. }
  368. #endif
  369. /*
  370. * Send address in multidrop mode.
  371. */
  372. if (tx_aframe) {
  373. outr(USARTn_BASE + US_CR_OFF, US_SENDA);
  374. }
  375. /* Start transmission of the next character. */
  376. outr(USARTn_BASE + US_THR_OFF, *cp);
  377. /* Decrement the number of available bytes in the buffer. */
  378. rbf->rbf_cnt--;
  379. /* Wrap around the buffer pointer if we reached its end. */
  380. if (++cp == rbf->rbf_last) {
  381. cp = rbf->rbf_start;
  382. }
  383. rbf->rbf_tail = cp;
  384. #if USE_BUILT_IN_HALF_DUPLEX == 0
  385. /*
  386. * If software half duplex enabled, we need TX-Empty IRQ for
  387. * detection if last bit of last byte transmission is finished.
  388. */
  389. if( hdx_control && rbf->rbf_cnt == 0) {
  390. outr(USARTn_BASE + US_IER_OFF, US_TXEMPTY);
  391. }
  392. #endif
  393. /* Send an event if we reached the low watermark. */
  394. if (rbf->rbf_cnt == rbf->rbf_lwm) {
  395. NutEventPostFromIrq(&rbf->rbf_que);
  396. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_WRITE);
  397. }
  398. }
  399. /*
  400. * Nothing left to transmit, disable interrupt.
  401. */
  402. else {
  403. /* Disable transmit interrupts. */
  404. outr(USARTn_BASE + US_IDR_OFF, US_TXRDY);
  405. /* Send an event to inform the upper level. */
  406. NutEventPostFromIrq(&rbf->rbf_que);
  407. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_WRITE);
  408. }
  409. }
  410. /*
  411. * \brief USARTn receiver ready interrupt handler.
  412. *
  413. *
  414. * \param rbf Pointer to the receiver ring buffer.
  415. */
  416. static void At91UsartRxReady(RINGBUF *rbf)
  417. {
  418. register size_t cnt;
  419. register uint8_t ch;
  420. /*
  421. * We read the received character as early as possible to avoid overflows
  422. * caused by interrupt latency.
  423. */
  424. ch = inb(USARTn_BASE + US_RHR_OFF);
  425. /* Collect receiver errors. */
  426. rx_errors |= inr(USARTn_BASE + US_CSR_OFF) & (US_OVRE | US_FRAME | US_PARE);
  427. /*
  428. * Handle software handshake. We have to do this before checking the
  429. * buffer, because flow control must work in write-only mode, where
  430. * there is no receive buffer.
  431. */
  432. if (flow_control) {
  433. /* XOFF character disables transmit interrupts. */
  434. if (ch == ASCII_XOFF) {
  435. outr(USARTn_BASE + US_IDR_OFF, US_TXRDY);
  436. flow_control |= XOFF_RCVD;
  437. return;
  438. }
  439. /* XON enables transmit interrupts. */
  440. else if (ch == ASCII_XON) {
  441. outr(USARTn_BASE + US_IER_OFF, US_TXRDY);
  442. flow_control &= ~XOFF_RCVD;
  443. return;
  444. }
  445. }
  446. /*
  447. * Check buffer overflow.
  448. */
  449. cnt = rbf->rbf_cnt;
  450. if (cnt >= rbf->rbf_siz) {
  451. rx_errors |= US_OVRE;
  452. return;
  453. }
  454. /* Wake up waiting threads if this is the first byte in the buffer. */
  455. if (cnt++ == 0){
  456. NutEventPostFromIrq(&rbf->rbf_que);
  457. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_READ);
  458. }
  459. /*
  460. * Check the high watermark for software handshake. If the number of
  461. * buffered bytes is equal or above this mark, then send XOFF.
  462. */
  463. else if (flow_control) {
  464. if(cnt >= rbf->rbf_hwm) {
  465. if((flow_control & XOFF_SENT) == 0) {
  466. if (inr(USARTn_BASE + US_CSR_OFF) & US_TXRDY) {
  467. outb(USARTn_BASE + US_THR_OFF, ASCII_XOFF);
  468. flow_control |= XOFF_SENT;
  469. flow_control &= ~XOFF_PENDING;
  470. } else {
  471. flow_control |= XOFF_PENDING;
  472. }
  473. }
  474. }
  475. }
  476. #if defined(UART_RTS_BIT) || defined(UART_USES_NPL)
  477. /*
  478. * Check the high watermark for GPIO hardware handshake. If the
  479. * number of buffered bytes is equal or above this mark, then
  480. * disable RTS.
  481. */
  482. else if (rts_control && cnt >= rbf->rbf_hwm) {
  483. UART_RTS_OFF();
  484. }
  485. #endif
  486. /*
  487. * Store the character and increment and the ring buffer pointer.
  488. */
  489. *rbf->rbf_head++ = ch;
  490. if (rbf->rbf_head == rbf->rbf_last) {
  491. rbf->rbf_head = rbf->rbf_start;
  492. }
  493. /* Update the ring buffer counter. */
  494. rbf->rbf_cnt = cnt;
  495. }
  496. /*!
  497. * \brief USART interrupt handler.
  498. *
  499. * \param arg Pointer to the device specific control block.
  500. */
  501. static void At91UsartInterrupt(void *arg)
  502. {
  503. USARTDCB *dcb = (USARTDCB *)arg;
  504. unsigned int csr = inr(USARTn_BASE + US_CSR_OFF);
  505. if (csr & US_RXRDY) {
  506. At91UsartRxReady(&dcb->dcb_rx_rbf);
  507. }
  508. if (csr & US_TXRDY) {
  509. At91UsartTxReady(&dcb->dcb_tx_rbf);
  510. }
  511. #if USE_BUILT_IN_HALF_DUPLEX == 0
  512. if (csr & US_TXEMPTY) {
  513. At91UsartTxEmpty(&dcb->dcb_tx_rbf);
  514. }
  515. #endif
  516. }
  517. /*!
  518. * \brief Carefully enable USART hardware functions.
  519. *
  520. * Always enabale transmitter and receiver, even on read-only or
  521. * write-only mode. So we can support software flow control.
  522. */
  523. static void At91UsartEnable(void)
  524. {
  525. /* Enable UART receiver and transmitter. */
  526. outr(USARTn_BASE + US_CR_OFF, US_RXEN | US_TXEN);
  527. /* Globally enable UART interrupts. */
  528. NutUartIrqEnable(&SIG_UART);
  529. }
  530. /*!
  531. * \brief Carefully disable USART hardware functions.
  532. *
  533. * This routine is called before changing cruical settings like
  534. * baudrate, frame format etc.
  535. *
  536. * The previous version uses a 10ms delay to make sure, that any
  537. * incoming or outgoing character is processed. However, this time
  538. * depends on the baudrate.
  539. *
  540. * In fact we do not need to take care of incoming characters,
  541. * when changing such settings.
  542. *
  543. * For outgoing characters however, settings may be changed on
  544. * the fly and we should wait, until the last character transmitted
  545. * with the old settings has left the shift register. While TXRDY
  546. * is set when the holding register is empty, TXEMPTY is set when the
  547. * shift register is empty. The bad news is, that both are zero, if
  548. * the transmitter is disabled. We are not able to determine this
  549. * state. So we check TXRDY first and, if set, wait for any character
  550. * currently in the shift register.
  551. */
  552. static void At91UsartDisable(void)
  553. {
  554. /* Globally disable UART interrupts. */
  555. NutUartIrqDisable(&SIG_UART);
  556. /* Wait until all bits had been shifted out. */
  557. if (inr(USARTn_BASE + US_CSR_OFF) & US_TXRDY) {
  558. while((inr(USARTn_BASE + US_CSR_OFF) & US_TXEMPTY) == 0);
  559. }
  560. /* Disable USART transmit and receive. */
  561. outr(USARTn_BASE + US_CR_OFF, US_RXDIS | US_TXDIS);
  562. }
  563. /*!
  564. * \brief Query the USART hardware for the selected speed.
  565. *
  566. * This function is called by ioctl function of the upper level USART
  567. * driver through the USARTDCB jump table.
  568. *
  569. * \return The currently selected baudrate.
  570. */
  571. static uint32_t At91UsartGetSpeed(void)
  572. {
  573. unsigned int cs;
  574. uint32_t clk;
  575. clk = NutClockGet(NUT_HWCLK_PERIPHERAL);
  576. cs = inr(USARTn_BASE + US_MR_OFF) & US_CLKS;
  577. if (cs == US_CLKS_MCK8) {
  578. clk /= 8;
  579. }
  580. else if (cs != US_CLKS_MCK) {
  581. clk = 0;
  582. }
  583. return clk / (16UL * (inr(USARTn_BASE + US_BRGR_OFF) & 0xFFFF));
  584. }
  585. /*!
  586. * \brief Set the USART hardware bit rate.
  587. *
  588. * This function is called by ioctl function of the upper level USART
  589. * driver through the USARTDCB jump table.
  590. *
  591. * \param rate Number of bits per second.
  592. *
  593. * \return 0 on success, -1 otherwise.
  594. */
  595. static int At91UsartSetSpeed(uint32_t rate)
  596. {
  597. At91UsartDisable();
  598. #if !(USARTn_BASE == DBGU_BASE)
  599. outr(USARTn_BASE + US_BRGR_OFF, (NutClockGet(NUT_HWCLK_PERIPHERAL) / (8 * (rate)) + 1) / 2);
  600. #else
  601. #if defined(AT91_PLL_MAINCK)
  602. outr(DBGU_BRGR, (At91GetMasterClock() / (8 * rate) + 1) / 2);
  603. #else
  604. outr(DBGU_BRGR, (NutGetCpuClock() / (8 * rate) + 1) / 2);
  605. #endif
  606. #endif
  607. At91UsartEnable();
  608. return 0;
  609. }
  610. /*!
  611. * \brief Query the USART hardware for the number of data bits.
  612. *
  613. * This function is called by ioctl function of the upper level USART
  614. * driver through the USARTDCB jump table.
  615. *
  616. * \return The number of data bits set.
  617. */
  618. static uint8_t At91UsartGetDataBits(void)
  619. {
  620. #if !(USARTn_BASE == DBGU_BASE)
  621. unsigned int val = inr(USARTn_BASE + US_MR_OFF);
  622. if ((val & US_PAR) == US_PAR_MULTIDROP) {
  623. val = 9;
  624. }
  625. else {
  626. val &= US_CHRL;
  627. if (val == US_CHRL_5) {
  628. val = 5;
  629. }
  630. else if (val == US_CHRL_6) {
  631. val = 6;
  632. }
  633. else if (val == US_CHRL_7) {
  634. val = 7;
  635. }
  636. else {
  637. val = 8;
  638. }
  639. }
  640. return (uint8_t)val;
  641. #else
  642. /* Not supported by DBGU, always 8 bits */
  643. return 8;
  644. #endif
  645. }
  646. /*!
  647. * \brief Set the USART hardware to the number of data bits.
  648. *
  649. * This function is called by ioctl function of the upper level USART
  650. * driver through the USARTDCB jump table.
  651. *
  652. * \return 0 on success, -1 otherwise.
  653. */
  654. static int At91UsartSetDataBits(uint8_t bits)
  655. {
  656. #if !(USARTn_BASE == DBGU_BASE)
  657. unsigned int val = inr(USARTn_BASE + US_MR_OFF);
  658. if (bits == 9) {
  659. val &= ~US_PAR;
  660. val |= US_PAR_MULTIDROP;
  661. }
  662. else {
  663. val &= ~US_CHRL;
  664. if (bits == 5) {
  665. val |= US_CHRL_5;
  666. }
  667. else if (bits == 6) {
  668. val |= US_CHRL_6;
  669. }
  670. else if (bits == 7) {
  671. val |= US_CHRL_7;
  672. }
  673. else if (bits == 8) {
  674. val |= US_CHRL_8;
  675. }
  676. }
  677. At91UsartDisable();
  678. outr(USARTn_BASE + US_MR_OFF, val);
  679. At91UsartEnable();
  680. /*
  681. * Verify the result.
  682. */
  683. if (At91UsartGetDataBits() != bits) {
  684. return -1;
  685. }
  686. return 0;
  687. #else
  688. /* Not supported by DBGU, always 8 bits */
  689. return -1;
  690. #endif
  691. }
  692. /*!
  693. * \brief Query the USART hardware for the parity mode.
  694. *
  695. * This routine is called by ioctl function of the upper level USART
  696. * driver through the USARTDCB jump table.
  697. *
  698. * \return Parity mode, either 0 (disabled), 1 (odd), 2 (even) or 9 (multidrop).
  699. */
  700. static uint8_t At91UsartGetParity(void)
  701. {
  702. unsigned int val = inr(USARTn_BASE + US_MR_OFF) & US_PAR;
  703. if ((val & US_PAR) == US_PAR_MULTIDROP) {
  704. val = 9;
  705. }
  706. else {
  707. if (val == US_PAR_ODD) {
  708. val = 1;
  709. }
  710. else if (val == US_PAR_EVEN) {
  711. val = 2;
  712. }
  713. else {
  714. val = 0;
  715. }
  716. }
  717. return (uint8_t)val;
  718. }
  719. /*!
  720. * \brief Set the USART hardware to the specified parity mode.
  721. *
  722. * This routine is called by ioctl function of the upper level USART
  723. * driver through the USARTDCB jump table.
  724. *
  725. * \param mode 0 (disabled), 1 (odd) or 2 (even)
  726. *
  727. * \return 0 on success, -1 otherwise.
  728. */
  729. static int At91UsartSetParity(uint8_t mode)
  730. {
  731. unsigned int val = inr(USARTn_BASE + US_MR_OFF) & ~US_PAR;
  732. switch (mode) {
  733. case 0:
  734. val |= US_PAR_NO;
  735. break;
  736. case 1:
  737. val |= US_PAR_ODD;
  738. break;
  739. case 2:
  740. val |= US_PAR_EVEN;
  741. break;
  742. }
  743. At91UsartDisable();
  744. outr(USARTn_BASE + US_MR_OFF, val);
  745. At91UsartEnable();
  746. /*
  747. * Verify the result.
  748. */
  749. if (At91UsartGetParity() != mode) {
  750. return -1;
  751. }
  752. return 0;
  753. }
  754. /*!
  755. * \brief Query the USART hardware for the number of stop bits.
  756. *
  757. * This routine is called by ioctl function of the upper level USART
  758. * driver through the USARTDCB jump table.
  759. *
  760. * \return The number of stop bits set, either 1, 2 or 3 (1.5 bits).
  761. */
  762. static uint8_t At91UsartGetStopBits(void)
  763. {
  764. #if !(USARTn_BASE == DBGU_BASE)
  765. unsigned int val = inr(USARTn_BASE + US_MR_OFF) & US_NBSTOP;
  766. if (val == US_NBSTOP_1) {
  767. val = 1;
  768. }
  769. else if (val == US_NBSTOP_2) {
  770. val = 2;
  771. }
  772. else {
  773. val = 3;
  774. }
  775. return (uint8_t)val;
  776. #else
  777. /* Not supported by DBGU, always 1 */
  778. return 1;
  779. #endif
  780. }
  781. /*!
  782. * \brief Set the USART hardware to the number of stop bits.
  783. *
  784. * This routine is called by ioctl function of the upper level USART
  785. * driver through the USARTDCB jump table.
  786. *
  787. * \return 0 on success, -1 otherwise.
  788. */
  789. static int At91UsartSetStopBits(uint8_t bits)
  790. {
  791. #if !(USARTn_BASE == DBGU_BASE)
  792. unsigned int val = inr(USARTn_BASE + US_MR_OFF) & ~US_NBSTOP;
  793. switch(bits) {
  794. case 1:
  795. val |= US_NBSTOP_1;
  796. break;
  797. case 2:
  798. val |= US_NBSTOP_2;
  799. break;
  800. case 3:
  801. val |= US_NBSTOP_1_5;
  802. break;
  803. }
  804. At91UsartDisable();
  805. outr(USARTn_BASE + US_MR_OFF, val);
  806. At91UsartEnable();
  807. /*
  808. * Verify the result.
  809. */
  810. if (At91UsartGetStopBits() != bits) {
  811. return -1;
  812. }
  813. #endif
  814. return 0;
  815. }
  816. /*!
  817. * \brief Query the USART hardware status.
  818. *
  819. * \return Status flags.
  820. */
  821. static uint32_t At91UsartGetStatus(void)
  822. {
  823. uint32_t rc = 0;
  824. #if USE_BUILT_IN_HARDWARE_HANDSHAKE
  825. uint32_t csr = inr(USARTn_BASE + US_CSR_OFF);
  826. #endif
  827. /*
  828. * Set receiver error flags.
  829. */
  830. if ((rx_errors & US_FRAME) != 0) {
  831. rc |= UART_FRAMINGERROR;
  832. }
  833. if ((rx_errors & US_OVRE) != 0) {
  834. rc |= UART_OVERRUNERROR;
  835. }
  836. if ((rx_errors & US_PARE) != 0) {
  837. rc |= UART_PARITYERROR;
  838. }
  839. /*
  840. * Determine software handshake status. The flow control status may
  841. * change during interrupt, but this doesn't really hurt us.
  842. */
  843. if (flow_control) {
  844. if (flow_control & XOFF_SENT) {
  845. rc |= UART_RXDISABLED;
  846. }
  847. if (flow_control & XOFF_RCVD) {
  848. rc |= UART_TXDISABLED;
  849. }
  850. }
  851. /*
  852. * Determine hardware handshake control status.
  853. */
  854. #if USE_BUILT_IN_HARDWARE_HANDSHAKE
  855. /* How to find out? */
  856. #elif defined(UART_RTS_BIT)
  857. /* No definition of the status register? */
  858. #elif defined(UART_USES_NPL)
  859. if (bit_is_set(NPL_RSCR, NPL_RSRTS_BIT)) {
  860. rc |= UART_RTSDISABLED;
  861. if (rts_control) {
  862. rc |= UART_RXDISABLED;
  863. }
  864. } else {
  865. rc |= UART_RTSENABLED;
  866. }
  867. #endif
  868. /*
  869. * Determine hardware handshake sense status.
  870. */
  871. #if USE_BUILT_IN_HARDWARE_HANDSHAKE
  872. if (csr & US_CTS) {
  873. rc |= UART_CTSDISABLED;
  874. if (cts_sense) {
  875. rc |= UART_RXDISABLED;
  876. }
  877. } else {
  878. rc |= UART_CTSENABLED;
  879. }
  880. #else
  881. if (UART_CTS_IS_ON()) {
  882. rc |= UART_CTSENABLED;
  883. } else {
  884. rc |= UART_CTSDISABLED;
  885. if (cts_sense) {
  886. rc |= UART_RXDISABLED;
  887. }
  888. }
  889. #endif
  890. /*
  891. * Determine hardware modem sense status.
  892. */
  893. #if 0
  894. /* I'm confused. Awful flag mismatch? Why do we have uart.h and usart.h? */
  895. if (csr & US_RI) {
  896. rc |= UART_RIDISABLED;
  897. } else {
  898. rc |= UART_RIENABLED;
  899. }
  900. if (csr & US_DSR) {
  901. rc |= UART_DSRDISABLED;
  902. } else {
  903. rc |= UART_DSRENABLED;
  904. }
  905. if (csr & US_DCD) {
  906. rc |= UART_DCDDISABLED;
  907. } else {
  908. rc |= UART_DCDENABLED;
  909. }
  910. #endif
  911. /*
  912. * If transmitter and receiver haven't been detected disabled by any
  913. * of the checks above, then they are probably enabled.
  914. */
  915. if ((rc & UART_RXDISABLED) == 0) {
  916. rc |= UART_RXENABLED;
  917. }
  918. if ((rc & UART_TXDISABLED) == 0) {
  919. rc |= UART_TXENABLED;
  920. }
  921. /*
  922. * Process multidrop setting.
  923. */
  924. if (tx_aframe) {
  925. rc |= UART_TXADDRFRAME;
  926. } else {
  927. rc |= UART_TXNORMFRAME;
  928. }
  929. return rc;
  930. }
  931. /*!
  932. * \brief Set the USART hardware status.
  933. *
  934. * \param flags Status flags.
  935. *
  936. * \return 0 on success, -1 otherwise.
  937. */
  938. static int At91UsartSetStatus(uint32_t flags)
  939. {
  940. /*
  941. * Process software handshake control.
  942. */
  943. if (flow_control) {
  944. /* Access to the flow control status must be atomic. */
  945. NutUartIrqDisable(&SIG_UART);
  946. /*
  947. * Enabling or disabling the receiver means to behave like
  948. * having sent a XON or XOFF character resp.
  949. */
  950. if (flags & UART_RXENABLED) {
  951. flow_control &= ~XOFF_SENT;
  952. } else if (flags & UART_RXDISABLED) {
  953. flow_control |= XOFF_SENT;
  954. }
  955. /*
  956. * Enabling or disabling the transmitter means to behave like
  957. * having received a XON or XOFF character resp.
  958. */
  959. if (flags & UART_TXENABLED) {
  960. flow_control &= ~XOFF_RCVD;
  961. } else if (flags & UART_TXDISABLED) {
  962. flow_control |= XOFF_RCVD;
  963. }
  964. NutUartIrqEnable(&SIG_UART);
  965. }
  966. /*
  967. * Process hardware handshake control.
  968. */
  969. #if USE_BUILT_IN_HARDWARE_HANDSHAKE
  970. /* Built-in hardware. */
  971. if (rts_control) {
  972. if (flags & UART_RXDISABLED) {
  973. outr(USARTn_BASE + US_CR_OFF, US_RTSDIS);
  974. }
  975. if (flags & UART_RXENABLED) {
  976. outr(USARTn_BASE + US_CR_OFF, US_RTSEN);
  977. }
  978. }
  979. if (flags & UART_RTSDISABLED) {
  980. outr(USARTn_BASE + US_CR_OFF, US_RTSDIS);
  981. }
  982. if (flags & UART_RTSENABLED) {
  983. outr(USARTn_BASE + US_CR_OFF, US_RTSEN);
  984. }
  985. #else
  986. /* Manually controlled via GPIO. */
  987. if (rts_control) {
  988. if (flags & UART_RXDISABLED) {
  989. UART_RTS_OFF();
  990. }
  991. if (flags & UART_RXENABLED) {
  992. UART_RTS_ON();
  993. }
  994. }
  995. if (flags & UART_RTSDISABLED) {
  996. UART_RTS_OFF();
  997. }
  998. if (flags & UART_RTSENABLED) {
  999. UART_RTS_ON();
  1000. }
  1001. #endif
  1002. /*
  1003. * Process hardware modem control.
  1004. */
  1005. #if USE_BUILT_IN_MODEM_CONTROL
  1006. /* Built-in hardware. */
  1007. if (flags & UART_DTRDISABLED) {
  1008. outr(USARTn_BASE + US_CR_OFF, US_DTRDIS);
  1009. }
  1010. if (flags & UART_DTRENABLED) {
  1011. outr(USARTn_BASE + US_CR_OFF, US_DTREN);
  1012. }
  1013. #endif
  1014. /*
  1015. * Process multidrop setting.
  1016. */
  1017. if (flags & UART_TXADDRFRAME) {
  1018. tx_aframe = 1;
  1019. }
  1020. if (flags & UART_TXNORMFRAME) {
  1021. tx_aframe = 0;
  1022. }
  1023. /*
  1024. * Clear UART receive errors.
  1025. */
  1026. if (flags & UART_ERRORS) {
  1027. outr(USARTn_BASE + US_CR_OFF, US_RSTSTA);
  1028. }
  1029. /*
  1030. * Verify the result.
  1031. */
  1032. if ((At91UsartGetStatus() & ~UART_ERRORS) != flags) {
  1033. return -1;
  1034. }
  1035. return 0;
  1036. }
  1037. /*!
  1038. * \brief Query the USART hardware for synchronous mode.
  1039. *
  1040. * This function is called by ioctl function of the upper level USART
  1041. * driver through the USARTDCB jump table.
  1042. *
  1043. * Not implemented for the AT91 USART. Always returns 0.
  1044. *
  1045. * \return Or-ed combination of \ref UART_SYNC, \ref UART_MASTER,
  1046. * \ref UART_NCLOCK and \ref UART_HIGHSPEED.
  1047. */
  1048. static uint8_t At91UsartGetClockMode(void)
  1049. {
  1050. return 0;
  1051. }
  1052. /*!
  1053. * \brief Set asynchronous or synchronous mode.
  1054. *
  1055. * This function is called by ioctl function of the upper level USART
  1056. * driver through the USARTDCB jump table.
  1057. *
  1058. * Not implemented for the AT91 USART. Always returns -1.
  1059. *
  1060. * \param mode Must be an or-ed combination of USART_SYNC, USART_MASTER,
  1061. * USART_NCLOCK and USART_HIGHSPEED.
  1062. *
  1063. * \return 0 on success, -1 otherwise.
  1064. */
  1065. static int At91UsartSetClockMode(uint8_t mode)
  1066. {
  1067. return -1;
  1068. }
  1069. /*!
  1070. * \brief Query flow control mode.
  1071. *
  1072. * This routine is called by ioctl function of the upper level USART
  1073. * driver through the USARTDCB jump table.
  1074. *
  1075. * \return See UsartIOCtl().
  1076. */
  1077. static uint32_t At91UsartGetFlowControl(void)
  1078. {
  1079. uint32_t rc = 0;
  1080. if (flow_control) {
  1081. rc |= USART_MF_XONXOFF;
  1082. } else {
  1083. rc &= ~USART_MF_XONXOFF;
  1084. }
  1085. #if defined(UART_RTS_BIT) || defined(UART_USES_NPL) || defined(UART_HARDWARE_HANDSHAKE)
  1086. if (rts_control) {
  1087. rc |= USART_MF_RTSCONTROL;
  1088. } else {
  1089. rc &= ~USART_MF_RTSCONTROL;
  1090. }
  1091. #endif
  1092. #if defined(UART_CTS_BIT) || defined(UART_USES_NPL) || defined(UART_HARDWARE_HANDSHAKE)
  1093. if (cts_sense) {
  1094. rc |= USART_MF_CTSSENSE;
  1095. } else {
  1096. rc &= ~USART_MF_CTSSENSE;
  1097. }
  1098. #endif
  1099. if (hdx_control) {
  1100. rc |= USART_MF_HALFDUPLEX;
  1101. } else {
  1102. rc &= ~USART_MF_HALFDUPLEX;
  1103. }
  1104. return rc;
  1105. }
  1106. /*!
  1107. * \brief Set flow control mode.
  1108. *
  1109. * This function is called by ioctl function of the upper level USART
  1110. * driver through the USARTDCB jump table.
  1111. *
  1112. * \param flags See UsartIOCtl().
  1113. *
  1114. * \return 0 on success, -1 otherwise.
  1115. */
  1116. static int At91UsartSetFlowControl(uint32_t flags)
  1117. {
  1118. #if USE_BUILT_IN_HARDWARE_HANDSHAKE || USE_BUILT_IN_HALF_DUPLEX
  1119. uint32_t mr = inr(USARTn_BASE + US_MR_OFF) & ~US_MODE;
  1120. #endif
  1121. /*
  1122. * Set software handshake mode.
  1123. */
  1124. NutUartIrqDisable(&SIG_UART);
  1125. if (flags & USART_MF_XONXOFF) {
  1126. if(flow_control == 0) {
  1127. flow_control = 1 | XOFF_SENT; /* force XON to be sent on next read */
  1128. }
  1129. } else {
  1130. flow_control = 0;
  1131. }
  1132. NutUartIrqEnable(&SIG_UART);
  1133. /*
  1134. * Set RTS control mode.
  1135. */
  1136. UART_RTS_PIN_ENABLE();
  1137. UART_RTS_ON();
  1138. if (flags & USART_MF_RTSCONTROL) {
  1139. rts_control = 1;
  1140. #if USE_BUILT_IN_HARDWARE_HANDSHAKE
  1141. outr(USARTn_BASE + US_MR_OFF, mr | US_MODE_HWHANDSHAKE);
  1142. cts_sense = 1;
  1143. #endif
  1144. } else if (rts_control) {
  1145. rts_control = 0;
  1146. #if USE_BUILT_IN_HARDWARE_HANDSHAKE
  1147. outr(USARTn_BASE + US_MR_OFF, mr);
  1148. cts_sense = 0;
  1149. #endif
  1150. }
  1151. /*
  1152. * Set CTS sense mode.
  1153. */
  1154. if (flags & USART_MF_CTSSENSE) {
  1155. cts_sense = 1;
  1156. UART_CTS_PIN_ENABLE();
  1157. #if USE_BUILT_IN_HARDWARE_HANDSHAKE
  1158. rts_control = 1;
  1159. outr(USARTn_BASE + US_MR_OFF, mr | US_MODE_HWHANDSHAKE);
  1160. #endif
  1161. } else if (cts_sense) {
  1162. cts_sense = 0;
  1163. #if USE_BUILT_IN_HARDWARE_HANDSHAKE
  1164. rts_control = 0;
  1165. outr(USARTn_BASE + US_MR_OFF, mr);
  1166. #endif
  1167. }
  1168. /*
  1169. * Set half duplex mode.
  1170. */
  1171. if (flags & USART_MF_HALFDUPLEX) {
  1172. /* Mark half duplex mode enabled. */
  1173. hdx_control = 1;
  1174. /* Enable half duplex pin. */
  1175. UART_HDX_PIN_ENABLE();
  1176. UART_HDX_RX();
  1177. #if USE_BUILT_IN_HALF_DUPLEX
  1178. /* Enable built-in RS-485 mode. */
  1179. outr(USARTn_BASE + US_MR_OFF, mr | US_MODE_RS485);
  1180. #else
  1181. /* Enable USART receive, disable transmit. */
  1182. outr(USARTn_BASE + US_CR_OFF, US_RXEN | US_TXDIS);
  1183. /* Enable transmit complete interrupt. */
  1184. outr(USARTn_BASE + US_IDR_OFF, US_TXEMPTY);
  1185. #endif
  1186. }
  1187. else if (hdx_control) {
  1188. hdx_control = 0;
  1189. #if USE_BUILT_IN_HALF_DUPLEX
  1190. /* Disable built-in RS-485 mode. */
  1191. outr(USARTn_BASE + US_MR_OFF, inr(USARTn_BASE + US_MR_OFF) & ~US_MODE);
  1192. #else
  1193. /* Enable USART receive and transmit. */
  1194. outr(USARTn_BASE + US_CR_OFF, US_RXEN | US_TXEN);
  1195. /* Disable transmit complete interrupt. */
  1196. outr(USARTn_BASE + US_IDR_OFF, US_TXEMPTY);
  1197. #endif
  1198. }
  1199. /* No need to call At91UsartGetFlowControl. The result is obvious,
  1200. ** because we do not exclude unsupported modes yet. */
  1201. return 0;
  1202. }
  1203. /*!
  1204. * \brief Start the USART transmitter hardware.
  1205. *
  1206. * The upper level USART driver will call this function through the
  1207. * USARTDCB jump table each time it added one or more bytes to the
  1208. * transmit buffer.
  1209. */
  1210. static void At91UsartTxStart(void)
  1211. {
  1212. #if USE_BUILT_IN_HALF_DUPLEX == 0
  1213. if (hdx_control) {
  1214. #if defined(UART_HDX_BIT) || defined(UART_USES_NPL)
  1215. UART_HDX_TX();
  1216. #endif
  1217. /* Disable USART receive, enable transmit. */
  1218. outr(USARTn_BASE + US_CR_OFF, US_RXDIS | US_TXEN);
  1219. }
  1220. #endif
  1221. /* Enable transmit interrupts. */
  1222. outr(USARTn_BASE + US_IER_OFF, US_TXRDY);
  1223. }
  1224. /*!
  1225. * \brief Start the USART receiver hardware.
  1226. *
  1227. * The upper level USART driver will call this function through the
  1228. * USARTDCB jump table each time it removed enough bytes from the
  1229. * receive buffer. Enough means, that the number of bytes left in
  1230. * the buffer is below the low watermark.
  1231. */
  1232. static void At91UsartRxStart(void)
  1233. {
  1234. /*
  1235. * Do any required software flow control.
  1236. */
  1237. if (flow_control && (flow_control & XOFF_SENT) != 0) {
  1238. NutUartIrqDisable(&SIG_UART);
  1239. if ((inr(USARTn_BASE + US_CSR_OFF) & US_TXRDY)) {
  1240. outr(USARTn_BASE + US_THR_OFF, ASCII_XON);
  1241. flow_control &= ~XON_PENDING;
  1242. } else {
  1243. flow_control |= XON_PENDING;
  1244. }
  1245. flow_control &= ~(XOFF_SENT | XOFF_PENDING);
  1246. NutUartIrqEnable(&SIG_UART);
  1247. }
  1248. /* Enable RTS. */
  1249. UART_RTS_ON();
  1250. /* Enable receive interrupts. */
  1251. outr(USARTn_BASE + US_IER_OFF, US_RXRDY);
  1252. }
  1253. /*
  1254. * \brief Initialize the USART hardware driver.
  1255. *
  1256. * This function is called during device registration by the upper level
  1257. * USART driver through the USARTDCB jump table.
  1258. *
  1259. * \return 0 on success, -1 otherwise.
  1260. */
  1261. static int At91UsartInit(void)
  1262. {
  1263. /*
  1264. * Register receive and transmit interrupts.
  1265. */
  1266. if (NutUartIrqRegister(&SIG_UART, At91UsartInterrupt, &dcb_usart)) {
  1267. return -1;
  1268. }
  1269. /*
  1270. * Register CTS sense interrupts.
  1271. */
  1272. #if defined(UART_CTS_BIT)
  1273. if (GpioRegisterIrqHandler(&sig_GPIO1, UART_CTS_BIT, At91UsartCts, NULL)) {
  1274. return -1;
  1275. }
  1276. #if defined(PS_PCER)
  1277. outr(PS_PCER, _BV(UART_CTS_PIO_ID));
  1278. #elif defined(PMC_PCER)
  1279. outr(PMC_PCER, _BV(UART_CTS_PIO_ID));
  1280. #endif
  1281. #elif defined(UART_USES_NPL)
  1282. if (NplRegisterIrqHandler(&sig_RSCTS, At91UsartCts, NULL)) {
  1283. return -1;
  1284. }
  1285. #endif
  1286. /* Enable UART clock. */
  1287. #if defined(US_ID)
  1288. #if defined(PS_PCER)
  1289. outr(PS_PCER, _BV(US_ID));
  1290. #elif defined(PMC_PCER)
  1291. outr(PMC_PCER, _BV(US_ID));
  1292. #endif
  1293. #endif
  1294. /* Disable GPIO on UART tx/rx pins. */
  1295. UART_RXTX_PINS_ENABLE();
  1296. /* Reset UART. */
  1297. outr(USARTn_BASE + US_CR_OFF, US_RSTRX | US_RSTTX | US_RXDIS | US_TXDIS);
  1298. /* Disable all UART interrupts. */
  1299. outr(USARTn_BASE + US_IDR_OFF, 0xFFFFFFFF);
  1300. #if defined(US_RCR_OFF) && defined(US_TCR_OFF)
  1301. /* Clear UART PDC counter registers. */
  1302. outr(USARTn_BASE + US_RCR_OFF, 0);
  1303. outr(USARTn_BASE + US_TCR_OFF, 0);
  1304. #endif
  1305. /* Set UART baud rate generator register. */
  1306. At91UsartSetSpeed( UART_INIT_BAUDRATE);
  1307. /* Set UART mode to 8 data bits, no parity and 1 stop bit. */
  1308. outr(USARTn_BASE + US_MR_OFF, US_CHMODE_NORMAL | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1);
  1309. return 0;
  1310. }
  1311. /*
  1312. * \brief Deinitialize the USART hardware driver.
  1313. *
  1314. * This function is called during device deregistration by the upper
  1315. * level USART driver through the USARTDCB jump table.
  1316. *
  1317. * \return 0 on success, -1 otherwise.
  1318. */
  1319. static int At91UsartDeinit(void)
  1320. {
  1321. /* Deregister receive and transmit interrupts. */
  1322. NutUartIrqRegister(&SIG_UART, 0, 0);
  1323. /* Reset UART. */
  1324. outr(USARTn_BASE + US_CR_OFF, US_RSTRX | US_RSTTX | US_RXDIS | US_TXDIS);
  1325. /* Disable all UART interrupts. */
  1326. outr(USARTn_BASE + US_IDR_OFF, 0xFFFFFFFF);
  1327. /* Disable UART clock. */
  1328. #if defined (US_ID)
  1329. #if defined(PS_PCDR)
  1330. outr(PS_PCDR, _BV(US_ID));
  1331. #elif defined(PMC_PCDR)
  1332. outr(PMC_PCDR, _BV(US_ID));
  1333. #endif
  1334. #endif
  1335. /*
  1336. * Disabling flow control shouldn't be required here, because it's up
  1337. * to the upper level to do this on the last close or during
  1338. * deregistration.
  1339. */
  1340. hdx_control = 0;
  1341. UART_HDX_RX();
  1342. cts_sense = 0;
  1343. rts_control = 0;
  1344. return 0;
  1345. }
  1346. /*@}*/