ahdlcavr.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537
  1. /*
  2. * Copyright (C) 2003-2004 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. */
  33. /*!
  34. * \file arch/avr/dev/ahdlcavr.c
  35. * \brief AVR AHDLC driver.
  36. *
  37. * \verbatim
  38. * $Id: ahdlcavr.c 5472 2013-12-06 00:16:28Z olereinhardt $
  39. * \endverbatim
  40. */
  41. #include <cfg/ahdlc.h>
  42. #include <cfg/arch/avr.h>
  43. #include <toolchain.h>
  44. #include <sys/atom.h>
  45. #include <sys/heap.h>
  46. #include <sys/event.h>
  47. #include <sys/timer.h>
  48. #include <sys/thread.h>
  49. #include <dev/irqreg.h>
  50. #include <dev/uartavr.h>
  51. #include <dev/ppp.h>
  52. #include <dev/ahdlcavr.h>
  53. #include <stdint.h>
  54. #include <stdio.h>
  55. #include <string.h>
  56. #include <stdlib.h>
  57. #include <fcntl.h>
  58. /*!
  59. * \addtogroup xgAhdlcAvr
  60. */
  61. /*@{*/
  62. /*!
  63. * \name UART0 RTS Handshake Control
  64. *
  65. * UART0_RTS_BIT must be defined in arch/avr.h
  66. */
  67. #ifdef UART0_RTS_BIT
  68. #if (UART0_RTS_AVRPORT == AVRPORTB)
  69. #define UART0_RTS_PORT PORTB
  70. #define UART0_RTS_DDR DDRB
  71. #elif (UART0_RTS_AVRPORT == AVRPORTD)
  72. #define UART0_RTS_PORT PORTD
  73. #define UART0_RTS_DDR DDRD
  74. #elif (UART0_RTS_AVRPORT == AVRPORTE)
  75. #define UART0_RTS_PORT PORTE
  76. #define UART0_RTS_DDR DDRE
  77. #elif (UART0_RTS_AVRPORT == AVRPORTF)
  78. #define UART0_RTS_PORT PORTF
  79. #define UART0_RTS_DDR DDRF
  80. #elif (UART0_RTS_AVRPORT == AVRPORTG)
  81. #define UART0_RTS_PORT PORTG
  82. #define UART0_RTS_DDR DDRG
  83. #elif (UART0_RTS_AVRPORT == AVRPORTH)
  84. #define UART0_RTS_PORT PORTH
  85. #define UART0_RTS_DDR DDRH
  86. #endif
  87. #endif /* UART0_RTS_BIT */
  88. #ifdef UART0_DTR_BIT
  89. #if (UART0_DTR_AVRPORT == AVRPORTB)
  90. #define UART0_DTR_PORT PORTB
  91. #define UART0_DTR_DDR DDRB
  92. #elif (UART0_DTR_AVRPORT == AVRPORTD)
  93. #define UART0_DTR_PORT PORTD
  94. #define UART0_DTR_DDR DDRD
  95. #elif (UART0_DTR_AVRPORT == AVRPORTE)
  96. #define UART0_DTR_PORT PORTE
  97. #define UART0_DTR_DDR DDRE
  98. #elif (UART0_DTR_AVRPORT == AVRPORTF)
  99. #define UART0_DTR_PORT PORTF
  100. #define UART0_DTR_DDR DDRF
  101. #elif (UART0_DTR_AVRPORT == AVRPORTG)
  102. #define UART0_DTR_PORT PORTG
  103. #define UART0_DTR_DDR DDRG
  104. #elif (UART0_DTR_AVRPORT == AVRPORTH)
  105. #define UART0_DTR_PORT PORTH
  106. #define UART0_DTR_DDR DDRH
  107. #endif
  108. #endif /* UART0_DTR_BIT */
  109. /*!
  110. * \name UART1 RTS Handshake Control
  111. *
  112. * UART1_RTS_BIT must be defined in arch/avr.h
  113. */
  114. #ifdef UART1_RTS_BIT
  115. #if (UART1_RTS_AVRPORT == AVRPORTB)
  116. #define UART1_RTS_PORT PORTB
  117. #define UART1_RTS_DDR DDRB
  118. #elif (UART1_RTS_AVRPORT == AVRPORTD)
  119. #define UART1_RTS_PORT PORTD
  120. #define UART1_RTS_DDR DDRD
  121. #elif (UART1_RTS_AVRPORT == AVRPORTE)
  122. #define UART1_RTS_PORT PORTE
  123. #define UART1_RTS_DDR DDRE
  124. #elif (UART1_RTS_AVRPORT == AVRPORTF)
  125. #define UART1_RTS_PORT PORTF
  126. #define UART1_RTS_DDR DDRF
  127. #elif (UART1_RTS_AVRPORT == AVRPORTG)
  128. #define UART1_RTS_PORT PORTG
  129. #define UART1_RTS_DDR DDRG
  130. #elif (UART1_RTS_AVRPORT == AVRPORTH)
  131. #define UART1_RTS_PORT PORTH
  132. #define UART1_RTS_DDR DDRH
  133. #endif
  134. #endif /* UART1_RTS_BIT */
  135. #ifdef UART1_DTR_BIT
  136. #if (UART1_DTR_AVRPORT == AVRPORTB)
  137. #define UART1_DTR_PORT PORTB
  138. #define UART1_DTR_DDR DDRB
  139. #elif (UART1_DTR_AVRPORT == AVRPORTD)
  140. #define UART1_DTR_PORT PORTD
  141. #define UART1_DTR_DDR DDRD
  142. #elif (UART1_DTR_AVRPORT == AVRPORTE)
  143. #define UART1_DTR_PORT PORTE
  144. #define UART1_DTR_DDR DDRE
  145. #elif (UART1_DTR_AVRPORT == AVRPORTF)
  146. #define UART1_DTR_PORT PORTF
  147. #define UART1_DTR_DDR DDRF
  148. #elif (UART1_DTR_AVRPORT == AVRPORTG)
  149. #define UART1_DTR_PORT PORTG
  150. #define UART1_DTR_DDR DDRG
  151. #elif (UART1_DTR_AVRPORT == AVRPORTH)
  152. #define UART1_DTR_PORT PORTH
  153. #define UART1_DTR_DDR DDRH
  154. #endif
  155. #endif /* UART1_DTR_BIT */
  156. /*
  157. * FCS lookup table located in program memory space.
  158. */
  159. static const char fcstab[512] PROGMEM = {
  160. 0x00, 0x00, 0x11, 0x89, 0x23, 0x12, 0x32, 0x9b, 0x46, 0x24, 0x57, 0xad, 0x65, 0x36, 0x74, 0xbf,
  161. 0x8c, 0x48, 0x9d, 0xc1, 0xaf, 0x5a, 0xbe, 0xd3, 0xca, 0x6c, 0xdb, 0xe5, 0xe9, 0x7e, 0xf8, 0xf7,
  162. 0x10, 0x81, 0x01, 0x08, 0x33, 0x93, 0x22, 0x1a, 0x56, 0xa5, 0x47, 0x2c, 0x75, 0xb7, 0x64, 0x3e,
  163. 0x9c, 0xc9, 0x8d, 0x40, 0xbf, 0xdb, 0xae, 0x52, 0xda, 0xed, 0xcb, 0x64, 0xf9, 0xff, 0xe8, 0x76,
  164. 0x21, 0x02, 0x30, 0x8b, 0x02, 0x10, 0x13, 0x99, 0x67, 0x26, 0x76, 0xaf, 0x44, 0x34, 0x55, 0xbd,
  165. 0xad, 0x4a, 0xbc, 0xc3, 0x8e, 0x58, 0x9f, 0xd1, 0xeb, 0x6e, 0xfa, 0xe7, 0xc8, 0x7c, 0xd9, 0xf5,
  166. 0x31, 0x83, 0x20, 0x0a, 0x12, 0x91, 0x03, 0x18, 0x77, 0xa7, 0x66, 0x2e, 0x54, 0xb5, 0x45, 0x3c,
  167. 0xbd, 0xcb, 0xac, 0x42, 0x9e, 0xd9, 0x8f, 0x50, 0xfb, 0xef, 0xea, 0x66, 0xd8, 0xfd, 0xc9, 0x74,
  168. 0x42, 0x04, 0x53, 0x8d, 0x61, 0x16, 0x70, 0x9f, 0x04, 0x20, 0x15, 0xa9, 0x27, 0x32, 0x36, 0xbb,
  169. 0xce, 0x4c, 0xdf, 0xc5, 0xed, 0x5e, 0xfc, 0xd7, 0x88, 0x68, 0x99, 0xe1, 0xab, 0x7a, 0xba, 0xf3,
  170. 0x52, 0x85, 0x43, 0x0c, 0x71, 0x97, 0x60, 0x1e, 0x14, 0xa1, 0x05, 0x28, 0x37, 0xb3, 0x26, 0x3a,
  171. 0xde, 0xcd, 0xcf, 0x44, 0xfd, 0xdf, 0xec, 0x56, 0x98, 0xe9, 0x89, 0x60, 0xbb, 0xfb, 0xaa, 0x72,
  172. 0x63, 0x06, 0x72, 0x8f, 0x40, 0x14, 0x51, 0x9d, 0x25, 0x22, 0x34, 0xab, 0x06, 0x30, 0x17, 0xb9,
  173. 0xef, 0x4e, 0xfe, 0xc7, 0xcc, 0x5c, 0xdd, 0xd5, 0xa9, 0x6a, 0xb8, 0xe3, 0x8a, 0x78, 0x9b, 0xf1,
  174. 0x73, 0x87, 0x62, 0x0e, 0x50, 0x95, 0x41, 0x1c, 0x35, 0xa3, 0x24, 0x2a, 0x16, 0xb1, 0x07, 0x38,
  175. 0xff, 0xcf, 0xee, 0x46, 0xdc, 0xdd, 0xcd, 0x54, 0xb9, 0xeb, 0xa8, 0x62, 0x9a, 0xf9, 0x8b, 0x70,
  176. 0x84, 0x08, 0x95, 0x81, 0xa7, 0x1a, 0xb6, 0x93, 0xc2, 0x2c, 0xd3, 0xa5, 0xe1, 0x3e, 0xf0, 0xb7,
  177. 0x08, 0x40, 0x19, 0xc9, 0x2b, 0x52, 0x3a, 0xdb, 0x4e, 0x64, 0x5f, 0xed, 0x6d, 0x76, 0x7c, 0xff,
  178. 0x94, 0x89, 0x85, 0x00, 0xb7, 0x9b, 0xa6, 0x12, 0xd2, 0xad, 0xc3, 0x24, 0xf1, 0xbf, 0xe0, 0x36,
  179. 0x18, 0xc1, 0x09, 0x48, 0x3b, 0xd3, 0x2a, 0x5a, 0x5e, 0xe5, 0x4f, 0x6c, 0x7d, 0xf7, 0x6c, 0x7e,
  180. 0xa5, 0x0a, 0xb4, 0x83, 0x86, 0x18, 0x97, 0x91, 0xe3, 0x2e, 0xf2, 0xa7, 0xc0, 0x3c, 0xd1, 0xb5,
  181. 0x29, 0x42, 0x38, 0xcb, 0x0a, 0x50, 0x1b, 0xd9, 0x6f, 0x66, 0x7e, 0xef, 0x4c, 0x74, 0x5d, 0xfd,
  182. 0xb5, 0x8b, 0xa4, 0x02, 0x96, 0x99, 0x87, 0x10, 0xf3, 0xaf, 0xe2, 0x26, 0xd0, 0xbd, 0xc1, 0x34,
  183. 0x39, 0xc3, 0x28, 0x4a, 0x1a, 0xd1, 0x0b, 0x58, 0x7f, 0xe7, 0x6e, 0x6e, 0x5c, 0xf5, 0x4d, 0x7c,
  184. 0xc6, 0x0c, 0xd7, 0x85, 0xe5, 0x1e, 0xf4, 0x97, 0x80, 0x28, 0x91, 0xa1, 0xa3, 0x3a, 0xb2, 0xb3,
  185. 0x4a, 0x44, 0x5b, 0xcd, 0x69, 0x56, 0x78, 0xdf, 0x0c, 0x60, 0x1d, 0xe9, 0x2f, 0x72, 0x3e, 0xfb,
  186. 0xd6, 0x8d, 0xc7, 0x04, 0xf5, 0x9f, 0xe4, 0x16, 0x90, 0xa9, 0x81, 0x20, 0xb3, 0xbb, 0xa2, 0x32,
  187. 0x5a, 0xc5, 0x4b, 0x4c, 0x79, 0xd7, 0x68, 0x5e, 0x1c, 0xe1, 0x0d, 0x68, 0x3f, 0xf3, 0x2e, 0x7a,
  188. 0xe7, 0x0e, 0xf6, 0x87, 0xc4, 0x1c, 0xd5, 0x95, 0xa1, 0x2a, 0xb0, 0xa3, 0x82, 0x38, 0x93, 0xb1,
  189. 0x6b, 0x46, 0x7a, 0xcf, 0x48, 0x54, 0x59, 0xdd, 0x2d, 0x62, 0x3c, 0xeb, 0x0e, 0x70, 0x1f, 0xf9,
  190. 0xf7, 0x8f, 0xe6, 0x06, 0xd4, 0x9d, 0xc5, 0x14, 0xb1, 0xab, 0xa0, 0x22, 0x92, 0xb9, 0x83, 0x30,
  191. 0x7b, 0xc7, 0x6a, 0x4e, 0x58, 0xd5, 0x49, 0x5c, 0x3d, 0xe3, 0x2c, 0x6a, 0x1e, 0xf1, 0x0f, 0x78
  192. };
  193. /*!
  194. * Checks the 32-bit ACCM to see if the byte needs un-escaping
  195. */
  196. #define IN_ACC_MAP(c, m) in_acc_map(c, &(m))
  197. /* Trust me, this is a whole lot smaller when compiled than it looks in C.
  198. * It is written explicitly so that gcc can make good AVR asm out of it. */
  199. static NUT_INLINE_FUNC uint8_t in_acc_map(u_char ch, void * esc_mask) NUT_FORCE_INLINE; /* gcc specific attribute */
  200. static NUT_INLINE_FUNC uint8_t in_acc_map(u_char ch, void * esc_mask)
  201. {
  202. const uint8_t shift_mask = 0x07;
  203. const uint8_t index_mask = 0x18;
  204. const uint8_t over_mask = ~(shift_mask|index_mask);
  205. uint8_t shift, index, emask;
  206. uint8_t * emskp = esc_mask;
  207. if (over_mask & ch) {
  208. return 0;
  209. }
  210. shift = shift_mask & ch;
  211. index = ch >> (uint8_t)3;
  212. /* NOTE: This assumes that the esc bit field is little endian,
  213. * which it should have been switched to before being set. */
  214. emask = emskp[index];
  215. return emask & ( ((uint8_t)1) << shift );
  216. }
  217. #ifndef NUT_THREAD_AHDLCRXSTACK
  218. #define NUT_THREAD_AHDLCRXSTACK 512
  219. #endif
  220. #if !defined(MCU_AT90USB1287)
  221. /*
  222. * Handle AVR UART0 transmit complete interrupts.
  223. */
  224. static void Tx0Complete(void *arg)
  225. {
  226. AHDLCDCB *dcb = arg;
  227. if (dcb->dcb_tx_idx != dcb->dcb_wr_idx) {
  228. #ifdef UART0_CTS_BIT
  229. if (bit_is_set(UART0_CTS_PIN, UART0_CTS_BIT)) {
  230. cbi(UCR, UDRIE);
  231. return;
  232. }
  233. #endif
  234. outb(UDR, dcb->dcb_tx_buf[dcb->dcb_tx_idx]);
  235. dcb->dcb_tx_idx++;
  236. } else {
  237. cbi(UCR, UDRIE);
  238. NutEventPostFromIrq(&dcb->dcb_tx_rdy);
  239. }
  240. }
  241. #ifdef UART0_CTS_BIT
  242. /*
  243. * Handle AVR UART0 transmit handshake interrupts.
  244. */
  245. static void Cts0Interrupt(void *arg)
  246. {
  247. sbi(UCR, UDRIE);
  248. }
  249. #endif
  250. #endif /*!USB1287*/
  251. #ifdef __AVR_ENHANCED__
  252. /*
  253. * Handle AVR UART1 transmit complete interrupts.
  254. */
  255. static void Tx1Complete(void *arg)
  256. {
  257. register AHDLCDCB *dcb = arg;
  258. if (dcb->dcb_tx_idx != dcb->dcb_wr_idx) {
  259. #ifdef UART1_CTS_BIT
  260. if (bit_is_set(UART1_CTS_PIN, UART1_CTS_BIT)) {
  261. cbi(UCSR1B, UDRIE);
  262. return;
  263. }
  264. #endif
  265. outb(UDR1, dcb->dcb_tx_buf[dcb->dcb_tx_idx]);
  266. dcb->dcb_tx_idx++;
  267. } else {
  268. cbi(UCSR1B, UDRIE);
  269. NutEventPostFromIrq(&dcb->dcb_tx_rdy);
  270. }
  271. }
  272. #ifdef UART1_CTS_BIT
  273. /*
  274. * Handle AVR UART1 transmit handshake interrupts.
  275. */
  276. static void Cts1Interrupt(void *arg)
  277. {
  278. sbi(UCSR1B, UDRIE);
  279. }
  280. #endif
  281. #endif /* __AVR_ENHANCED__ */
  282. #if !defined(MCU_AT90USB1287)
  283. /*
  284. * Handle AVR UART0 receive complete interrupts.
  285. */
  286. static void Rx0Complete(void *arg)
  287. {
  288. AHDLCDCB *dcb = arg;
  289. dcb->dcb_rx_buf[dcb->dcb_rx_idx] = inb(UDR);
  290. if (dcb->dcb_rd_idx == dcb->dcb_rx_idx)
  291. NutEventPostFromIrq(&dcb->dcb_rx_rdy);
  292. /* Late increment fixes ICCAVR bug on volatile variables. */
  293. dcb->dcb_rx_idx++;
  294. }
  295. #endif /*!USB1287*/
  296. #ifdef __AVR_ENHANCED__
  297. /*
  298. * Handle AVR UART1 receive complete interrupts.
  299. */
  300. static void Rx1Complete(void *arg)
  301. {
  302. AHDLCDCB *dcb = arg;
  303. dcb->dcb_rx_buf[dcb->dcb_rx_idx] = inb(UDR1);
  304. if (dcb->dcb_rd_idx == dcb->dcb_rx_idx)
  305. NutEventPostFromIrq(&dcb->dcb_rx_rdy);
  306. /* Late increment fixes ICCAVR bug on volatile variables. */
  307. dcb->dcb_rx_idx++;
  308. }
  309. #endif /* __AVR_ENHANCED__ */
  310. /*
  311. * \return 0 on success, -1 in case of any errors.
  312. */
  313. static int SendRawByte(AHDLCDCB * dcb, uint8_t ch, uint8_t flush)
  314. {
  315. /*
  316. * If transmit buffer is full, wait until interrupt routine
  317. * signals an empty buffer or until a timeout occurs.
  318. */
  319. while ((uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
  320. if (NutEventWait(&dcb->dcb_tx_rdy, dcb->dcb_wtimeout))
  321. break;
  322. }
  323. /*
  324. * If transmit buffer is still full, we have a write timeout.
  325. */
  326. if ((uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
  327. return -1;
  328. }
  329. /*
  330. * Buffer has room for more data. Put the byte in the buffer
  331. * and increment the write index.
  332. */
  333. dcb->dcb_tx_buf[dcb->dcb_wr_idx] = ch;
  334. dcb->dcb_wr_idx++;
  335. /*
  336. * If transmit buffer has become full and the transmitter
  337. * is not active, then activate it.
  338. */
  339. if (flush || (uint8_t) (dcb->dcb_wr_idx + 1) == dcb->dcb_tx_idx) {
  340. /*
  341. * TODO: Check handshake.
  342. */
  343. NutEnterCritical();
  344. #ifdef __AVR_ENHANCED__
  345. if (dcb->dcb_base)
  346. sbi(UCSR1B, UDRIE);
  347. else
  348. #endif
  349. sbi(UCR, UDRIE);
  350. NutExitCritical();
  351. }
  352. return 0;
  353. }
  354. /*
  355. * Characters are properly escaped and checksum is updated.
  356. *
  357. * \return 0 on success, -1 in case of any errors.
  358. */
  359. static int SendHdlcData(AHDLCDCB * dcb, const uint8_t * data, uint16_t len, uint16_t * txfcs)
  360. {
  361. uint16_t tbx;
  362. register uint16_t fcs;
  363. if (txfcs)
  364. fcs = *txfcs;
  365. else
  366. fcs = 0;
  367. while (len) {
  368. tbx = (uint16_t) ((uint8_t) fcs ^ *data) << 1;
  369. fcs >>= 8;
  370. fcs ^= ((uint16_t) PRG_RDB(fcstab + tbx) << 8) | PRG_RDB(fcstab + tbx + 1);
  371. if (IN_ACC_MAP(*data, dcb->dcb_tx_accm) || *data == AHDLC_FLAG || *data == AHDLC_ESCAPE) {
  372. if (SendRawByte(dcb, AHDLC_ESCAPE, 0))
  373. return -1;
  374. if (SendRawByte(dcb, *data ^ AHDLC_TRANS, 0))
  375. return -1;
  376. } else if (SendRawByte(dcb, *data, 0))
  377. return -1;
  378. data++;
  379. len--;
  380. }
  381. if (txfcs)
  382. *txfcs = fcs;
  383. return 0;
  384. }
  385. /*!
  386. * \brief Send HDLC frame.
  387. *
  388. * \param dev Identifies the device to use.
  389. * \param nb Network buffer structure containing the packet to be sent.
  390. * The structure must have been allocated by a previous
  391. * call NutNetBufAlloc().
  392. *
  393. * \return 0 on success, -1 in case of any errors.
  394. */
  395. int AhdlcOutput(NUTDEVICE * dev, NETBUF * nb)
  396. {
  397. uint16_t txfcs;
  398. AHDLCDCB *dcb = dev->dev_dcb;
  399. uint16_t sz;
  400. /*
  401. * If we are in RAW mode we are not allowed to send AHDLC output.
  402. * We just emulate packet loss behaviour in here.
  403. */
  404. if (dcb->dcb_modeflags & UART_MF_RAWMODE) {
  405. return 0;
  406. }
  407. /*
  408. * Calculate the number of bytes to be send. Do not
  409. * send packets larger than transmit mru.
  410. */
  411. sz = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;
  412. if (sz > dcb->dcb_tx_mru) {
  413. return -1;
  414. }
  415. /*
  416. * TODO: If transmitter is running, we may omit the flag.
  417. */
  418. SendRawByte(dcb, AHDLC_FLAG, 0);
  419. /* Initialize the checksum and send the NETBUF. */
  420. txfcs = AHDLC_INITFCS;
  421. if (SendHdlcData(dcb, nb->nb_dl.vp, nb->nb_dl.sz, &txfcs))
  422. return -1;
  423. if (SendHdlcData(dcb, nb->nb_nw.vp, nb->nb_nw.sz, &txfcs))
  424. return -1;
  425. if (SendHdlcData(dcb, nb->nb_tp.vp, nb->nb_tp.sz, &txfcs))
  426. return -1;
  427. if (SendHdlcData(dcb, nb->nb_ap.vp, nb->nb_ap.sz, &txfcs))
  428. return -1;
  429. /* Send the checksum and the final flag. */
  430. txfcs ^= 0xffff;
  431. if (SendHdlcData(dcb, (uint8_t *) & txfcs, 2, 0))
  432. return -1;
  433. SendRawByte(dcb, AHDLC_FLAG, 1);
  434. return 0;
  435. }
  436. /*! \fn AhdlcRx(void *arg)
  437. * \brief Asynchronous HDLC receiver thread.
  438. *
  439. *
  440. * Running at high priority.
  441. */
  442. THREAD(AhdlcRx, arg)
  443. {
  444. NUTDEVICE *dev = arg;
  445. NUTDEVICE *netdev;
  446. AHDLCDCB *dcb = dev->dev_dcb;
  447. IFNET *ifn;
  448. NETBUF *nb;
  449. uint8_t *rxbuf;
  450. uint8_t *rxptr;
  451. uint16_t rxcnt;
  452. uint8_t ch;
  453. uint16_t tbx;
  454. uint8_t inframe;
  455. uint8_t escaped;
  456. uint16_t rxfcs;
  457. NutThreadSetPriority(9);
  458. for (;;) {
  459. /*
  460. * Reset variables to their initial state
  461. */
  462. rxptr = 0;
  463. rxcnt = 0;
  464. escaped = 0;
  465. rxfcs = AHDLC_INITFCS;
  466. inframe = 0;
  467. for (;;) {
  468. /*
  469. * Wait until the network interface has been attached.
  470. * This will be initiated by the application calling
  471. * NutNetIfConfig(), which in turn calls a HDLC_SETIFNET
  472. * ioctl() to store the NUTDEVICE pointer of the network
  473. * device in dev_icb and trigger an event on dcb_mf_evt.
  474. */
  475. while ((netdev = dev->dev_icb) == 0) {
  476. NutEventWait(&dcb->dcb_mf_evt, 1000);
  477. }
  478. ifn = netdev->dev_icb;
  479. dcb->dcb_rtimeout = 1000;
  480. inframe = 0;
  481. /*
  482. * Allocate the receive buffer, if this fails, we are in a
  483. * low memory situation. Take a nap and see, if the
  484. * situation improved.
  485. * Note that we also put the FCS into the receive buffer.
  486. */
  487. if ((rxbuf = NutHeapAlloc(dcb->dcb_rx_mru + 2)) != 0) {
  488. break;
  489. }
  490. NutSleep(1000);
  491. }
  492. /*
  493. * Signal the link driver that we are up.
  494. */
  495. ifn->if_send = AhdlcOutput;
  496. netdev->dev_ioctl(netdev, LCP_LOWERUP, 0);
  497. for (;;) {
  498. /*
  499. * If we are still connected to a network, fetch the next
  500. * character from the buffer.
  501. */
  502. while (dcb->dcb_rd_idx == dcb->dcb_rx_idx) {
  503. if (dev->dev_icb == 0)
  504. break;
  505. /* TODO: Check for idle timeout. */
  506. if (NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout)) {
  507. continue;
  508. }
  509. }
  510. /*
  511. * Leave loop if network interface is detached
  512. */
  513. if (dev->dev_icb == 0)
  514. break;
  515. /*
  516. * If RAW mode is active, we are not allowing any data encapsulation
  517. * processing. So we just sleep for a while.
  518. */
  519. if (dcb->dcb_modeflags & UART_MF_RAWMODE) {
  520. /*
  521. * It is a must to sleep here, because if we just yield it could create
  522. * too much processing in here and stall processing elsewhere. This gives
  523. * opportunity to other threads to process incoming data from USART.
  524. */
  525. NutSleep(100);
  526. continue;
  527. }
  528. /*
  529. * Read next character from input buffer
  530. */
  531. ch = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];
  532. if (inframe) {
  533. if (ch != AHDLC_FLAG) {
  534. if (ch == AHDLC_ESCAPE) {
  535. escaped = 1;
  536. continue;
  537. }
  538. if (escaped) {
  539. ch ^= AHDLC_TRANS;
  540. escaped = 0;
  541. }
  542. /*
  543. * Unless the peer lied to us about the negotiated MRU,
  544. * we should never get a frame which is too long. If it
  545. * happens, toss it away and grab the next incoming one.
  546. */
  547. if (rxcnt++ < dcb->dcb_rx_mru + 2) {
  548. /* Update calculated checksum and store character in buffer. */
  549. tbx = (uint16_t) ((uint8_t) rxfcs ^ ch) << 1;
  550. rxfcs >>= 8;
  551. rxfcs ^= ((uint16_t) PRG_RDB(fcstab + tbx) << 8) | PRG_RDB(fcstab + tbx + 1);
  552. *rxptr++ = ch;
  553. } else
  554. inframe = 0;
  555. continue;
  556. }
  557. if (rxcnt >= 2 && rxfcs == AHDLC_GOODFCS) {
  558. /*
  559. * If the frame checksum is valid, create a NETBUF
  560. * and pass it to the network specific receive handler.
  561. */
  562. rxcnt -= 2;
  563. if ((nb = NutNetBufAlloc(0, NBAF_DATALINK, rxcnt)) != 0) {
  564. memcpy(nb->nb_dl.vp, rxbuf, rxcnt);
  565. (*ifn->if_recv) (netdev, nb);
  566. }
  567. }
  568. }
  569. /*
  570. * If frame flag is received, resync frame processing
  571. */
  572. if (ch == AHDLC_FLAG) {
  573. inframe = 1;
  574. escaped = 0;
  575. rxptr = rxbuf;
  576. rxcnt = 0;
  577. rxfcs = AHDLC_INITFCS;
  578. }
  579. }
  580. /* Signal the link driver that we are down. */
  581. netdev->dev_ioctl(netdev, LCP_LOWERDOWN, 0);
  582. /* Disconnected, clean up. */
  583. if (rxbuf) {
  584. NutHeapFree(rxbuf);
  585. rxbuf = 0;
  586. }
  587. }
  588. }
  589. /*
  590. * \param dev Indicates the UART device.
  591. *
  592. * \return 0 on success, -1 otherwise.
  593. */
  594. static int AhdlcAvrGetStatus(NUTDEVICE * dev, uint32_t * status)
  595. {
  596. AHDLCDCB *dcb = dev->dev_dcb;
  597. uint8_t us;
  598. *status = 0;
  599. #ifdef __AVR_ENHANCED__
  600. if (dev->dev_base) {
  601. #ifdef UART1_CTS_BIT
  602. if (bit_is_set(UART1_CTS_PIN, UART1_CTS_BIT))
  603. *status |= UART_CTSDISABLED;
  604. else
  605. *status |= UART_CTSENABLED;
  606. #endif
  607. #ifdef UART1_RTS_BIT
  608. if (bit_is_set(UART1_RTS_PORT, UART1_RTS_BIT))
  609. *status |= UART_RTSDISABLED;
  610. else
  611. *status |= UART_RTSENABLED;
  612. #endif
  613. #ifdef UART1_DTR_BIT
  614. if (bit_is_set(UART1_DTR_PORT, UART1_DTR_BIT))
  615. *status |= UART_DTRDISABLED;
  616. else
  617. *status |= UART_DTRENABLED;
  618. #endif
  619. us = inb(UCSR1A);
  620. } else
  621. #endif /* __AVR_ENHANCED__ */
  622. {
  623. #ifdef UART0_CTS_BIT
  624. if (bit_is_set(UART0_CTS_PIN, UART0_CTS_BIT))
  625. *status |= UART_CTSDISABLED;
  626. else
  627. *status |= UART_CTSENABLED;
  628. #endif
  629. #ifdef UART0_RTS_BIT
  630. if (bit_is_set(UART0_RTS_PORT, UART0_RTS_BIT))
  631. *status |= UART_RTSDISABLED;
  632. else
  633. *status |= UART_RTSENABLED;
  634. #endif
  635. #ifdef UART0_DTR_BIT
  636. if (bit_is_set(UART0_DTR_PORT, UART0_DTR_BIT))
  637. *status |= UART_DTRDISABLED;
  638. else
  639. *status |= UART_DTRENABLED;
  640. #endif
  641. us = inb(USR);
  642. }
  643. if (us & FE)
  644. *status |= UART_FRAMINGERROR;
  645. if (us & DOR)
  646. *status |= UART_OVERRUNERROR;
  647. if (dcb->dcb_tx_idx == dcb->dcb_wr_idx)
  648. *status |= UART_TXBUFFEREMPTY;
  649. if (dcb->dcb_rd_idx == dcb->dcb_rx_idx)
  650. *status |= UART_RXBUFFEREMPTY;
  651. return 0;
  652. }
  653. /*
  654. * \param dev Indicates the UART device.
  655. *
  656. * \return 0 on success, -1 otherwise.
  657. */
  658. static int AhdlcAvrSetStatus(NUTDEVICE * dev, uint32_t status)
  659. {
  660. #ifdef __AVR_ENHANCED__
  661. if (dev->dev_base) {
  662. #ifdef UART1_RTS_BIT
  663. if (status & UART_RTSDISABLED)
  664. sbi(UART1_RTS_PORT, UART1_RTS_BIT);
  665. else if (status & UART_RTSENABLED)
  666. cbi(UART1_RTS_PORT, UART1_RTS_BIT);
  667. #endif
  668. #ifdef UART1_DTR_BIT
  669. if (status & UART_DTRDISABLED)
  670. sbi(UART1_DTR_PORT, UART1_DTR_BIT);
  671. else if (status & UART_DTRENABLED)
  672. cbi(UART1_DTR_PORT, UART1_DTR_BIT);
  673. #endif
  674. } else
  675. #endif /* __AVR_ENHANCED__ */
  676. {
  677. #ifdef UART0_RTS_BIT
  678. if (status & UART_RTSDISABLED)
  679. sbi(UART0_RTS_PORT, UART0_RTS_BIT);
  680. else if (status & UART_RTSENABLED)
  681. cbi(UART0_RTS_PORT, UART0_RTS_BIT);
  682. #endif
  683. #ifdef UART0_DTR_BIT
  684. if (status & UART_DTRDISABLED)
  685. sbi(UART0_DTR_PORT, UART0_DTR_BIT);
  686. else if (status & UART_DTRENABLED)
  687. cbi(UART0_DTR_PORT, UART0_DTR_BIT);
  688. #endif
  689. }
  690. return 0;
  691. }
  692. /*
  693. * Carefully enable UART functions.
  694. */
  695. static void AhdlcAvrEnable(uint16_t base)
  696. {
  697. NutEnterCritical();
  698. #ifdef __AVR_ENHANCED__
  699. if (base) {
  700. #ifdef UART1_CTS_BIT
  701. sbi(EIMSK, UART1_CTS_BIT);
  702. #endif
  703. outb(UCSR1B, BV(RXCIE) | BV(RXEN) | BV(TXEN));
  704. } else
  705. #endif /* __AVR_ENHANCED__ */
  706. {
  707. #ifdef UART0_CTS_BIT
  708. sbi(EIMSK, UART0_CTS_BIT);
  709. #endif
  710. outb(UCR, BV(RXCIE) | BV(RXEN) | BV(TXEN));
  711. }
  712. NutExitCritical();
  713. }
  714. /*
  715. * Carefully disable UART functions.
  716. */
  717. static void AhdlcAvrDisable(uint16_t base)
  718. {
  719. /*
  720. * Disable UART interrupts.
  721. */
  722. NutEnterCritical();
  723. #ifdef __AVR_ENHANCED__
  724. if (base) {
  725. #ifdef UART1_CTS_BIT
  726. cbi(EIMSK, UART1_CTS_BIT);
  727. #endif
  728. outb(UCSR1B, inb(UCSR1B) & ~(BV(RXCIE) | BV(UDRIE)));
  729. } else
  730. #endif /* __AVR_ENHANCED__ */
  731. {
  732. #ifdef UART0_CTS_BIT
  733. cbi(EIMSK, UART0_CTS_BIT);
  734. #endif
  735. outb(UCR, inb(UCR) & ~(BV(RXCIE) | BV(UDRIE)));
  736. }
  737. NutExitCritical();
  738. /*
  739. * Allow incoming or outgoing character to finish.
  740. */
  741. NutDelay(10);
  742. /*
  743. * Now disable UART functions.
  744. */
  745. #ifdef __AVR_ENHANCED__
  746. if (base)
  747. outb(UCSR1B, inb(UCSR1B) & ~(BV(RXEN) | BV(TXEN)));
  748. else
  749. #endif /* __AVR_ENHANCED__ */
  750. outb(UCR, inb(UCR) & ~(BV(RXEN) | BV(TXEN)));
  751. }
  752. /*!
  753. * \brief Perform on-chip UART control functions.
  754. *
  755. * \param dev Identifies the device that receives the device-control
  756. * function.
  757. * \param req Requested control function. May be set to one of the
  758. * following constants:
  759. * - UART_SETSPEED, conf points to an uint32_t value containing the baudrate.
  760. * - UART_GETSPEED, conf points to an uint32_t value receiving the current baudrate.
  761. * - UART_SETDATABITS, conf points to an uint32_t value containing the number of data bits, 5, 6, 7 or 8.
  762. * - UART_GETDATABITS, conf points to an uint32_t value receiving the number of data bits, 5, 6, 7 or 8.
  763. * - UART_SETPARITY, conf points to an uint32_t value containing the parity, 0 (no), 1 (odd) or 2 (even).
  764. * - UART_GETPARITY, conf points to an uint32_t value receiving the parity, 0 (no), 1 (odd) or 2 (even).
  765. * - UART_SETSTOPBITS, conf points to an uint32_t value containing the number of stop bits 1 or 2.
  766. * - UART_GETSTOPBITS, conf points to an uint32_t value receiving the number of stop bits 1 or 2.
  767. * - UART_SETSTATUS, conf points to an uint32_t value containing the changes for the control lines.
  768. * - UART_GETSTATUS, conf points to an uint32_t value receiving the state of the control lines and the device.
  769. * - UART_SETREADTIMEOUT, conf points to an uint32_t value containing the read timeout.
  770. * - UART_GETREADTIMEOUT, conf points to an uint32_t value receiving the read timeout.
  771. * - UART_SETWRITETIMEOUT, conf points to an uint32_t value containing the write timeout.
  772. * - UART_GETWRITETIMEOUT, conf points to an uint32_t value receiving the write timeout.
  773. * - UART_SETLOCALECHO, conf points to an uint32_t value containing 0 (off) or 1 (on).
  774. * - UART_GETLOCALECHO, conf points to an uint32_t value receiving 0 (off) or 1 (on).
  775. * - UART_SETFLOWCONTROL, conf points to an uint32_t value containing combined UART_FCTL_ values.
  776. * - UART_GETFLOWCONTROL, conf points to an uint32_t value containing receiving UART_FCTL_ values.
  777. * - UART_SETCOOKEDMODE, conf points to an uint32_t value containing 0 (off) or 1 (on).
  778. * - UART_GETCOOKEDMODE, conf points to an uint32_t value receiving 0 (off) or 1 (on).
  779. * - UART_SETRAWMODE, conf points to an uint32_t value containing 0 (off) or 1 (on).
  780. * - UART_GETRAWMODE, conf points to an uint32_t value receiving 0 (off) or 1 (on).
  781. * - HDLC_SETIFNET, conf points to a pointer containing the address of the network device's NUTDEVICE structure.
  782. * - HDLC_GETIFNET, conf points to a pointer receiving the address of the network device's NUTDEVICE structure.
  783. * - HDLC_SETTXACCM, conf points to an uint32_t value containing the ACC Map in host endian.
  784. * - HDLC_GETTXACCM, conf points to an uint32_t value receiving the ACC Map in host endian.
  785. *
  786. * \param conf Points to a buffer that contains any data required for
  787. * the given control function or receives data from that
  788. * function.
  789. * \return 0 on success, -1 otherwise.
  790. *
  791. * \warning Timeout values are given in milliseconds and are limited to
  792. * the granularity of the system timer.
  793. *
  794. * \note For ATmega103, only 8 data bits, 1 stop bit and no parity are allowed.
  795. *
  796. */
  797. int AhdlcAvrIOCtl(NUTDEVICE * dev, int req, void *conf)
  798. {
  799. int rc = 0;
  800. AHDLCDCB *dcb;
  801. void **ppv = (void **) conf;
  802. uint32_t *lvp = (uint32_t *) conf;
  803. uint8_t bv = 0;
  804. uint16_t sv = 0;
  805. uint8_t devnum;
  806. #if !defined(MCU_AT90USB1287)
  807. if (dev == 0)
  808. dev = &devUart0;
  809. #else
  810. if (dev == 0)
  811. return -1;
  812. #endif
  813. devnum = dev->dev_base;
  814. dcb = dev->dev_dcb;
  815. switch (req) {
  816. case UART_SETSPEED:
  817. AhdlcAvrDisable(devnum);
  818. sv = (uint16_t) ((((2UL * NutGetCpuClock()) / (*lvp * 16UL)) + 1UL) / 2UL) - 1;
  819. #ifdef __AVR_ENHANCED__
  820. if (devnum) {
  821. outb(UBRR1L, (uint8_t) sv);
  822. outb(UBRR1H, (uint8_t) (sv >> 8));
  823. #if !defined(MCU_AT90USB1287)
  824. } else {
  825. outb(UBRR0L, (uint8_t) sv);
  826. outb(UBRR0H, (uint8_t) (sv >> 8));
  827. #endif
  828. }
  829. #else
  830. outb(UBRR, (uint8_t) sv);
  831. #endif
  832. AhdlcAvrEnable(devnum);
  833. break;
  834. case UART_GETSPEED:
  835. #ifdef __AVR_ENHANCED__
  836. if (devnum)
  837. sv = (uint16_t) inb(UBRR1H) << 8 | inb(UBRR1L);
  838. #if !defined(MCU_AT90USB1287)
  839. else
  840. sv = (uint16_t) inb(UBRR0H) << 8 | inb(UBRR0L);
  841. #endif
  842. #else
  843. sv = inb(UBRR);
  844. #endif
  845. *lvp = NutGetCpuClock() / (16UL * (uint32_t) (sv + 1));
  846. break;
  847. case UART_SETDATABITS:
  848. AhdlcAvrDisable(devnum);
  849. bv = (uint8_t)(*lvp);
  850. #ifdef __AVR_ENHANCED__
  851. if (bv >= 5 && bv <= 8) {
  852. bv = (bv - 5) << 1;
  853. if (devnum) {
  854. outb(UCSR1C, (inb(UCSR1C) & 0xF9) | bv);
  855. outb(UCSR1B, inb(UCSR1B) & 0xFB);
  856. #if !defined(MCU_AT90USB1287)
  857. } else {
  858. outb(UCSR0C, (inb(UCSR0C) & 0xF9) | bv);
  859. outb(UCSR0B, inb(UCSR0B) & 0xFB);
  860. #endif
  861. }
  862. } else
  863. rc = -1;
  864. #else
  865. if (bv != 8)
  866. rc = -1;
  867. #endif
  868. AhdlcAvrEnable(devnum);
  869. break;
  870. case UART_GETDATABITS:
  871. #ifdef __AVR_ENHANCED__
  872. if (devnum)
  873. *lvp = ((inb(UCSR1C) & 0x06) >> 1) + 5;
  874. #if !defined(MCU_AT90USB1287)
  875. else
  876. *lvp = ((inb(UCSR0C) & 0x06) >> 1) + 5;
  877. #endif
  878. #else
  879. *lvp = 8;
  880. #endif
  881. break;
  882. case UART_SETPARITY:
  883. AhdlcAvrDisable(devnum);
  884. bv = (uint8_t)(*lvp);
  885. #ifdef __AVR_ENHANCED__
  886. if (bv <= 2) {
  887. if (bv == 1)
  888. bv = 3;
  889. bv <<= 4;
  890. if (devnum)
  891. outb(UCSR1C, (inb(UCSR1C) & 0xCF) | bv);
  892. #if !defined(MCU_AT90USB1287)
  893. else
  894. outb(UCSR0C, (inb(UCSR0C) & 0xCF) | bv);
  895. #endif
  896. } else
  897. rc = -1;
  898. #endif
  899. if (bv)
  900. rc = -1;
  901. AhdlcAvrEnable(devnum);
  902. break;
  903. case UART_GETPARITY:
  904. #ifdef __AVR_ENHANCED__
  905. if (devnum)
  906. bv = (inb(UCSR1C) & 0x30) >> 4;
  907. #if !defined(MCU_AT90USB1287)
  908. else
  909. bv = (inb(UCSR0C) & 0x30) >> 4;
  910. #endif
  911. if (bv == 3)
  912. bv = 1;
  913. #else
  914. bv = 0;
  915. #endif
  916. *lvp = bv;
  917. break;
  918. case UART_SETSTOPBITS:
  919. AhdlcAvrDisable(devnum);
  920. bv = (uint8_t)(*lvp);
  921. #ifdef __AVR_ENHANCED__
  922. if (bv == 1 || bv == 2) {
  923. bv = (bv - 1) << 3;
  924. if (devnum)
  925. outb(UCSR1C, (inb(UCSR1C) & 0xF7) | bv);
  926. #if !defined(MCU_AT90USB1287)
  927. else
  928. outb(UCSR0C, (inb(UCSR0C) & 0xF7) | bv);
  929. #endif
  930. } else
  931. rc = -1;
  932. #else
  933. if (bv != 1)
  934. rc = -1;
  935. #endif
  936. AhdlcAvrEnable(devnum);
  937. break;
  938. case UART_GETSTOPBITS:
  939. #ifdef __AVR_ENHANCED__
  940. if (devnum)
  941. *lvp = ((inb(UCSR1C) & 0x08) >> 3) + 1;
  942. #if !defined(MCU_AT90USB1287)
  943. else
  944. *lvp = ((inb(UCSR0C) & 0x08) >> 3) + 1;
  945. #endif
  946. #else
  947. *lvp = 1;
  948. #endif
  949. break;
  950. case UART_GETSTATUS:
  951. AhdlcAvrGetStatus(dev, lvp);
  952. break;
  953. case UART_SETSTATUS:
  954. AhdlcAvrSetStatus(dev, *lvp);
  955. break;
  956. case UART_SETREADTIMEOUT:
  957. dcb->dcb_rtimeout = *lvp;
  958. break;
  959. case UART_GETREADTIMEOUT:
  960. *lvp = dcb->dcb_rtimeout;
  961. break;
  962. case UART_SETWRITETIMEOUT:
  963. dcb->dcb_wtimeout = *lvp;
  964. break;
  965. case UART_GETWRITETIMEOUT:
  966. *lvp = dcb->dcb_wtimeout;
  967. break;
  968. case UART_SETLOCALECHO:
  969. bv = (uint8_t)(*lvp);
  970. if (bv)
  971. dcb->dcb_modeflags |= UART_MF_LOCALECHO;
  972. else
  973. dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
  974. break;
  975. case UART_GETLOCALECHO:
  976. if (dcb->dcb_modeflags & UART_MF_LOCALECHO)
  977. *lvp = 1;
  978. else
  979. *lvp = 0;
  980. break;
  981. case UART_SETFLOWCONTROL:
  982. bv = (uint8_t)(*lvp);
  983. if (bv)
  984. dcb->dcb_modeflags |= UART_MF_LOCALECHO;
  985. else
  986. dcb->dcb_modeflags &= ~UART_MF_LOCALECHO;
  987. break;
  988. case UART_GETFLOWCONTROL:
  989. break;
  990. case UART_SETRAWMODE:
  991. bv = (uint8_t)(*lvp);
  992. if (bv)
  993. dcb->dcb_modeflags |= UART_MF_RAWMODE;
  994. else
  995. dcb->dcb_modeflags &= ~UART_MF_RAWMODE;
  996. break;
  997. case UART_GETRAWMODE:
  998. if (dcb->dcb_modeflags & UART_MF_RAWMODE)
  999. *lvp = 1;
  1000. else
  1001. *lvp = 0;
  1002. break;
  1003. case HDLC_SETIFNET:
  1004. if (ppv && (*ppv != 0)) {
  1005. dev->dev_icb = *ppv;
  1006. dev->dev_type = IFTYP_NET;
  1007. dcb->dcb_rx_mru = dcb->dcb_tx_mru = ((IFNET *)(((NUTDEVICE *)ppv)->dev_icb))->if_mtu;
  1008. NutEventPost(&dcb->dcb_mf_evt);
  1009. } else {
  1010. dev->dev_type = IFTYP_CHAR;
  1011. if (dev->dev_icb != 0)
  1012. {
  1013. dev->dev_icb = 0;
  1014. /*
  1015. * Signal AHDLC Thread, so it can change it's state instantly
  1016. */
  1017. NutEventPost(&dcb->dcb_rx_rdy);
  1018. }
  1019. }
  1020. break;
  1021. case HDLC_GETIFNET:
  1022. *ppv = dev->dev_icb;
  1023. break;
  1024. /* AVR host endian is little endian, and the ACCM should have been switched
  1025. * to host endian when the value was read in. */
  1026. case HDLC_SETTXACCM:
  1027. dcb->dcb_tx_accm = (*lvp);
  1028. break;
  1029. case HDLC_GETTXACCM:
  1030. (*lvp) = dcb->dcb_tx_accm;
  1031. break;
  1032. default:
  1033. rc = -1;
  1034. break;
  1035. }
  1036. return rc;
  1037. }
  1038. /*!
  1039. * \brief Initialize asynchronous HDLC device.
  1040. *
  1041. * This function will be called during device registration. It
  1042. * initializes the hardware, registers all required interrupt
  1043. * handlers and initializes all internal data structures used by
  1044. * this driver.
  1045. *
  1046. * \param dev Identifies the device to initialize.
  1047. *
  1048. * \return 0 on success, -1 otherwise.
  1049. */
  1050. int AhdlcAvrInit(NUTDEVICE * dev)
  1051. {
  1052. int rc = 0;
  1053. AHDLCDCB *dcb;
  1054. uint32_t baudrate = 9600;
  1055. /* Disable UART. */
  1056. AhdlcAvrDisable(dev->dev_base);
  1057. /* Initialize driver control block. */
  1058. dcb = dev->dev_dcb;
  1059. memset(dcb, 0, sizeof(AHDLCDCB));
  1060. dcb->dcb_base = dev->dev_base;
  1061. dcb->dcb_rx_buf = NutHeapAlloc(256);
  1062. dcb->dcb_tx_buf = NutHeapAlloc(256);
  1063. dcb->dcb_rx_mru = dcb->dcb_tx_mru = ((IFNET *)dev->dev_icb)->if_mtu;
  1064. dcb->dcb_tx_accm = 0xFFFFFFFF;
  1065. /*
  1066. * Initialize UART handshake hardware and register interrupt handlers.
  1067. */
  1068. if (dev->dev_base) {
  1069. #ifdef __AVR_ENHANCED__
  1070. #ifdef UART1_CTS_BIT
  1071. sbi(UART1_CTS_PORT, UART1_CTS_BIT);
  1072. cbi(UART1_CTS_DDR, UART1_CTS_BIT);
  1073. /* Falling edge will generate interrupts. */
  1074. #if UART1_CTS_BIT == 4
  1075. sbi(EICR, 1);
  1076. #elif UART1_CTS_BIT == 5
  1077. sbi(EICR, 3);
  1078. #elif UART1_CTS_BIT == 6
  1079. sbi(EICR, 5);
  1080. #elif UART1_CTS_BIT == 7
  1081. sbi(EICR, 7);
  1082. #endif
  1083. #endif
  1084. #ifdef UART1_RTS_BIT
  1085. sbi(UART1_RTS_PORT, UART1_RTS_BIT);
  1086. sbi(UART1_RTS_DDR, UART1_RTS_BIT);
  1087. #endif
  1088. #ifdef UART1_DTR_BIT
  1089. sbi(UART1_DTR_PORT, UART1_DTR_BIT);
  1090. sbi(UART1_DTR_DDR, UART1_DTR_BIT);
  1091. #endif
  1092. if (NutRegisterIrqHandler(&sig_UART1_RECV, Rx1Complete, dcb))
  1093. rc = -1;
  1094. else if (NutRegisterIrqHandler(&sig_UART1_DATA, Tx1Complete, dcb))
  1095. #ifdef UART1_CTS_BIT
  1096. rc = -1;
  1097. else if (NutRegisterIrqHandler(&UART1_CTS_SIGNAL, Cts1Interrupt, dev))
  1098. #endif
  1099. #endif /* __AVR_ENHANCED__ */
  1100. rc = -1;
  1101. } else {
  1102. #if defined(MCU_AT90USB1287)
  1103. rc = -1;
  1104. #else
  1105. #ifdef UART0_CTS_BIT
  1106. sbi(UART0_CTS_PORT, UART0_CTS_BIT);
  1107. cbi(UART0_CTS_DDR, UART0_CTS_BIT);
  1108. #if UART0_CTS_BIT == 4
  1109. sbi(EICR, 1);
  1110. #elif UART0_CTS_BIT == 5
  1111. sbi(EICR, 3);
  1112. #elif UART0_CTS_BIT == 6
  1113. sbi(EICR, 5);
  1114. #elif UART0_CTS_BIT == 7
  1115. sbi(EICR, 7);
  1116. #endif
  1117. #endif
  1118. #ifdef UART0_RTS_BIT
  1119. sbi(UART0_RTS_PORT, UART0_RTS_BIT);
  1120. sbi(UART0_RTS_DDR, UART0_RTS_BIT);
  1121. #endif
  1122. #ifdef UART0_DTR_BIT
  1123. sbi(UART0_DTR_PORT, UART0_DTR_BIT);
  1124. sbi(UART0_DTR_DDR, UART0_DTR_BIT);
  1125. #endif
  1126. if (NutRegisterIrqHandler(&sig_UART0_RECV, Rx0Complete, dcb))
  1127. rc = -1;
  1128. else if (NutRegisterIrqHandler(&sig_UART0_DATA, Tx0Complete, dcb))
  1129. rc = -1;
  1130. #ifdef UART0_CTS_BIT
  1131. else if (NutRegisterIrqHandler(&UART0_CTS_SIGNAL, Cts0Interrupt, dev))
  1132. rc = -1;
  1133. #endif
  1134. #endif
  1135. }
  1136. /*
  1137. * If we have been successful so far, start the HDLC receiver thread,
  1138. * set the initial baudrate and enable the UART.
  1139. */
  1140. if (rc == 0 && NutThreadCreate("ahdlcrx", AhdlcRx, dev,
  1141. (NUT_THREAD_AHDLCRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD)) {
  1142. AhdlcAvrIOCtl(dev, UART_SETSPEED, &baudrate);
  1143. return 0;
  1144. }
  1145. /* We failed, clean up. */
  1146. if (dcb->dcb_rx_buf)
  1147. NutHeapFree((void *) dcb->dcb_rx_buf);
  1148. if (dcb->dcb_tx_buf)
  1149. NutHeapFree((void *) dcb->dcb_tx_buf);
  1150. return -1;
  1151. }
  1152. /*!
  1153. * \brief Read from the asynchronous HDLC device.
  1154. *
  1155. * This function is called by the low level input routines of the
  1156. * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_read
  1157. * entry.
  1158. *
  1159. * The function may block the calling thread until at least one
  1160. * character has been received or a timeout occurs.
  1161. *
  1162. * It is recommended to set a proper read timeout with software handshake.
  1163. * In this case a timeout may occur, if the communication peer lost our
  1164. * last XON character. The application may then use ioctl() to disable the
  1165. * receiver and do the read again. This will send out another XON.
  1166. *
  1167. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a
  1168. * previous call to AhdlcOpen().
  1169. * \param buffer Pointer to the buffer that receives the data. If zero,
  1170. * then all characters in the input buffer will be
  1171. * removed.
  1172. * \param size Maximum number of bytes to read.
  1173. *
  1174. * \return The number of bytes read, which may be less than the number
  1175. * of bytes specified. A return value of -1 indicates an error,
  1176. * while zero is returned in case of a timeout.
  1177. */
  1178. int AhdlcAvrRead(NUTFILE * fp, void *buffer, int size)
  1179. {
  1180. int rc = 0;
  1181. AHDLCDCB *dcb = fp->nf_dev->dev_dcb;
  1182. uint8_t *cp = buffer;
  1183. /*
  1184. * Get characters from receive buffer.
  1185. */
  1186. if (buffer) {
  1187. while (rc < size) {
  1188. if (dcb->dcb_rd_idx != dcb->dcb_rx_idx) {
  1189. *cp++ = dcb->dcb_rx_buf[dcb->dcb_rd_idx++];
  1190. rc++;
  1191. } else if (rc || NutEventWait(&dcb->dcb_rx_rdy, dcb->dcb_rtimeout))
  1192. break;
  1193. }
  1194. }
  1195. /*
  1196. * Call without data buffer discards receive buffer.
  1197. */
  1198. else
  1199. dcb->dcb_rd_idx = dcb->dcb_rx_idx;
  1200. return rc;
  1201. }
  1202. /*!
  1203. * \brief Write to the asynchronous HDLC device.
  1204. *
  1205. * \param dev Pointer to a previously registered NUTDEVICE structure.
  1206. * \param buffer Pointer the data to write.
  1207. * \param len Number of data bytes to write.
  1208. * \param pflg If this flag is set, then the buffer is located in program
  1209. * space.
  1210. *
  1211. * \return The number of bytes written. In case of a write timeout, this
  1212. * may be less than the specified length.
  1213. */
  1214. int AhdlcAvrPut(NUTDEVICE * dev, const void *buffer, int len, int pflg)
  1215. {
  1216. int rc = 0;
  1217. AHDLCDCB *dcb = dev->dev_dcb;
  1218. const uint8_t *cp = buffer;
  1219. /*
  1220. * Put characters in transmit buffer.
  1221. */
  1222. if (buffer) {
  1223. while (rc < len) {
  1224. if (SendRawByte(dcb, pflg ? PRG_RDB(cp) : *cp, 0))
  1225. break;
  1226. cp++;
  1227. rc++;
  1228. }
  1229. }
  1230. /*
  1231. * Call without data pointer starts transmission.
  1232. */
  1233. else {
  1234. /*
  1235. * TODO: Check handshake.
  1236. */
  1237. #ifdef __AVR_ENHANCED__
  1238. if (dev->dev_base)
  1239. sbi(UCSR1B, UDRIE);
  1240. else
  1241. #endif
  1242. sbi(UCR, UDRIE);
  1243. }
  1244. return rc;
  1245. }
  1246. /*!
  1247. * \brief Write to the asynchronous HDLC device.
  1248. *
  1249. * This function is called by the low level output routines of the
  1250. * \ref xrCrtLowio "C runtime library", using the
  1251. * \ref _NUTDEVICE::dev_write entry.
  1252. *
  1253. * The function may block the calling thread.
  1254. *
  1255. * \param fp Pointer to a _NUTFILE structure, obtained by a previous
  1256. * call to AhldcOpen().
  1257. * \param buffer Pointer to the data to be written. If zero, then the
  1258. * output buffer will be flushed.
  1259. * \param len Number of bytes to write.
  1260. *
  1261. * \return The number of bytes written, which may be less than the number
  1262. * of bytes specified if a timeout occured. A return value of -1
  1263. * indicates an error.
  1264. */
  1265. int AhdlcAvrWrite(NUTFILE * fp, const void *buffer, int len)
  1266. {
  1267. return AhdlcAvrPut(fp->nf_dev, buffer, len, 0);
  1268. }
  1269. /*!
  1270. * \brief Write to the asynchronous HDLC device.
  1271. *
  1272. * Similar to AhdlcWrite() except that the data is located in program
  1273. * memory.
  1274. *
  1275. * This function is called by the low level output routines of the
  1276. * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_write_P
  1277. * entry.
  1278. *
  1279. * The function may block the calling thread.
  1280. *
  1281. * \param fp Pointer to a NUTFILE structure, obtained by a previous
  1282. * call to AhdlcOpen().
  1283. * \param buffer Pointer to the data in program space to be written.
  1284. * \param len Number of bytes to write.
  1285. *
  1286. * \return The number of bytes written, which may be less than the number
  1287. * of bytes specified if a timeout occured. A return value of -1
  1288. * indicates an error.
  1289. */
  1290. int AhdlcAvrWrite_P(NUTFILE * fp, PGM_P buffer, int len)
  1291. {
  1292. return AhdlcAvrPut(fp->nf_dev, (const char *) buffer, len, 1);
  1293. }
  1294. /*!
  1295. * \brief Open the asynchronous HDLC device.
  1296. *
  1297. * This function is called by the low level open routine of the C runtime
  1298. * library, using the _NUTDEVICE::dev_open entry.
  1299. *
  1300. * \param dev Pointer to the NUTDEVICE structure.
  1301. * \param name Ignored, should point to an empty string.
  1302. * \param mode Operation mode. Any of the following values may be or-ed:
  1303. * - \ref _O_BINARY
  1304. * - \ref _O_RDONLY
  1305. * - \ref _O_WRONLY
  1306. * \param acc Ignored, should be zero.
  1307. *
  1308. * \return Pointer to a NUTFILE structure if successful or NUTFILE_EOF otherwise.
  1309. */
  1310. NUTFILE *AhdlcAvrOpen(NUTDEVICE * dev, const char *name, int mode, int acc)
  1311. {
  1312. NUTFILE *fp;
  1313. if ((fp = NutHeapAlloc(sizeof(NUTFILE))) == 0)
  1314. return NUTFILE_EOF;
  1315. fp->nf_dev = dev;
  1316. fp->nf_fcb = NULL;
  1317. /* Enable handshake outputs. */
  1318. #ifdef __AVR_ENHANCED__
  1319. if (dev->dev_base) {
  1320. #ifdef UART1_RTS_BIT
  1321. cbi(UART1_RTS_PORT, UART1_RTS_BIT);
  1322. #endif
  1323. #ifdef UART1_DTR_BIT
  1324. cbi(UART1_DTR_PORT, UART1_DTR_BIT);
  1325. #endif
  1326. } else
  1327. #endif /* __AVR_ENHANCED__ */
  1328. {
  1329. #ifdef UART0_RTS_BIT
  1330. cbi(UART0_RTS_PORT, UART0_RTS_BIT);
  1331. #endif
  1332. #ifdef UART0_DTR_BIT
  1333. cbi(UART0_DTR_PORT, UART0_DTR_BIT);
  1334. #endif
  1335. }
  1336. return fp;
  1337. }
  1338. /*!
  1339. * \brief Close the asynchronous HDLC device.
  1340. *
  1341. * This function is called by the low level close routine of the C runtime
  1342. * library, using the _NUTDEVICE::dev_close entry.
  1343. *
  1344. * \param fp Pointer to a _NUTFILE structure, obtained by a previous call
  1345. * to UsartOpen().
  1346. *
  1347. * \return 0 on success or -1 otherwise.
  1348. *
  1349. * \todo We may support shared open and use dev_irq as an open counter.
  1350. */
  1351. int AhdlcAvrClose(NUTFILE * fp)
  1352. {
  1353. if (fp && fp != NUTFILE_EOF) {
  1354. /* Disable handshake outputs. */
  1355. #ifdef __AVR_ENHANCED__
  1356. if (fp->nf_dev->dev_base) {
  1357. #ifdef UART1_RTS_BIT
  1358. sbi(UART1_RTS_PORT, UART1_RTS_BIT);
  1359. #endif
  1360. #ifdef UART1_DTR_BIT
  1361. sbi(UART1_DTR_PORT, UART1_DTR_BIT);
  1362. #endif
  1363. } else
  1364. #endif /* __AVR_ENHANCED__ */
  1365. {
  1366. #ifdef UART0_RTS_BIT
  1367. sbi(UART0_RTS_PORT, UART0_RTS_BIT);
  1368. #endif
  1369. #ifdef UART0_DTR_BIT
  1370. sbi(UART0_DTR_PORT, UART0_DTR_BIT);
  1371. #endif
  1372. }
  1373. NutHeapFree(fp);
  1374. return 0;
  1375. }
  1376. return -1;
  1377. }
  1378. /*@}*/