usart_cb_avr.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. /*
  2. * Copyright (C) 2012-2013 by egnite GmbH
  3. * Copyright (C) 2001-2003 by egnite Software 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. *
  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. /*!
  33. * \file arch/avr/usart_cb_avr.c
  34. * \brief Low level routines for AVR UARTs.
  35. *
  36. * See comments in the UART0 driver about constant port addresses.
  37. * The routines in this file should work for all UARTs. This saves
  38. * code in applications using multiple UARTs, but adds more code
  39. * to applications using a single UART only. To avoid the latter,
  40. * NUT_USE_UART0_ONLY may be defined.
  41. *
  42. * \verbatim
  43. * $Id$
  44. * \endverbatim
  45. */
  46. #include <dev/usart.h>
  47. #include <sys/timer.h>
  48. #include <arch/avr/usart_avrctl.h>
  49. #if defined(UBRR0H)
  50. #define UBRR0_HIGH ((uint32_t) inb(UBRR0H) << 8)
  51. #else
  52. #define UBRR0_HIGH 0
  53. #endif
  54. #if defined(U2X0)
  55. #define U2X0_SET (bit_is_set(UCSR0A, U2X0) != 0)
  56. #else
  57. #define U2X0_SET 0
  58. #endif
  59. #if defined(UMSEL0)
  60. #define UMSEL0_SET (bit_is_set(UCSR0C, UMSEL0) != 0)
  61. #else
  62. #define UMSEL0_SET 0
  63. #endif
  64. #if defined(UBRR1H)
  65. #define UBRR1_HIGH ((uint32_t) inb(UBRR1H) << 8)
  66. #else
  67. #define UBRR1_HIGH 0
  68. #endif
  69. #if defined(U2X1)
  70. #define U2X1_SET (bit_is_set(UCSR1A, U2X1) != 0)
  71. #else
  72. #define U2X1_SET 0
  73. #endif
  74. #if defined(UMSEL1)
  75. #define UMSEL1_SET (bit_is_set(UCSR1C, UMSEL1) != 0)
  76. #else
  77. #define UMSEL1_SET 0
  78. #endif
  79. #if defined(UBRR2H)
  80. #define UBRR2_HIGH ((uint32_t) inb(UBRR2H) << 8)
  81. #else
  82. #define UBRR2_HIGH 0
  83. #endif
  84. #if defined(U2X2)
  85. #define U2X2_SET (bit_is_set(UCSR2A, U2X2) != 0)
  86. #else
  87. #define U2X2_SET 0
  88. #endif
  89. #if defined(UMSEL2)
  90. #define UMSEL2_SET (bit_is_set(UCSR2C, UMSEL2) != 0)
  91. #else
  92. #define UMSEL2_SET 0
  93. #endif
  94. #if defined(UBRR3H)
  95. #define UBRR3_HIGH ((uint32_t) inb(UBRR3H) << 8)
  96. #else
  97. #define UBRR3_HIGH 0
  98. #endif
  99. #if defined(U2X3)
  100. #define U2X3_SET (bit_is_set(UCSR3A, U2X3) != 0)
  101. #else
  102. #define U2X3_SET 0
  103. #endif
  104. #if defined(UMSEL3)
  105. #define UMSEL3_SET (bit_is_set(UCSR3C, UMSEL3) != 0)
  106. #else
  107. #define UMSEL3_SET 0
  108. #endif
  109. static uint32_t UsartGetSpeed(uint8_t ifn)
  110. {
  111. uint32_t div;
  112. #if !defined(NUT_USE_UART0_ONLY)
  113. uint8_t shift;
  114. switch (ifn) {
  115. case 0:
  116. div = inb(UBRR0L) | UBRR0_HIGH;
  117. shift = (UMSEL0_SET ? 0 : 4 - U2X0_SET);
  118. break;
  119. case 1:
  120. div = inb(UBRR1L) | UBRR1_HIGH;
  121. shift = (UMSEL1_SET ? 0 : 4 - U2X1_SET);
  122. break;
  123. #if defined(UBRR2L)
  124. /* USART2 --------------------- */
  125. case 2:
  126. div = inb(UBRR2L) | UBRR2_HIGH;
  127. shift = (UMSEL2_SET ? 0 : 4 - U2X2_SET);
  128. break;
  129. #if defined(UBRR3L)
  130. /* USART3 --------------------- */
  131. case 3:
  132. div = inb(UBRR3L) | UBRR3_HIGH;
  133. shift = (UMSEL3_SET ? 0 : 4 - U2X3_SET);
  134. break;
  135. #endif
  136. #endif
  137. default:
  138. return 0;
  139. }
  140. div++;
  141. div <<= shift;
  142. #elif defined(NUT_USE_UART0_ONLY)
  143. div = inb(UBRR0L);
  144. div |= UBRR0_HIGH;
  145. div++;
  146. div <<= (UMSEL0_SET ? 0 : 4 - U2X0_SET);
  147. #endif
  148. return NutClockGet(NUT_HWCLK_PERIPHERAL) / div;
  149. }
  150. static int UsartSetSpeed(uint8_t ifn, uint32_t rate)
  151. {
  152. uint16_t sv;
  153. #if !defined(NUT_USE_UART0_ONLY)
  154. uint8_t shift;
  155. switch (ifn) {
  156. case 0:
  157. shift = (UMSEL0_SET ? 0 : 3 - U2X0_SET);
  158. break;
  159. case 1:
  160. shift = (UMSEL1_SET ? 0 : 3 - U2X1_SET);
  161. break;
  162. #if defined(UBRR2L)
  163. case 2:
  164. shift = (UMSEL2_SET ? 0 : 3 - U2X2_SET);
  165. break;
  166. #if defined(UBRR3L)
  167. case 3:
  168. shift = (UMSEL3_SET ? 0 : 3 - U2X3_SET);
  169. break;
  170. #endif
  171. #endif
  172. default:
  173. return -1;
  174. }
  175. rate <<= shift;
  176. sv = (uint16_t) ((NutClockGet(NUT_HWCLK_PERIPHERAL) / rate + 1UL) / 2UL) - 1;
  177. switch (ifn) {
  178. case 0:
  179. outb(UBRR0L, (uint8_t) sv);
  180. #if defined(UBRR0H)
  181. outb(UBRR0H, (uint8_t) (sv >> 8));
  182. #endif
  183. break;
  184. case 1:
  185. outb(UBRR1L, (uint8_t) sv);
  186. #if defined(UBRR1H)
  187. outb(UBRR1H, (uint8_t) (sv >> 8));
  188. #endif
  189. break;
  190. #if defined(UBRR2L)
  191. case 2:
  192. outb(UBRR2L, (uint8_t) sv);
  193. #if defined(UBRR2H)
  194. outb(UBRR2H, (uint8_t) (sv >> 8));
  195. #endif
  196. break;
  197. #if defined(UBRR3L)
  198. case 3:
  199. outb(UBRR3L, (uint8_t) sv);
  200. #if defined(UBRR3H)
  201. outb(UBRR3H, (uint8_t) (sv >> 8));
  202. #endif
  203. break;
  204. #endif
  205. #endif
  206. }
  207. #else
  208. if (bit_is_clear(UCSR0C, UMSEL)) {
  209. if (bit_is_set(UCSR0A, U2X)) {
  210. rate <<= 2;
  211. } else {
  212. rate <<= 3;
  213. }
  214. }
  215. #endif
  216. return 0;
  217. }
  218. static uint_fast8_t UsartGetDataBits(uint8_t ifn)
  219. {
  220. #if !defined(NUT_USE_UART0_ONLY)
  221. uint_fast8_t szn2 = 0;
  222. uint_fast8_t src = 0;
  223. switch (ifn) {
  224. case 0:
  225. szn2 = bit_is_set(UCSR0B, UCSZ02) != 0;
  226. src = inb(UCSR0C);
  227. break;
  228. case 1:
  229. szn2 = bit_is_set(UCSR1B, UCSZ12) != 0;
  230. src = inb(UCSR1C);
  231. break;
  232. #ifdef UCSR2C
  233. case 2:
  234. szn2 = bit_is_set(UCSR2B, UCSZ22) != 0;
  235. src = inb(UCSR2C);
  236. break;
  237. #ifdef UCSR3C
  238. case 3:
  239. szn2 = bit_is_set(UCSR3B, UCSZ32) != 0;
  240. src = inb(UCSR3C);
  241. break;
  242. #endif
  243. #endif
  244. }
  245. return szn2 ? 9 : ((src & 0x06) >> 1) + 5;
  246. #else
  247. if (bit_is_set(UCSR0B, UCSZ02)) {
  248. return 9;
  249. }
  250. return ((inb(UCSR0C) & 0x06) >> 1) + 5;
  251. #endif
  252. }
  253. static int UsartSetDataBits(uint8_t ifn, uint_fast8_t bits)
  254. {
  255. if (bits == 9) {
  256. switch (ifn) {
  257. case 0:
  258. sbi(UCSR0B, UCSZ02);
  259. break;
  260. case 1:
  261. sbi(UCSR1B, UCSZ12);
  262. break;
  263. #ifdef UCSZ22
  264. case 2:
  265. sbi(UCSR2B, UCSZ22);
  266. break;
  267. #ifdef UCSZ32
  268. case 3:
  269. sbi(UCSR3B, UCSZ32);
  270. break;
  271. #endif
  272. #endif
  273. default:
  274. return -1;
  275. }
  276. bits = 5;
  277. }
  278. if (bits >= 5 && bits <= 8) {
  279. bits = (bits - 5) << 1;
  280. switch (ifn) {
  281. case 0:
  282. outb(UCSR0C, (inb(UCSR0C) & ~(_BV(UCSZ00) | _BV(UCSZ01))) | bits);
  283. break;
  284. case 1:
  285. outb(UCSR1C, (inb(UCSR1C) & ~(_BV(UCSZ10) | _BV(UCSZ11))) | bits);
  286. break;
  287. #if defined(UCSZ20) && defined(UCSZ21)
  288. case 2:
  289. outb(UCSR2C, (inb(UCSR2C) & ~(_BV(UCSZ20) | _BV(UCSZ21))) | bits);
  290. break;
  291. #if defined(UCSZ30) && defined(UCSZ31)
  292. case 3:
  293. outb(UCSR3C, (inb(UCSR3C) & ~(_BV(UCSZ30) | _BV(UCSZ31))) | bits);
  294. break;
  295. #endif
  296. #endif
  297. default:
  298. return -1;
  299. }
  300. }
  301. return 0;
  302. }
  303. static uint_fast8_t UsartGetParity(uint8_t ifn)
  304. {
  305. uint_fast8_t rc = 0;
  306. switch (ifn) {
  307. case 0:
  308. rc = inb(UCSR0C) & (_BV(UPM00) | _BV(UPM01));
  309. break;
  310. case 1:
  311. rc = inb(UCSR1C) & (_BV(UPM10) | _BV(UPM11));
  312. break;
  313. #if defined(UPM20) && defined(UPM21)
  314. case 2:
  315. rc = inb(UCSR2C) & (_BV(UPM20) | _BV(UPM21));
  316. break;
  317. #if defined(UPM30) && defined(UPM31)
  318. case 3:
  319. rc = inb(UCSR3C) & (_BV(UPM30) | _BV(UPM31));
  320. break;
  321. #endif
  322. #endif
  323. }
  324. rc >>= 4;
  325. if (rc == 3) {
  326. rc = 1;
  327. }
  328. return rc;
  329. }
  330. static int UsartSetParity(uint8_t ifn, uint_fast8_t mode)
  331. {
  332. if (mode <= 2) {
  333. if (mode == 1) {
  334. mode = 3;
  335. }
  336. mode <<= 4;
  337. switch (ifn) {
  338. case 0:
  339. outb(UCSR0C, (inb(UCSR0C) & ~(_BV(UPM00) | _BV(UPM01))) | mode);
  340. break;
  341. case 1:
  342. outb(UCSR1C, (inb(UCSR1C) & ~(_BV(UPM10) | _BV(UPM11))) | mode);
  343. break;
  344. #if defined(UPM20) && defined(UPM21)
  345. case 2:
  346. outb(UCSR2C, (inb(UCSR2C) & ~(_BV(UPM20) | _BV(UPM21))) | mode);
  347. break;
  348. #if defined(UPM30) && defined(UPM31)
  349. case 3:
  350. outb(UCSR3C, (inb(UCSR3C) & ~(_BV(UPM30) | _BV(UPM31))) | mode);
  351. break;
  352. #endif
  353. #endif
  354. }
  355. return 0;
  356. }
  357. return -1;
  358. }
  359. static uint8_t UsartGetStopBits(uint8_t ifn)
  360. {
  361. uint8_t rc = 0;
  362. switch (ifn) {
  363. case 0:
  364. rc = bit_is_set(UCSR0C, USBS0) != 0;
  365. break;
  366. case 1:
  367. rc = bit_is_set(UCSR1C, USBS1) != 0;
  368. break;
  369. #if defined(USBS2)
  370. case 2:
  371. rc = bit_is_set(UCSR2C, USBS2) != 0;
  372. break;
  373. #if defined(USBS2)
  374. case 3:
  375. rc = bit_is_set(UCSR3C, USBS3) != 0;
  376. break;
  377. #endif
  378. #endif
  379. }
  380. return rc + 1;
  381. }
  382. static int UsartSetStopBits(uint8_t ifn, uint8_t bits)
  383. {
  384. if (bits == 1) {
  385. switch (ifn) {
  386. case 0:
  387. cbi(UCSR0C, USBS0);
  388. break;
  389. case 1:
  390. cbi(UCSR1C, USBS1);
  391. break;
  392. #if defined(USBS2)
  393. case 2:
  394. cbi(UCSR2C, USBS2);
  395. break;
  396. #if defined(USBS3)
  397. case 3:
  398. cbi(UCSR3C, USBS3);
  399. break;
  400. #endif
  401. #endif
  402. default:
  403. return -1;
  404. }
  405. }
  406. else if (bits == 2) {
  407. switch (ifn) {
  408. case 0:
  409. sbi(UCSR0C, USBS0);
  410. break;
  411. case 1:
  412. sbi(UCSR1C, USBS1);
  413. break;
  414. #if defined(USBS2)
  415. case 2:
  416. sbi(UCSR2C, USBS2);
  417. break;
  418. #if defined(USBS3)
  419. case 3:
  420. sbi(UCSR3C, USBS3);
  421. break;
  422. #endif
  423. #endif
  424. default:
  425. return -1;
  426. }
  427. }
  428. else {
  429. return -1;
  430. }
  431. return 0;
  432. }
  433. int AvrUsartControl(USARTCB_DCB *dcb, int req, void *conf)
  434. {
  435. int rc = 0;
  436. uint32_t *u32vp = (uint32_t *) conf;
  437. AVRUSART_IFC *uif = (AVRUSART_IFC *) dcb->usart_hwif;
  438. int8_t ifn = uif->uifc_num;
  439. switch (req) {
  440. case UART_GETSPEED:
  441. *u32vp = UsartGetSpeed(ifn);
  442. break;
  443. case UART_SETSPEED:
  444. rc = UsartSetSpeed(ifn, *u32vp);
  445. break;
  446. case UART_GETDATABITS:
  447. *u32vp = UsartGetDataBits(ifn);
  448. break;
  449. case UART_SETDATABITS:
  450. rc = UsartSetDataBits(ifn, (uint_fast8_t) *u32vp);
  451. break;
  452. case UART_GETPARITY:
  453. *u32vp = UsartGetParity(ifn);
  454. break;
  455. case UART_SETPARITY:
  456. rc = UsartSetParity(ifn, (uint_fast8_t) *u32vp);
  457. break;
  458. case UART_GETSTOPBITS:
  459. *u32vp = UsartGetStopBits(ifn);
  460. break;
  461. case UART_SETSTOPBITS:
  462. rc = UsartSetStopBits(ifn, (uint_fast8_t) *u32vp);
  463. break;
  464. case UART_GETSTATUS:
  465. //*u32vp = dcb->usart_status(dcb, 0);
  466. break;
  467. case UART_SETSTATUS:
  468. //dcb->usart_status(dcb, *u32vp | _BV(31));
  469. break;
  470. case UART_GETFLOWCONTROL:
  471. *u32vp = dcb->usart_mode & (USART_MF_SENSEMASK | USART_MF_CONTROLMASK | USART_MF_XONXOFF);
  472. break;
  473. case UART_SETFLOWCONTROL:
  474. if (*u32vp & ~(dcb->usart_caps & (USART_MF_SENSEMASK | USART_MF_CONTROLMASK | USART_MF_XONXOFF))) {
  475. rc = -1;
  476. } else {
  477. dcb->usart_mode &= ~dcb->usart_caps;
  478. dcb->usart_mode |= *u32vp;
  479. }
  480. break;
  481. case UART_GETRXBUFLWMARK:
  482. *u32vp = dcb->usart_rx_lowm;
  483. break;
  484. case UART_SETRXBUFLWMARK:
  485. dcb->usart_rx_lowm = (size_t) *u32vp;
  486. break;
  487. case UART_GETRXBUFHWMARK:
  488. *u32vp = dcb->usart_rx_hiwm;
  489. break;
  490. case UART_SETRXBUFHWMARK:
  491. dcb->usart_rx_hiwm = (size_t) *u32vp;
  492. break;
  493. default:
  494. rc = -1;
  495. break;
  496. }
  497. return rc;
  498. }