usart0avr.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * Copyright (C) 2001-2007 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/usart0avr.c
  39. * \brief AVR USART0 support.
  40. *
  41. * \verbatim
  42. * $Id: usart0avr.c 5472 2013-12-06 00:16:28Z olereinhardt $
  43. * \endverbatim
  44. */
  45. #include <cfg/os.h>
  46. #include <cfg/arch/avr.h>
  47. #include <string.h>
  48. #include <sys/atom.h>
  49. #include <sys/event.h>
  50. #include <sys/timer.h>
  51. #include <dev/irqreg.h>
  52. #include <dev/usartavr.h>
  53. /*!
  54. * \name UART0 RTS Handshake Control
  55. *
  56. * UART0_RTS_BIT must be defined in arch/avr.h
  57. */
  58. #ifdef UART0_RTS_BIT
  59. #if (UART0_RTS_AVRPORT == AVRPORTB)
  60. #define UART_RTS_PORT PORTB
  61. #define UART_RTS_DDR DDRB
  62. #elif (UART0_RTS_AVRPORT == AVRPORTD)
  63. #define UART_RTS_PORT PORTD
  64. #define UART_RTS_DDR DDRD
  65. #elif (UART0_RTS_AVRPORT == AVRPORTE)
  66. #define UART_RTS_PORT PORTE
  67. #define UART_RTS_DDR DDRE
  68. #elif (UART0_RTS_AVRPORT == AVRPORTF)
  69. #define UART_RTS_PORT PORTF
  70. #define UART_RTS_DDR DDRF
  71. #elif (UART0_RTS_AVRPORT == AVRPORTG)
  72. #define UART_RTS_PORT PORTG
  73. #define UART_RTS_DDR DDRG
  74. #elif (UART0_RTS_AVRPORT == AVRPORTH)
  75. #define UART_RTS_PORT PORTH
  76. #define UART_RTS_DDR DDRH
  77. #endif
  78. #define UART_RTS_BIT UART0_RTS_BIT
  79. #endif /* UART0_RTS_BIT */
  80. #ifdef UART0_DTR_BIT
  81. #if (UART0_DTR_AVRPORT == AVRPORTB)
  82. #define UART_DTR_PORT PORTB
  83. #define UART_DTR_DDR DDRB
  84. #elif (UART0_DTR_AVRPORT == AVRPORTD)
  85. #define UART_DTR_PORT PORTD
  86. #define UART_DTR_DDR DDRD
  87. #elif (UART0_DTR_AVRPORT == AVRPORTE)
  88. #define UART_DTR_PORT PORTE
  89. #define UART_DTR_DDR DDRE
  90. #elif (UART0_DTR_AVRPORT == AVRPORTF)
  91. #define UART_DTR_PORT PORTF
  92. #define UART_DTR_DDR DDRF
  93. #elif (UART0_DTR_AVRPORT == AVRPORTG)
  94. #define UART_DTR_PORT PORTG
  95. #define UART_DTR_DDR DDRG
  96. #elif (UART0_DTR_AVRPORT == AVRPORTH)
  97. #define UART_DTR_PORT PORTH
  98. #define UART_DTR_DDR DDRH
  99. #endif
  100. #define UART_DTR_BIT UART0_DTR_BIT
  101. #endif /* UART0_DTR_BIT */
  102. /*!
  103. * \name UART0 Half Duplex Control
  104. *
  105. * UART0_HDX_BIT must be defined in arch/avr.h
  106. */
  107. #ifdef UART0_HDX_BIT
  108. #if (UART0_HDX_AVRPORT == AVRPORTB)
  109. #define UART_HDX_PORT PORTB
  110. #define UART_HDX_DDR DDRB
  111. #elif (UART0_HDX_AVRPORT == AVRPORTD)
  112. #define UART_HDX_PORT PORTD
  113. #define UART_HDX_DDR DDRD
  114. #elif (UART0_HDX_AVRPORT == AVRPORTE)
  115. #define UART_HDX_PORT PORTE
  116. #define UART_HDX_DDR DDRE
  117. #elif (UART0_HDX_AVRPORT == AVRPORTF)
  118. #define UART_HDX_PORT PORTF
  119. #define UART_HDX_DDR DDRF
  120. #elif (UART0_HDX_AVRPORT == AVRPORTG)
  121. #define UART_HDX_PORT PORTG
  122. #define UART_HDX_DDR DDRG
  123. #elif (UART0_HDX_AVRPORT == AVRPORTH)
  124. #define UART_HDX_PORT PORTH
  125. #define UART_HDX_DDR DDRH
  126. #endif
  127. #define UART_HDX_BIT UART0_HDX_BIT
  128. #endif /* UART0_HDX_BIT */
  129. /*
  130. * Local function prototypes.
  131. */
  132. static uint32_t AvrUsartGetSpeed(void);
  133. static int AvrUsartSetSpeed(uint32_t rate);
  134. static uint8_t AvrUsartGetDataBits(void);
  135. static int AvrUsartSetDataBits(uint8_t bits);
  136. static uint8_t AvrUsartGetParity(void);
  137. static int AvrUsartSetParity(uint8_t mode);
  138. static uint8_t AvrUsartGetStopBits(void);
  139. static int AvrUsartSetStopBits(uint8_t bits);
  140. static uint32_t AvrUsartGetFlowControl(void);
  141. static int AvrUsartSetFlowControl(uint32_t flags);
  142. static uint32_t AvrUsartGetStatus(void);
  143. static int AvrUsartSetStatus(uint32_t flags);
  144. static uint8_t AvrUsartGetClockMode(void);
  145. static int AvrUsartSetClockMode(uint8_t mode);
  146. static void AvrUsartTxStart(void);
  147. static void AvrUsartRxStart(void);
  148. static int AvrUsartInit(void);
  149. static int AvrUsartDeinit(void);
  150. /*!
  151. * \addtogroup xgUsartAvr
  152. */
  153. /*@{*/
  154. /*!
  155. * \brief USART0 device control block structure.
  156. */
  157. static USARTDCB dcb_usart0 = {
  158. 0, /* dcb_modeflags */
  159. 0, /* dcb_statusflags */
  160. 0, /* dcb_rtimeout */
  161. 0, /* dcb_wtimeout */
  162. {0, 0, 0, 0, 0, 0, 0, 0}, /* dcb_tx_rbf */
  163. {0, 0, 0, 0, 0, 0, 0, 0}, /* dcb_rx_rbf */
  164. 0, /* dbc_last_eol */
  165. AvrUsartInit, /* dcb_init */
  166. AvrUsartDeinit, /* dcb_deinit */
  167. AvrUsartTxStart, /* dcb_tx_start */
  168. AvrUsartRxStart, /* dcb_rx_start */
  169. AvrUsartSetFlowControl, /* dcb_set_flow_control */
  170. AvrUsartGetFlowControl, /* dcb_get_flow_control */
  171. AvrUsartSetSpeed, /* dcb_set_speed */
  172. AvrUsartGetSpeed, /* dcb_get_speed */
  173. AvrUsartSetDataBits, /* dcb_set_data_bits */
  174. AvrUsartGetDataBits, /* dcb_get_data_bits */
  175. AvrUsartSetParity, /* dcb_set_parity */
  176. AvrUsartGetParity, /* dcb_get_parity */
  177. AvrUsartSetStopBits, /* dcb_set_stop_bits */
  178. AvrUsartGetStopBits, /* dcb_get_stop_bits */
  179. AvrUsartSetStatus, /* dcb_set_status */
  180. AvrUsartGetStatus, /* dcb_get_status */
  181. AvrUsartSetClockMode, /* dcb_set_clock_mode */
  182. AvrUsartGetClockMode, /* dcb_get_clock_mode */
  183. };
  184. /*!
  185. * \name AVR USART0 Device
  186. */
  187. /*@{*/
  188. /*!
  189. * \brief USART0 device information structure.
  190. *
  191. * An application must pass a pointer to this structure to
  192. * NutRegisterDevice() before using the serial communication
  193. * driver of the AVR's on-chip USART0.
  194. *
  195. * The device is named \b uart0.
  196. *
  197. * \showinitializer
  198. */
  199. NUTDEVICE devUsartAvr0 = {
  200. 0, /* Pointer to next device, dev_next. */
  201. {'u', 'a', 'r', 't', '0', 0, 0, 0, 0}, /* Unique device name, dev_name. */
  202. IFTYP_CHAR, /* Type of device, dev_type. */
  203. 0, /* Base address, dev_base (not used). */
  204. 0, /* First interrupt number, dev_irq (not used). */
  205. 0, /* Interface control block, dev_icb (not used). */
  206. &dcb_usart0, /* Driver control block, dev_dcb. */
  207. UsartInit, /* Driver initialization routine, dev_init. */
  208. UsartIOCtl, /* Driver specific control function, dev_ioctl. */
  209. UsartRead, /* Read from device, dev_read. */
  210. UsartWrite, /* Write to device, dev_write. */
  211. UsartWrite_P, /* Write data from program space to device, dev_write_P. */
  212. UsartOpen, /* Open a device or file, dev_open. */
  213. UsartClose, /* Close a device or file, dev_close. */
  214. UsartSize, /* Request file size, dev_size. */
  215. UsartSelect, /* Select function, dev_select. */
  216. };
  217. /*@}*/
  218. /*!
  219. * \name UART0 CTS Handshake Sense
  220. *
  221. * \ref UART0_CTS_IRQ must be defined in arch/avr.h
  222. */
  223. // added extra ifdef as test below is true even if UART0_CTS_IRQ is undef
  224. #ifdef UART0_CTS_IRQ
  225. #if (UART0_CTS_IRQ == INT0)
  226. #define UART_CTS_SIGNAL sig_INTERRUPT0
  227. #define UART_CTS_BIT 0
  228. #define UART_CTS_PORT PORTD
  229. #define UART_CTS_PIN PIND
  230. #define UART_CTS_DDR DDRD
  231. #elif (UART0_CTS_IRQ == INT1)
  232. #define UART_CTS_SIGNAL sig_INTERRUPT1
  233. #define UART_CTS_BIT 1
  234. #define UART_CTS_PORT PORTD
  235. #define UART_CTS_PIN PIND
  236. #define UART_CTS_DDR DDRD
  237. #elif (UART0_CTS_IRQ == INT2)
  238. #define UART_CTS_SIGNAL sig_INTERRUPT2
  239. #define UART_CTS_BIT 2
  240. #define UART_CTS_PORT PORTD
  241. #define UART_CTS_PIN PIND
  242. #define UART_CTS_DDR DDRD
  243. #elif (UART0_CTS_IRQ == INT3)
  244. #define UART_CTS_SIGNAL sig_INTERRUPT3
  245. #define UART_CTS_BIT 3
  246. #define UART_CTS_PORT PORTD
  247. #define UART_CTS_PIN PIND
  248. #define UART_CTS_DDR DDRD
  249. #elif (UART0_CTS_IRQ == INT4)
  250. #define UART_CTS_SIGNAL sig_INTERRUPT4
  251. #define UART_CTS_BIT 4
  252. #define UART_CTS_PORT PORTE
  253. #define UART_CTS_PIN PINE
  254. #define UART_CTS_DDR DDRE
  255. #elif (UART0_CTS_IRQ == INT5)
  256. #define UART_CTS_SIGNAL sig_INTERRUPT5
  257. #define UART_CTS_BIT 5
  258. #define UART_CTS_PORT PORTE
  259. #define UART_CTS_PIN PINE
  260. #define UART_CTS_DDR DDRE
  261. #elif (UART0_CTS_IRQ == INT6)
  262. #define UART_CTS_SIGNAL sig_INTERRUPT6
  263. #define UART_CTS_BIT 6
  264. #define UART_CTS_PORT PORTE
  265. #define UART_CTS_PIN PINE
  266. #define UART_CTS_DDR DDRE
  267. #elif (UART0_CTS_IRQ == INT7)
  268. #define UART_CTS_SIGNAL sig_INTERRUPT7
  269. #define UART_CTS_BIT 7
  270. #define UART_CTS_PORT PORTE
  271. #define UART_CTS_PIN PINE
  272. #define UART_CTS_DDR DDRE
  273. #endif
  274. #else
  275. // alternate way to specify the cts line
  276. #define UART_CTS_PORT UART0_CTS_PORT
  277. #define UART_CTS_PIN UART0_CTS_PIN
  278. #define UART_CTS_DDR UART0_CTS_DDR
  279. // only set CTS_BIT if used and IRQ available
  280. #ifdef UART1_CTS_BIT
  281. #define UART_CTS_SIGNAL UART0_CTS_SIGNAL
  282. #define UART_CTS_BIT UART0_CTS_BIT
  283. #endif
  284. #endif
  285. /*@}*/
  286. #ifdef __AVR_ENHANCED__
  287. #define UDRn UDR0
  288. #define UCSRnA UCSR0A
  289. #define UCSRnB UCSR0B
  290. #define UCSRnC UCSR0C
  291. #define UBRRnL UBRR0L
  292. #define UBRRnH UBRR0H
  293. #ifdef __IMAGECRAFT__
  294. #define TXB8 TXB80
  295. #if defined(ATMega2560) || defined(ATMega2561)
  296. #define UMSEL UMSEL00
  297. #else
  298. #define UMSEL UMSEL0
  299. #endif
  300. #define U2X U2X0
  301. #define UCSZ2 UCSZ02
  302. #define UCSZ1 UCSZ01
  303. #define UCSZ0 UCSZ00
  304. #define UPM0 UPM00
  305. #define UPM1 UPM01
  306. #define USBS USBS0
  307. #define UPE UPE0
  308. #define MPCM MPCM0
  309. #define UCPOL UCPOL0
  310. #endif
  311. #else
  312. #define UDRn UDR
  313. #define UCSRnA USR
  314. #define UCSRnB UCR
  315. #define UBRRnL UBRR
  316. #define UCSZ2 CHR9
  317. #endif
  318. #define sig_UART_RECV sig_UART0_RECV
  319. #define sig_UART_DATA sig_UART0_DATA
  320. #define sig_UART_TRANS sig_UART0_TRANS
  321. /* avr-libc names the vector as in the datasheets. As Atmel naming is
  322. * inconsistant, so is the avr-libc naming.
  323. * Equalize!
  324. */
  325. #if !defined(USART0_RX_vect) && defined( UART0_RX_vect)
  326. #define USART0_RX_vect UART0_RX_vect
  327. #elif !defined(USART0_RX_vect) && defined(UART_RX_vect)
  328. #define USART0_RX_vect UART_RX_vect
  329. #endif
  330. #define SIG_AVRUART_RECV USART0_RX_vect
  331. #if !defined(USART0_UDRE_vect) && defined(UART0_UDRE_vect)
  332. #define USART0_UDRE_vect UART0_UDRE_vect
  333. #elif !defined(USART0_UDRE_vect) && defined(UART_UDRE_vect)
  334. #define USART0_UDRE_vect UART_UDRE_vect
  335. #endif
  336. #define SIG_AVRUART_DATA USART0_UDRE_vect
  337. #if !defined(USART0_TX_vect) && defined( UART0_TX_vect)
  338. #define USART0_TX_vect UART0_TX_vect
  339. #elif !defined(USART0_TX_vect) && defined(UART_TX_vect)
  340. #define USART0_TX_vect UART_TX_vect
  341. #endif
  342. #define SIG_AVRUART_TRANS USART0_TX_vect
  343. #define dcb_usart dcb_usart0
  344. #ifdef NUTTRACER
  345. #define TRACE_INT_UART_CTS TRACE_INT_UART0_CTS
  346. #define TRACE_INT_UART_RXCOMPL TRACE_INT_UART0_RXCOMPL
  347. #define TRACE_INT_UART_TXEMPTY TRACE_INT_UART0_TXEMPTY
  348. #endif
  349. /* Define to allow IRQ handler to read all bytes from RX FIFO. */
  350. #ifdef UART0_READMULTIBYTE
  351. #define UART_READMULTIBYTE
  352. #endif
  353. /* Define to use native interrupt handler. */
  354. #ifdef USE_USART0
  355. #define USE_USART
  356. #endif
  357. /* Define to bypass software flow control. */
  358. #ifdef UART0_NO_SW_FLOWCONTROL
  359. #define UART_NO_SW_FLOWCONTROL
  360. #endif
  361. /*@}*/
  362. #include "usartavr.c"