usartsc16is752.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426
  1. /*
  2. * Copyright (C) 2010 by Ulrich Prinz (uprinz2@netscape.net)
  3. * Copyright (C) 2009 by Rittal GmbH & Co. KG. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the copyright holders nor the names of
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  22. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  25. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  26. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  27. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  28. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * For additional information see http://www.ethernut.de/
  32. *
  33. */
  34. /*
  35. * $Log$
  36. *
  37. * Revision 1.0 2009/04/13 ulrichprinz
  38. * First checkin, new twi driver for SC16IS752 dual usart chip
  39. * (currently SAM7X256 is tested only)
  40. *
  41. */
  42. // #define PRINT_DEBUG
  43. #if defined (PRINT_DEBUG)
  44. #include <stdio.h>
  45. /*
  46. #define MYPRINT(fmt, ...) printf ("%s:%s(%d)\t" fmt "\n", \
  47. __FILE__,__FUNCTION__,__LINE__, ##__VA_ARGS__);
  48. */
  49. #define MYPRINT(fmt, ...) printf ("%s(%d)\t" fmt "\n", \
  50. __FUNCTION__,__LINE__, ##__VA_ARGS__);
  51. #else
  52. #define MYPRINT(fmt, ...)
  53. #endif
  54. // #include <assert.h>
  55. #include <cfg/clock.h>
  56. #include <sys/atom.h>
  57. #include <sys/event.h>
  58. #include <sys/timer.h>
  59. #include <dev/irqreg.h>
  60. #include <dev/usartsc16is752.h>
  61. #include <dev/twif.h>
  62. /*!
  63. * \addtogroup xgNutArchArmAt91Us
  64. */
  65. /*@{*/
  66. #ifdef US_OVRE
  67. #undef US_OVRE
  68. #endif
  69. #define US_OVRE 0x00000020 /*!< \brief Overrun error */
  70. /* \brief ASCII code for software flow control, starts transmitter. */
  71. #define ASCII_XON 0x11
  72. /* \brief ASCII code for software flow control, stops transmitter. */
  73. #define ASCII_XOFF 0x13
  74. /* \brief XON transmit pending flag. */
  75. #define XON_PENDING 0x10
  76. /* \brief XOFF transmit pending flag. */
  77. #define XOFF_PENDING 0x20
  78. /* \brief XOFF sent flag. */
  79. #define XOFF_SENT 0x40
  80. /* \brief XOFF received flag. */
  81. #define XOFF_RCVD 0x80
  82. int Sc16is752RegWrite(uint8_t dev, uint8_t ch, uint8_t reg, uint8_t val);
  83. int Sc16is752RegRead(uint8_t dev, uint8_t ch, uint8_t reg, uint8_t *val);
  84. static int setBaudrate(uint8_t dev, uint8_t ch, int baud);
  85. int selectRegisterSet(uint8_t dev, uint8_t ch, uint8_t reg);
  86. static uint8_t selectSpecialRegisterSet(uint8_t dev, uint8_t ch);
  87. static uint8_t selectEnhancedRegisterSet(uint8_t dev, uint8_t ch);
  88. static uint8_t selectDefaultRegisterSet(uint8_t dev, uint8_t ch);
  89. static uint8_t switchEnhancedFunctions(uint8_t dev, uint8_t ch, uint8_t flag);
  90. static uint8_t switchTcrTlrSelect(uint8_t dev, uint8_t ch, uint8_t flag);
  91. static int Sc16is752RegRawRead(uint8_t dev, uint8_t ch, uint8_t reg, uint8_t *val);
  92. static int Sc16is752RegRawWrite(uint8_t dev, uint8_t ch, uint8_t reg, uint8_t val);
  93. /*!
  94. * \brief Receiver error flags.
  95. */
  96. static ureg_t rx_errors;
  97. /*!
  98. * \brief Enables software flow control if not equal zero.
  99. */
  100. static uint_fast8_t flow_control;
  101. /*!
  102. * \brief Transmit address frame, if not zero.
  103. */
  104. //static uint_fast8_t tx_aframe;
  105. //#if defined(UART_RTS_BIT) || defined(US_MODE_HWHANDSHAKE)
  106. /*!
  107. * \brief Enables RTS control if not equal zero.
  108. *
  109. * This variable exists only if the hardware configuration defines a
  110. * port bit to control the RTS signal.
  111. */
  112. //static uint_fast8_t rts_control;
  113. //#endif
  114. //#if defined(UART_CTS_BIT) || defined(US_MODE_HWHANDSHAKE)
  115. /*!
  116. * \brief Enables CTS sense if not equal zero.
  117. *
  118. * This variable exists only if the hardware configuration defines a
  119. * port bit to sense the CTS signal.
  120. */
  121. //static uint_fast8_t cts_sense;
  122. //#endif
  123. /** Incoming interrupt events */
  124. static HANDLE irqEvents[DEV_MAX];
  125. static NUTDEVICE *deviceList[DEV_MAX][CH_MAX];
  126. /*
  127. * \brief USARTn transmitter ready interrupt handler.
  128. *
  129. * \param rbf Pointer to the transmitter ring buffer.
  130. */
  131. static void Sc16is752UsartTxReady(uint8_t dev, uint8_t ch, RINGBUF *rbf)
  132. {
  133. register uint8_t *cp = rbf->rbf_tail;
  134. uint8_t v;
  135. //
  136. // /*
  137. // * Process pending software flow controls first.
  138. // */
  139. // if (flow_control & (XON_PENDING | XOFF_PENDING)) {
  140. // if (flow_control & XON_PENDING) {
  141. // outr(USARTn_BASE + US_THR_OFF, ASCII_XOFF);
  142. // flow_control |= XOFF_SENT;
  143. // } else {
  144. // outr(USARTn_BASE + US_THR_OFF, ASCII_XON);
  145. // flow_control &= ~XOFF_SENT;
  146. // }
  147. // flow_control &= ~(XON_PENDING | XOFF_PENDING);
  148. // return;
  149. // }
  150. //
  151. // if (flow_control & XOFF_RCVD) {
  152. // /*
  153. // * If XOFF has been received, we disable the transmit interrupts
  154. // * and return without sending anything.
  155. // */
  156. // outr(USARTn_BASE + US_IDR_OFF, US_TXRDY);
  157. // return;
  158. // }
  159. //
  160. if (rbf->rbf_cnt) {
  161. //
  162. // #ifdef UART_CTS_BIT
  163. // /*
  164. // * If CTS has been disabled, we disable the transmit interrupts
  165. // * and return without sending anything.
  166. // */
  167. // if (cts_sense && bit_is_set(UART_CTS_PIN, UART_CTS_BIT)) {
  168. // outr(USARTn_BASE + US_IDR_OFF, US_TXRDY);
  169. // sbi(EIMSK, UART_CTS_BIT);
  170. // return;
  171. // }
  172. // #endif
  173. rbf->rbf_cnt--;
  174. // /*
  175. // * Send address in multidrop mode.
  176. // */
  177. // if (tx_aframe) {
  178. // outr(USARTn_BASE + US_CR_OFF, US_SENDA);
  179. // }
  180. //
  181. /*
  182. * Start transmission of the next character.
  183. */
  184. Sc16is752RegWrite(dev, ch, THR, *cp);
  185. MYPRINT("sended %c\n",*cp);
  186. NutMicroDelay(500);
  187. /*
  188. * Wrap around the buffer pointer if we reached its end.
  189. */
  190. if (++cp == rbf->rbf_last) {
  191. cp = rbf->rbf_start;
  192. }
  193. rbf->rbf_tail = cp;
  194. if (rbf->rbf_cnt == rbf->rbf_lwm) {
  195. NutEventPost(&rbf->rbf_que);
  196. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_WRITE);
  197. }
  198. }
  199. /*
  200. * Nothing left to transmit, disable 'THR empty' interrupt.
  201. */
  202. else {
  203. Sc16is752RegRead(dev, ch, IER, &v);
  204. v &= ~(1<<1);
  205. Sc16is752RegWrite(dev, ch, IER, v);
  206. rbf->rbf_cnt = 0;
  207. NutEventPost(&rbf->rbf_que);
  208. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_WRITE);
  209. }
  210. }
  211. /*
  212. * \brief USARTn receiver ready interrupt handler.
  213. *
  214. *
  215. * \param rbf Pointer to the receiver ring buffer.
  216. */
  217. static void Sc16is752UsartRxReady(uint8_t dev, uint8_t ch, RINGBUF *rbf)
  218. {
  219. register size_t cnt;
  220. uint8_t c, e;
  221. /*
  222. * We read the received character as early as possible to avoid overflows
  223. * caused by interrupt latency.
  224. */
  225. Sc16is752RegRead(dev, ch, RHR, &c);
  226. //printf("r:%c\n", (char)c);
  227. /* Collect receiver errors. */
  228. Sc16is752RegRead(dev, ch, LSR, &e);
  229. rx_errors |= e & ((1<<3) | (1<<2) | (1<<1)); // Framing, parity, overrun error
  230. // /*
  231. // * Handle software handshake. We have to do this before checking the
  232. // * buffer, because flow control must work in write-only mode, where
  233. // * there is no receive buffer.
  234. // */
  235. // if (flow_control) {
  236. // /* XOFF character disables transmit interrupts. */
  237. // if (c == ASCII_XOFF) {
  238. // outr(USARTn_BASE + US_IDR_OFF, US_TXRDY);
  239. // flow_control |= XOFF_RCVD;
  240. // return;
  241. // }
  242. // /* XON enables transmit interrupts. */
  243. // else if (c == ASCII_XON) {
  244. // outr(USARTn_BASE + US_IER_OFF, US_TXRDY);
  245. // flow_control &= ~XOFF_RCVD;
  246. // return;
  247. // }
  248. // }
  249. /*
  250. * Check buffer overflow.
  251. */
  252. cnt = rbf->rbf_cnt;
  253. if (cnt >= rbf->rbf_siz) {
  254. rx_errors |= US_OVRE;
  255. return;
  256. }
  257. /* Wake up waiting threads if this is the first byte in the buffer. */
  258. if (cnt++ == 0){
  259. NutEventPost(&rbf->rbf_que);
  260. NutSelectWakeupFromIrq(rbf->wq_list, WQ_FLAG_READ);
  261. }
  262. // /*
  263. // * Check the high watermark for software handshake. If the number of
  264. // * buffered bytes is above this mark, then send XOFF.
  265. // */
  266. // else if (flow_control) {
  267. // if(cnt >= rbf->rbf_hwm) {
  268. // if((flow_control & XOFF_SENT) == 0) {
  269. // if (inr(USARTn_BASE + US_CSR_OFF) & US_TXRDY) {
  270. // outb(USARTn_BASE + US_THR_OFF, ASCII_XOFF);
  271. // flow_control |= XOFF_SENT;
  272. // flow_control &= ~XOFF_PENDING;
  273. // } else {
  274. // flow_control |= XOFF_PENDING;
  275. // }
  276. // }
  277. // }
  278. // }
  279. //
  280. // #ifdef UART_RTS_BIT
  281. // /*
  282. // * Check the high watermark for hardware handshake. If the number of
  283. // * buffered bytes is above this mark, then disable RTS.
  284. // */
  285. // else if (rts_control && cnt >= rbf->rbf_hwm) {
  286. // sbi(UART_RTS_PORT, UART_RTS_BIT);
  287. // }
  288. // #endif
  289. /*
  290. * Store the character and increment and the ring buffer pointer.
  291. */
  292. *rbf->rbf_head++ = c;
  293. if (rbf->rbf_head == rbf->rbf_last) {
  294. rbf->rbf_head = rbf->rbf_start;
  295. }
  296. /* Update the ring buffer counter. */
  297. rbf->rbf_cnt = cnt;
  298. }
  299. void Sc16is752UsartProcessChannelInterrupt(uint8_t dev, uint8_t ch, uint8_t iir)
  300. {
  301. USARTDCB *dcb = deviceList[dev][ch]->dev_dcb;
  302. switch(iir)
  303. {
  304. case 0x6: // (0b00 0110) receiver line status Overrun Error (OE), Framing Error (FE), Parity Error
  305. // (PE), or Break Interrupt (BI) errors occur in characters in the RX FIFO
  306. break;
  307. case 0xc: // (0b00 1100) RX time-out stale data in RX FIFO
  308. // break;
  309. case 0x4: // (0b00 0100) RHR interrupt receive data ready (FIFO disable) or
  310. // RX FIFO above trigger level (FIFO enable)
  311. Sc16is752UsartRxReady(dev, ch, &dcb->dcb_rx_rbf);
  312. break;
  313. case 0x2: // (0b00 0010) THR interrupt transmit FIFO empty (FIFO disable) or
  314. // TX FIFO passes above trigger level (FIFO enable)
  315. Sc16is752UsartTxReady(dev, ch, &dcb->dcb_tx_rbf);
  316. break;
  317. case 0x0: // (0b00 0000) modem status change of state of modem input pins
  318. break;
  319. case 0xe: // (0b00 1110) I/O pins input pins change of state
  320. break;
  321. case 0x10: // (0b01 0000) Xoff interrupt receive Xoff character(s)/special character
  322. break;
  323. case 0x20: // (0b10 0000) CTS, RTS RTS pin or CTS pin change state from active (LOW)
  324. //to inactive (HIGH)
  325. break;
  326. }
  327. }
  328. /**
  329. * UART Interrupt Processing Thread
  330. */
  331. THREAD(Sc16is752UsartInterruptProcessing, arg)
  332. {
  333. uint8_t dev = (uint8_t)(((int)arg)&0xff);
  334. uint8_t iir;
  335. NutThreadSetPriority(50);
  336. for(;;)
  337. {
  338. NutEventWait(&irqEvents[dev], NUT_WAIT_INFINITE);
  339. MYPRINT("irq proccess\n");
  340. Sc16is752RegRead(dev, 0, IIR, &iir);
  341. MYPRINT("1\n");
  342. if (!(iir&1))
  343. {
  344. MYPRINT("1\n");
  345. Sc16is752UsartProcessChannelInterrupt(dev, 0, iir);
  346. }
  347. Sc16is752RegRead(dev, 1, IIR, &iir);
  348. if (!(iir&1))
  349. {
  350. MYPRINT("1\n");
  351. Sc16is752UsartProcessChannelInterrupt(dev, 1, iir);
  352. }
  353. }
  354. }
  355. #if !defined(__linux__)
  356. /*!
  357. * \brief USART interrupt handler.
  358. *
  359. * \param arg Pointer to the device specific control block.
  360. */
  361. static void Sc16is752UsartInterrupt(void *arg)
  362. {
  363. NUTDEVICE *nutDev= (NUTDEVICE *)arg;
  364. uint8_t dev = ((nutDev->dev_base)>>8) & 0xff;
  365. MYPRINT("irq\n");
  366. // Trigger interrupt processing thread (I2C access not allowed from ISR)
  367. NutEventPostFromIrq(&irqEvents[dev]);
  368. }
  369. #endif
  370. /*!
  371. * \brief Carefully enable USART hardware functions.
  372. *
  373. * Always enabale transmitter and receiver, even on read-only or
  374. * write-only mode. So we can support software flow control.
  375. */
  376. void Sc16is752UsartEnable(uint8_t dev, uint8_t ch)
  377. {
  378. #if defined(__linux__)
  379. printf("%s\n", __func__);
  380. #endif
  381. // NutEnterCritical();
  382. //
  383. // /* Enable UART receiver and transmitter. */
  384. // outr(USARTn_BASE + US_CR_OFF, US_RXEN | US_TXEN);
  385. //
  386. // /* Enable UART receiver and transmitter interrupts. */
  387. // outr(USARTn_BASE + US_IER_OFF, US_RXRDY | US_TXRDY);
  388. // NutIrqEnable(&SIG_UART);
  389. //
  390. // NutExitCritical();
  391. }
  392. /*!
  393. * \brief Carefully disable USART hardware functions.
  394. */
  395. void Sc16is752UsartDisable(uint8_t dev, uint8_t ch)
  396. {
  397. #if defined(__linux__)
  398. printf("%s\n", __func__);
  399. #endif
  400. // /*
  401. // * Disable USART interrupts.
  402. // */
  403. // NutEnterCritical();
  404. // outr(USARTn_BASE + US_IDR_OFF, 0xFFFFFFFF);
  405. // NutExitCritical();
  406. //
  407. // /*
  408. // * Allow incoming or outgoing character to finish.
  409. // */
  410. // NutDelay(10);
  411. //
  412. // /*
  413. // * Disable USART transmit and receive.
  414. // */
  415. // outr(USARTn_BASE + US_CR_OFF, US_RXDIS | US_TXDIS);
  416. }
  417. /*!
  418. * \brief Query the USART hardware for the selected speed.
  419. *
  420. * This function is called by ioctl function of the upper level USART
  421. * driver through the USARTDCB jump table.
  422. *
  423. * \return The currently selected baudrate.
  424. */
  425. uint32_t Sc16is752UsartGetSpeed(uint8_t dev, uint8_t ch)
  426. {
  427. #if defined(__linux__)
  428. printf("%s\n", __func__);
  429. #endif
  430. // ureg_t cs = inr(USARTn_BASE + US_MR_OFF);
  431. // uint32_t clk;
  432. //
  433. // clk = NutClockGet(NUT_HWCLK_PERIPHERAL);
  434. // if ((cs & US_CLKS) == US_CLKS_MCK8) {
  435. // clk /= 8;
  436. // }
  437. // else if ((cs & US_CLKS) != US_CLKS_MCK) {
  438. // clk = 0;
  439. // }
  440. // return clk / (16UL * (inr(USARTn_BASE + US_BRGR_OFF) & 0xFFFF));
  441. return 0;
  442. }
  443. /*!
  444. * \brief Set the USART hardware bit rate.
  445. *
  446. * This function is called by ioctl function of the upper level USART
  447. * driver through the USARTDCB jump table.
  448. *
  449. * \param rate Number of bits per second.
  450. *
  451. * \return 0 on success, -1 otherwise.
  452. */
  453. int Sc16is752UsartSetSpeed(uint32_t rate, uint8_t dev, uint8_t ch)
  454. {
  455. #if defined(__linux__)
  456. printf("%s\n", __func__);
  457. #endif
  458. Sc16is752UsartDisable(dev, ch);
  459. // outr(USARTn_BASE + US_BRGR_OFF, (NutClockGet(NUT_HWCLK_PERIPHERAL) / (8 * (rate)) + 1) / 2);
  460. Sc16is752UsartEnable(dev, ch);
  461. return 0;
  462. }
  463. /*!
  464. * \brief Query the USART hardware for the number of data bits.
  465. *
  466. * This function is called by ioctl function of the upper level USART
  467. * driver through the USARTDCB jump table.
  468. *
  469. * \return The number of data bits set.
  470. */
  471. uint8_t Sc16is752UsartGetDataBits(uint8_t dev, uint8_t ch)
  472. {
  473. #if defined(__linux__)
  474. printf("%s\n", __func__);
  475. #endif
  476. // ureg_t val = inr(USARTn_BASE + US_MR_OFF);
  477. //
  478. // if ((val & US_PAR) == US_PAR_MULTIDROP) {
  479. // val = 9;
  480. // }
  481. // else {
  482. // val &= US_CHRL;
  483. // if (val == US_CHRL_5) {
  484. // val = 5;
  485. // }
  486. // else if (val == US_CHRL_6) {
  487. // val = 6;
  488. // }
  489. // else if (val == US_CHRL_7) {
  490. // val = 7;
  491. // }
  492. // else {
  493. // val = 8;
  494. // }
  495. // }
  496. // return (uint8_t)val;
  497. return 0;
  498. }
  499. /*!
  500. * \brief Set the USART hardware to the number of data bits.
  501. *
  502. * This function is called by ioctl function of the upper level USART
  503. * driver through the USARTDCB jump table.
  504. *
  505. * \return 0 on success, -1 otherwise.
  506. */
  507. int Sc16is752UsartSetDataBits(uint8_t bits, uint8_t dev, uint8_t ch)
  508. {
  509. #if defined(__linux__)
  510. printf("%s\n", __func__);
  511. #endif
  512. // ureg_t val = inr(USARTn_BASE + US_MR_OFF);
  513. //
  514. // if (bits == 9) {
  515. // val &= ~US_PAR;
  516. // val |= US_PAR_MULTIDROP;
  517. // }
  518. // else {
  519. // val &= ~US_CHRL;
  520. // if (bits == 5) {
  521. // val |= US_CHRL_5;
  522. // }
  523. // else if (bits == 6) {
  524. // val |= US_CHRL_6;
  525. // }
  526. // else if (bits == 7) {
  527. // val |= US_CHRL_7;
  528. // }
  529. // else if (bits == 8) {
  530. // val |= US_CHRL_8;
  531. // }
  532. // }
  533. //
  534. // At91UsartDisable();
  535. // outr(USARTn_BASE + US_MR_OFF, val);
  536. // At91UsartEnable();
  537. //
  538. // /*
  539. // * Verify the result.
  540. // */
  541. // if (At91UsartGetDataBits() != bits) {
  542. // return -1;
  543. // }
  544. return 0;
  545. }
  546. /*!
  547. * \brief Query the USART hardware for the parity mode.
  548. *
  549. * This routine is called by ioctl function of the upper level USART
  550. * driver through the USARTDCB jump table.
  551. *
  552. * \return Parity mode, either 0 (disabled), 1 (odd), 2 (even) or 9 (multidrop).
  553. */
  554. uint8_t Sc16is752UsartGetParity(uint8_t dev, uint8_t ch)
  555. {
  556. #if defined(__linux__)
  557. printf("%s\n", __func__);
  558. #endif
  559. // ureg_t val = inr(USARTn_BASE + US_MR_OFF) & US_PAR;
  560. //
  561. // if ((val & US_PAR) == US_PAR_MULTIDROP) {
  562. // val = 9;
  563. // }
  564. // else {
  565. // if (val == US_PAR_ODD) {
  566. // val = 1;
  567. // }
  568. // else if (val == US_PAR_EVEN) {
  569. // val = 2;
  570. // }
  571. // else {
  572. // val = 0;
  573. // }
  574. // }
  575. // return (uint8_t)val;
  576. return 0;
  577. }
  578. /*!
  579. * \brief Set the USART hardware to the specified parity mode.
  580. *
  581. * This routine is called by ioctl function of the upper level USART
  582. * driver through the USARTDCB jump table.
  583. *
  584. * \param mode 0 (disabled), 1 (odd) or 2 (even)
  585. *
  586. * \return 0 on success, -1 otherwise.
  587. */
  588. int Sc16is752UsartSetParity(uint8_t mode, uint8_t dev, uint8_t ch)
  589. {
  590. #if defined(__linux__)
  591. printf("%s\n", __func__);
  592. #endif
  593. // ureg_t val = inr(USARTn_BASE + US_MR_OFF) & ~US_PAR;
  594. //
  595. // switch (mode) {
  596. // case 0:
  597. // val |= US_PAR_NO;
  598. // break;
  599. // case 1:
  600. // val |= US_PAR_ODD;
  601. // break;
  602. // case 2:
  603. // val |= US_PAR_EVEN;
  604. // break;
  605. // }
  606. // At91UsartDisable();
  607. // outr(USARTn_BASE + US_MR_OFF, val);
  608. // At91UsartEnable();
  609. //
  610. // /*
  611. // * Verify the result.
  612. // */
  613. // if (At91UsartGetParity() != mode) {
  614. // return -1;
  615. // }
  616. return 0;
  617. }
  618. /*!
  619. * \brief Query the USART hardware for the number of stop bits.
  620. *
  621. * This routine is called by ioctl function of the upper level USART
  622. * driver through the USARTDCB jump table.
  623. *
  624. * \return The number of stop bits set, either 1, 2 or 3 (1.5 bits).
  625. */
  626. uint8_t Sc16is752UsartGetStopBits(uint8_t dev, uint8_t ch)
  627. {
  628. #if defined(__linux__)
  629. printf("%s\n", __func__);
  630. #endif
  631. // ureg_t val = inr(USARTn_BASE + US_MR_OFF) & US_NBSTOP;
  632. // if (val == US_NBSTOP_1) {
  633. // val = 1;
  634. // }
  635. // else if (val == US_NBSTOP_2) {
  636. // val = 2;
  637. // }
  638. // else {
  639. // val = 3;
  640. // }
  641. // return (uint8_t)val;
  642. return 0;
  643. }
  644. /*!
  645. * \brief Set the USART hardware to the number of stop bits.
  646. *
  647. * This routine is called by ioctl function of the upper level USART
  648. * driver through the USARTDCB jump table.
  649. *
  650. * \return 0 on success, -1 otherwise.
  651. */
  652. int Sc16is752UsartSetStopBits(uint8_t bits, uint8_t dev, uint8_t ch)
  653. {
  654. #if defined(__linux__)
  655. printf("%s\n", __func__);
  656. #endif
  657. // ureg_t val = inr(USARTn_BASE + US_MR_OFF) & ~US_NBSTOP;
  658. //
  659. // switch(bits) {
  660. // case 1:
  661. // val |= US_NBSTOP_1;
  662. // break;
  663. // case 2:
  664. // val |= US_NBSTOP_2;
  665. // break;
  666. // case 3:
  667. // val |= US_NBSTOP_1_5;
  668. // break;
  669. // }
  670. // At91UsartDisable();
  671. // outr(USARTn_BASE + US_MR_OFF, val);
  672. // At91UsartEnable();
  673. //
  674. // /*
  675. // * Verify the result.
  676. // */
  677. // if (At91UsartGetStopBits() != bits) {
  678. // return -1;
  679. // }
  680. return 0;
  681. }
  682. /*!
  683. * \brief Query the USART hardware status.
  684. *
  685. * \return Status flags.
  686. */
  687. uint32_t Sc16is752UsartGetStatus(uint8_t dev, uint8_t ch)
  688. {
  689. uint32_t rc = 0;
  690. #if defined(__linux__)
  691. printf("%s\n", __func__);
  692. #endif
  693. // /*
  694. // * Set receiver error flags.
  695. // */
  696. // if ((rx_errors & US_FRAME) != 0) {
  697. // rc |= UART_FRAMINGERROR;
  698. // }
  699. // if ((rx_errors & US_OVRE) != 0) {
  700. // rc |= UART_OVERRUNERROR;
  701. // }
  702. // if ((rx_errors & US_PARE) != 0) {
  703. // rc |= UART_PARITYERROR;
  704. // }
  705. //
  706. // /*
  707. // * Determine software handshake status. The flow control status may
  708. // * change during interrupt, but this doesn't really hurt us.
  709. // */
  710. // if (flow_control) {
  711. // if (flow_control & XOFF_SENT) {
  712. // rc |= UART_RXDISABLED;
  713. // }
  714. // if (flow_control & XOFF_RCVD) {
  715. // rc |= UART_TXDISABLED;
  716. // }
  717. // }
  718. //
  719. // /*
  720. // * Determine hardware handshake control status.
  721. // */
  722. //
  723. // /*
  724. // * Determine hardware handshake sense status.
  725. // */
  726. //
  727. // /*
  728. // * Determine hardware modem sense status.
  729. // */
  730. //
  731. // /*
  732. // * If transmitter and receiver haven't been detected disabled by any
  733. // * of the checks above, then they are probably enabled.
  734. // */
  735. // if ((rc & UART_RXDISABLED) == 0) {
  736. // rc |= UART_RXENABLED;
  737. // }
  738. // if ((rc & UART_TXDISABLED) == 0) {
  739. // rc |= UART_TXENABLED;
  740. // }
  741. //
  742. // /*
  743. // * Process multidrop setting.
  744. // */
  745. // if (tx_aframe) {
  746. // rc |= UART_TXADDRFRAME;
  747. // } else {
  748. // rc |= UART_TXNORMFRAME;
  749. // }
  750. return rc;
  751. }
  752. /*!
  753. * \brief Set the USART hardware status.
  754. *
  755. * \param flags Status flags.
  756. *
  757. * \return 0 on success, -1 otherwise.
  758. */
  759. int Sc16is752UsartSetStatus(uint32_t flags, uint8_t dev, uint8_t ch)
  760. {
  761. #if defined(__linux__)
  762. printf("%s\n", __func__);
  763. #endif
  764. // /*
  765. // * Process software handshake control.
  766. // */
  767. // if (flow_control) {
  768. //
  769. // /* Access to the flow control status must be atomic. */
  770. // NutEnterCritical();
  771. //
  772. // /*
  773. // * Enabling or disabling the receiver means to behave like
  774. // * having sent a XON or XOFF character resp.
  775. // */
  776. // if (flags & UART_RXENABLED) {
  777. // flow_control &= ~XOFF_SENT;
  778. // } else if (flags & UART_RXDISABLED) {
  779. // flow_control |= XOFF_SENT;
  780. // }
  781. //
  782. // /*
  783. // * Enabling or disabling the transmitter means to behave like
  784. // * having received a XON or XOFF character resp.
  785. // */
  786. // if (flags & UART_TXENABLED) {
  787. // flow_control &= ~XOFF_RCVD;
  788. // } else if (flags & UART_TXDISABLED) {
  789. // flow_control |= XOFF_RCVD;
  790. // }
  791. // NutExitCritical();
  792. // }
  793. //
  794. // /*
  795. // * Process hardware handshake control.
  796. // */
  797. //
  798. // /*
  799. // * Process hardware modem control.
  800. // */
  801. //
  802. // /*
  803. // * Process multidrop setting.
  804. // */
  805. // if (flags & UART_TXADDRFRAME) {
  806. // tx_aframe = 1;
  807. // }
  808. // if (flags & UART_TXNORMFRAME) {
  809. // tx_aframe = 0;
  810. // }
  811. //
  812. // /*
  813. // * Clear UART receive errors.
  814. // */
  815. // if (flags & UART_ERRORS) {
  816. // outr(USARTn_BASE + US_CR_OFF, US_RSTSTA);
  817. // }
  818. //
  819. // /*
  820. // * Verify the result.
  821. // */
  822. // if ((At91UsartGetStatus() & ~UART_ERRORS) != flags) {
  823. // return -1;
  824. // }
  825. return 0;
  826. }
  827. /*!
  828. * \brief Query the USART hardware for synchronous mode.
  829. *
  830. * This function is called by ioctl function of the upper level USART
  831. * driver through the USARTDCB jump table.
  832. *
  833. * \return Or-ed combination of \ref UART_SYNC, \ref UART_MASTER,
  834. * \ref UART_NCLOCK and \ref UART_HIGHSPEED.
  835. */
  836. uint8_t Sc16is752UsartGetClockMode(uint8_t dev, uint8_t ch)
  837. {
  838. uint8_t rc = 0;
  839. #if defined(__linux__)
  840. printf("%s\n", __func__);
  841. #endif
  842. return rc;
  843. }
  844. /*!
  845. * \brief Set asynchronous or synchronous mode.
  846. *
  847. * This function is called by ioctl function of the upper level USART
  848. * driver through the USARTDCB jump table.
  849. *
  850. * \param mode Must be an or-ed combination of USART_SYNC, USART_MASTER,
  851. * USART_NCLOCK and USART_HIGHSPEED.
  852. *
  853. * \return 0 on success, -1 otherwise.
  854. */
  855. int Sc16is752UsartSetClockMode(uint8_t mode, uint8_t dev, uint8_t ch)
  856. {
  857. #if defined(__linux__)
  858. printf("%s\n", __func__);
  859. #endif
  860. /*
  861. * Verify the result.
  862. */
  863. if (Sc16is752UsartGetClockMode(dev, ch) != mode) {
  864. return -1;
  865. }
  866. return 0;
  867. }
  868. /*!
  869. * \brief Query flow control mode.
  870. *
  871. * This routine is called by ioctl function of the upper level USART
  872. * driver through the USARTDCB jump table.
  873. *
  874. * \return See UsartIOCtl().
  875. */
  876. uint32_t Sc16is752UsartGetFlowControl(uint8_t dev, uint8_t ch)
  877. {
  878. uint32_t rc = 0;
  879. #if defined(__linux__)
  880. printf("%s\n", __func__);
  881. #endif
  882. if (flow_control) {
  883. rc |= USART_MF_XONXOFF;
  884. } else {
  885. rc &= ~USART_MF_XONXOFF;
  886. }
  887. return rc;
  888. }
  889. /*!
  890. * \brief Set flow control mode.
  891. *
  892. * This function is called by ioctl function of the upper level USART
  893. * driver through the USARTDCB jump table.
  894. *
  895. * \param flags See UsartIOCtl().
  896. *
  897. * \return 0 on success, -1 otherwise.
  898. */
  899. int Sc16is752UsartSetFlowControl(uint32_t flags, uint8_t dev, uint8_t ch)
  900. {
  901. #if defined(__linux__)
  902. printf("%s\n", __func__);
  903. #endif
  904. /*
  905. * Set software handshake mode.
  906. */
  907. /*
  908. * Verify the result.
  909. */
  910. if (Sc16is752UsartGetFlowControl(dev, ch) != flags) {
  911. return -1;
  912. }
  913. return 0;
  914. }
  915. //////////////////////////////////////////////////////////////////////////////
  916. /*!
  917. * \brief Start the USART transmitter hardware.
  918. *
  919. * The upper level USART driver will call this function through the
  920. * USARTDCB jump table each time it added one or more bytes to the
  921. * transmit buffer.
  922. */
  923. void Sc16is752UsartTxStart(uint8_t dev, uint8_t ch)
  924. {
  925. uint8_t ier;
  926. #if defined(__linux__)
  927. printf("%s\n", __func__);
  928. #endif
  929. /* Enable transmit interrupts. */
  930. ///TODO Check if Tx interrupt is generated immediately or if a first char needs to sent
  931. Sc16is752RegRead(dev, ch, IER, &ier);
  932. ier |= (1<<1);
  933. Sc16is752RegWrite(dev, ch, IER, ier);
  934. }
  935. /*!
  936. * \brief Start the USART receiver hardware.
  937. *
  938. * The upper level USART driver will call this function through the
  939. * USARTDCB jump table each time it removed enough bytes from the
  940. * receive buffer. Enough means, that the number of bytes left in
  941. * the buffer is below the low watermark.
  942. */
  943. void Sc16is752UsartRxStart(uint8_t dev, uint8_t ch)
  944. {
  945. #if defined(__linux__)
  946. printf("%s\n", __func__);
  947. #endif
  948. /*
  949. * Do any required software flow control.
  950. */
  951. // if (flow_control && (flow_control & XOFF_SENT) != 0) {
  952. // NutEnterCritical();
  953. // if ((inr(USARTn_BASE + US_CSR_OFF) & US_TXRDY)) {
  954. // outr(USARTn_BASE + US_THR_OFF, ASCII_XON);
  955. // flow_control &= ~XON_PENDING;
  956. // } else {
  957. // flow_control |= XON_PENDING;
  958. // }
  959. // flow_control &= ~(XOFF_SENT | XOFF_PENDING);
  960. // NutExitCritical();
  961. // }
  962. }
  963. /*!
  964. * \brief Initialize the USART hardware driver.
  965. *
  966. * This function is called during device registration by the upper level
  967. * USART driver through the USARTDCB jump table.
  968. *
  969. * \return 0 on success, -1 otherwise.
  970. */
  971. int Sc16is752UsartInit(uint8_t dev, uint8_t ch, NUTDEVICE *nutDev, IRQ_HANDLER *irq)
  972. {
  973. deviceList[dev][ch] = nutDev; // needs to be stored here for interrupt processing
  974. uint8_t ier;
  975. #if defined(__linux__)
  976. printf("%s\n", __func__);
  977. #endif
  978. MYPRINT("1\n");
  979. /*
  980. * Register receive and transmit interrupts.
  981. */
  982. // Register IRQ1 for dev=0 and IRQ1 for dev=1 and ch=0
  983. // This requires to keep the init sequence: ch=0, then ch=1
  984. // Deinit must happen vice versa: first ch=1, then ch=0
  985. if (ch==0)
  986. {
  987. /* Start Message Handler Thread. */
  988. char threadname[]="usartirq0";
  989. threadname[8] = '0'+dev; // Create unique name
  990. MYPRINT("1\n");
  991. if (NutThreadCreate(threadname, Sc16is752UsartInterruptProcessing, (void *)(int)dev, 512)==0)
  992. return -1;
  993. MYPRINT("1\n");
  994. #if !defined(__linux__)
  995. if (NutRegisterIrqHandler(irq, Sc16is752UsartInterrupt, nutDev))
  996. return -1;
  997. NutIrqSetMode(irq, NUT_IRQMODE_FALLINGEDGE);
  998. MYPRINT("1\n");
  999. NutIrqEnable(irq);
  1000. #endif
  1001. }
  1002. #if 1
  1003. MYPRINT("1\n");
  1004. /* Reset UART. */
  1005. //TOE Sc16is752RegWrite(dev, ch, IOControl, (1<<3)); // SW Reset
  1006. /* Enable receive interrupts. */
  1007. ///TODO Check if Rx interrupt is generated immediately or if a first char needs to sent
  1008. Sc16is752RegRead(dev, ch, IER, &ier);
  1009. MYPRINT("ier:%d\n",ier);
  1010. ier |= (1<<0); // Enable Rx interrupt
  1011. MYPRINT("ier:%d\n",ier);
  1012. Sc16is752RegWrite(dev, ch, IER, ier);
  1013. MYPRINT("1\n");
  1014. /* Set initial baudrate */
  1015. setBaudrate(dev, ch, INIT_BAUDRATE);
  1016. MYPRINT("1\n");
  1017. /* Set UART mode to 8 data bits, no parity and 1 stop bit. */
  1018. Sc16is752RegWrite(dev, ch, LCR, 3);
  1019. MYPRINT("1\n");
  1020. #endif
  1021. #if 0
  1022. {
  1023. uint8_t reg;
  1024. uint8_t val;
  1025. /* This register causes trubble */
  1026. /* Reset UART. */
  1027. // buf[0] = ( IOControl << 3 );
  1028. // buf[1] = 0x08; // Software reset
  1029. // TwMasterTransact( sla, buf, 2, 0, 0, 50 );
  1030. reg = LCR & 0x1F;
  1031. val = 0x80; // eable special registers
  1032. Sc16is752RegRawWrite( dev, ch, reg, val );
  1033. /* Set initial baudrate */
  1034. // div = 3; // XTAL / INIT_BAUDRATE / 16;
  1035. reg = DLL & 0x1F;
  1036. val = 3; // div & 0xff;
  1037. Sc16is752RegRawWrite( dev, ch, reg, val );
  1038. reg = DLH & 0x1F;
  1039. val = 0; //div >> 8; // set baud rate
  1040. Sc16is752RegRawWrite( dev, ch, reg, val );
  1041. /* Set 8N1 */
  1042. reg = LCR & 0x1F;
  1043. val = 0x03; // 8N1
  1044. Sc16is752RegRawWrite( dev, ch, reg, val );
  1045. // ensure clock divisor is off
  1046. reg = FCR & 0x1F;
  1047. val = 0x01; // FIFO enable
  1048. Sc16is752RegRawWrite( dev, ch, reg, val );
  1049. reg = IER & 0x1F;
  1050. val = 0x05; // FIFO enable
  1051. Sc16is752RegRawWrite( dev, ch, reg, val );
  1052. MYPRINT("val:%d\n",val);
  1053. }
  1054. #endif
  1055. return 0;
  1056. }
  1057. /*!
  1058. * \brief Deinitialize the USART hardware driver.
  1059. *
  1060. * This function is called during device deregistration by the upper
  1061. * level USART driver through the USARTDCB jump table.
  1062. *
  1063. * \return 0 on success, -1 otherwise.
  1064. */
  1065. int Sc16is752UsartDeinit(uint8_t dev, uint8_t ch, IRQ_HANDLER *irq)
  1066. {
  1067. #if defined(__linux__)
  1068. printf("%s\n", __func__);
  1069. #endif
  1070. /* Reset UART (this implicitely disables all interrupts). */
  1071. //TOE Sc16is752RegWrite(dev, ch, IOControl, (1<<3)); // SW Reset
  1072. /* Deregister receive and transmit interrupts. */
  1073. // unregister interrupt,
  1074. if (ch==0)
  1075. {
  1076. #if !defined(__linux__)
  1077. NutRegisterIrqHandler(irq, 0, 0);
  1078. #endif
  1079. }
  1080. return 0;
  1081. }
  1082. //////////////
  1083. #if 1
  1084. int setBaudrate(uint8_t dev, uint8_t ch, int baud)
  1085. {
  1086. uint8_t v;
  1087. #if defined(__linux__)
  1088. printf("%s\n", __func__);
  1089. #endif
  1090. // ensure clock divisor is off
  1091. Sc16is752RegRead(dev, ch, MCR, &v);
  1092. v &= ~(1<<8);
  1093. Sc16is752RegWrite(dev, ch, MCR, v);
  1094. // set baudrate
  1095. int div = XTAL / baud / 16;
  1096. Sc16is752RegRead(dev, ch, LCR, &v);
  1097. Sc16is752RegWrite(dev, ch, LCR, 0x80);
  1098. Sc16is752RegWrite(dev, ch, DLL, div & 0xff);
  1099. Sc16is752RegWrite(dev, ch, DLH, div >> 8);
  1100. Sc16is752RegWrite(dev, ch, LCR, v);
  1101. return 0;
  1102. }
  1103. #endif
  1104. /*
  1105. * I2C register access wrapper
  1106. */
  1107. static regselstate_t regselState[DEV_MAX][CH_MAX] = { {{0,0}, {0,0}}, {{0,0}, {0,0}}};
  1108. static uint8_t i2caddr[DEV_MAX] =
  1109. {
  1110. USART_DEVICE0_I2C_ADDR,
  1111. USART_DEVICE1_I2C_ADDR
  1112. };
  1113. int Sc16is752RegWrite(uint8_t dev, uint8_t ch, uint8_t reg, uint8_t val)
  1114. {
  1115. // check valid range of arguments
  1116. // assert(dev<=DEV_MAX);
  1117. // assert(ch<=CH_MAX);
  1118. //selectRegisterSet(dev, ch, reg);
  1119. // Now, perform the register access
  1120. return Sc16is752RegRawWrite(dev, ch, reg, val);
  1121. }
  1122. int Sc16is752RegRead(uint8_t dev, uint8_t ch, uint8_t reg, uint8_t *val)
  1123. {
  1124. // check valid range of arguments
  1125. // assert(dev<=DEV_MAX);
  1126. // assert(ch<=CH_MAX);
  1127. // selectRegisterSet(dev, ch, reg);
  1128. // Now, perform the register access
  1129. return Sc16is752RegRawRead(dev, ch, reg, val);
  1130. }
  1131. /*****
  1132. * Some Utility functions to select the different register sets
  1133. */
  1134. /**
  1135. * Select the register set depending on the register address
  1136. * The device can only address 16 registers directly.
  1137. * The other registers are accessible indirectly only.
  1138. */
  1139. int selectRegisterSet(uint8_t dev, uint8_t ch, uint8_t reg)
  1140. {
  1141. MYPRINT("selectRegSet");
  1142. switch(reg&REGSEL_MASK)
  1143. {
  1144. case DEFSEL:
  1145. if(((reg==MSR) || (reg==SPR)) && regselState[dev][ch].flags & TCRBIT)
  1146. {
  1147. MYPRINT("switchTcrTlrSelect\n");
  1148. // turn off TCR/TLR register mode
  1149. switchTcrTlrSelect(dev, ch, 0);
  1150. }
  1151. else if(regselState[dev][ch].state != DEFSEL)
  1152. {
  1153. MYPRINT("selectDefaultRegisterSet\n");
  1154. // select default register set
  1155. selectDefaultRegisterSet(dev, ch);
  1156. }
  1157. case TCRSEL:
  1158. MYPRINT("switchTcrTlrSelect\n");
  1159. // select TCR/TLR registers
  1160. switchTcrTlrSelect(dev, ch, 1);
  1161. break;
  1162. case SRSSEL:
  1163. MYPRINT("selectSpecialRegisterSet\n");
  1164. // select Special Registers (DLL/DLH)
  1165. selectSpecialRegisterSet(dev, ch);
  1166. break;
  1167. case ERSSEL:
  1168. MYPRINT("selectEnhancedRegisterSet\n");
  1169. // select Enhanced Registers (EFR; XONx, XOFFx)
  1170. selectEnhancedRegisterSet(dev, ch);
  1171. break;
  1172. }
  1173. return 0;
  1174. }
  1175. /**
  1176. * Switches to Special Register Set
  1177. * DLL and DLH are accessible ar register address 0 and 1
  1178. * This operation modifies the content of the LCR register
  1179. * The original content is passed as return value
  1180. */
  1181. static uint8_t selectSpecialRegisterSet(uint8_t dev, uint8_t ch)
  1182. {
  1183. uint8_t v;
  1184. Sc16is752RegRawRead(dev, ch, LCR, &v);
  1185. Sc16is752RegRawWrite(dev, ch, LCR, 0x80);
  1186. regselState[dev][ch].state = SRSSEL;
  1187. return v;
  1188. }
  1189. /**
  1190. * Switches to Enhanced Register Set
  1191. * Maps register EFR, XON1, XON2, XOFF1 and XOFF2
  1192. * This operation modifies the content of the LCR register
  1193. * The original content is passed as return value
  1194. */
  1195. static uint8_t selectEnhancedRegisterSet(uint8_t dev, uint8_t ch)
  1196. {
  1197. uint8_t v=0;
  1198. Sc16is752RegRawRead(dev, ch, LCR, &v);
  1199. Sc16is752RegRawWrite(dev, ch, LCR, 0xbf);
  1200. regselState[dev][ch].state = ERSSEL;
  1201. return v;
  1202. }
  1203. /**
  1204. * Switches to Default Register Set
  1205. * This operation modifies the content of the LCR register
  1206. * The original content is passed as return value
  1207. */
  1208. static uint8_t selectDefaultRegisterSet(uint8_t dev, uint8_t ch)
  1209. {
  1210. uint8_t v=0;
  1211. Sc16is752RegRawRead(dev, ch, LCR, &v);
  1212. v &= 0x7f; // turn off 'divisor latch enable' bit
  1213. Sc16is752RegRawWrite(dev, ch, LCR, v);
  1214. regselState[dev][ch].state = DEFSEL;
  1215. return v;
  1216. }
  1217. /**
  1218. * Turn on/off the enhanced functions bit in the EFR register
  1219. * This requires temporarily selecting the enhanced register set
  1220. * The original register set selection is restored via the original
  1221. * content of the LCR register
  1222. */
  1223. static uint8_t switchEnhancedFunctions(uint8_t dev, uint8_t ch, uint8_t flag)
  1224. {
  1225. uint8_t oldLcr;
  1226. uint8_t v=0;
  1227. oldLcr = selectEnhancedRegisterSet(dev, ch);
  1228. Sc16is752RegRawRead(dev, ch, EFR, &v);
  1229. if(flag)
  1230. {
  1231. v |= (1<<4); // switch on enhanced functions bit
  1232. regselState[dev][ch].flags |= EEFBIT;
  1233. }
  1234. else
  1235. {
  1236. v &= ~(1<<4); // switch off enhanced functions bit
  1237. regselState[dev][ch].flags &= ~EEFBIT;
  1238. }
  1239. Sc16is752RegRawWrite(dev, ch, EFR, v);
  1240. Sc16is752RegRawWrite(dev, ch, LCR, oldLcr); // select original register set
  1241. return 0;
  1242. }
  1243. static uint8_t switchTcrTlrSelect(uint8_t dev, uint8_t ch, uint8_t flag)
  1244. {
  1245. uint8_t v=0;
  1246. switchEnhancedFunctions(dev, ch, 1);
  1247. Sc16is752RegRawRead(dev, ch, MCR, &v);
  1248. if(flag)
  1249. {
  1250. v |= (1<<2); // switch on TCR/TLR enable
  1251. regselState[dev][ch].flags |= TCRBIT;
  1252. }
  1253. else
  1254. {
  1255. v &= ~(1<<2); // switch off TCR/TLR enable
  1256. regselState[dev][ch].flags &= ~TCRBIT;
  1257. }
  1258. Sc16is752RegRawWrite(dev, ch, MCR, v);
  1259. return 0;
  1260. }
  1261. static int Sc16is752RegRawWrite(uint8_t dev, uint8_t ch, uint8_t reg, uint8_t val)
  1262. {
  1263. uint8_t wbuf[2];
  1264. wbuf[0] = REGADDR(reg & 0xf, ch);
  1265. wbuf[1] = val;
  1266. #if defined(__linux__)
  1267. printf("%s(%d,%d,0x%02x,0x%02x) => slave addr:0x%02x data 0x%02x\n",
  1268. __func__, dev, ch, reg, val, i2caddr[dev], wbuf[0]);
  1269. return 0;
  1270. #else
  1271. MYPRINT("%s(%d,%d,0x%02x,0x%02x) => slave addr:0x%02x data 0x%02x\n",
  1272. __func__, dev, ch, reg, val, i2caddr[dev], wbuf[0]);
  1273. #endif
  1274. return TwMasterTransact(i2caddr[dev], wbuf, 2, 0, 0, 0);
  1275. }
  1276. static int Sc16is752RegRawRead(uint8_t dev, uint8_t ch, uint8_t reg, uint8_t *val)
  1277. {
  1278. uint8_t wbuf, rc;
  1279. wbuf = REGADDR(reg & 0xf, ch);
  1280. #if defined(__linux__)
  1281. printf("%s(%d,%d,0x%02x) => slave addr:0x%02x data 0x%02x\n",
  1282. __func__, dev, ch, reg, i2caddr[dev], wbuf);
  1283. return 0;
  1284. #else
  1285. // return TwMasterTransact(i2caddr[dev], wbuf, 1, val, 1, 0);
  1286. rc = TwMasterRegRead (i2caddr[dev], wbuf, 1, val, 1, 0);
  1287. MYPRINT("%s(%d,%d,0x%02x,0x%02x) => slave addr:0x%02x data 0x%02x\n",
  1288. __func__, dev, ch, reg, *val, i2caddr[dev], wbuf);
  1289. return rc;
  1290. #endif
  1291. }
  1292. /*@}*/