usart_cb_at91npl.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (C) 2012 by egnite GmbH
  3. * Copyright (C) 2001-2003 by egnite Software GmbH
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. Neither the name of the copyright holders nor the names of
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  30. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * For additional information see http://www.ethernut.de/
  34. */
  35. #include <dev/npl.h>
  36. #include <dev/usart.h>
  37. #include <arch/arm/atmel/usart_cb_at91npl.h>
  38. /*!
  39. * \file arch/arm/atmel/usart0cb_at91npl.c
  40. * \brief Low level routines for Ethernut 3 UARTs.
  41. *
  42. * Contains those functions, which are common to all internal UART
  43. * devices on Ethernut 3.
  44. *
  45. * \verbatim
  46. * $Id$
  47. * \endverbatim
  48. */
  49. static INLINE int CtsSense(void)
  50. {
  51. mem_wr16_mb(NPL_SCR, NPL_RSCTS);
  52. return (mem_rd16(NPL_SLR) & NPL_RSCTS) != 0;
  53. }
  54. void NplCtsInterrupt(void *arg)
  55. {
  56. USARTCB_DCB *dcb = (USARTCB_DCB *) arg;
  57. if (CtsSense()) {
  58. /* Disable CTS sense interrupt. */
  59. NplIrqDisable(&sig_RSCTS);
  60. /* Enable transmit interrupt. */
  61. mem_wr32(dcb->usart_hwif + US_IER_OFF, US_TXRDY);
  62. }
  63. }
  64. void NplUsartCbInterrupt(void *arg)
  65. {
  66. uint32_t sr;
  67. uint8_t ch;
  68. USARTCB_DCB *dcb = (USARTCB_DCB *) arg;
  69. cb_size_t idx;
  70. sr = mem_rd32(dcb->usart_hwif + US_CSR_OFF);
  71. sr &= mem_rd32(dcb->usart_hwif + US_IMR_OFF);
  72. if (sr & US_RXRDY) {
  73. USARTCB_RXBUFF *rxcb;
  74. ch = inb(dcb->usart_hwif + US_RHR_OFF);
  75. #if 0
  76. if (ch > 31 && ch < 127)
  77. putchar(ch);
  78. else
  79. putchar('.');
  80. #endif
  81. rxcb = &dcb->usart_rx_buff;
  82. idx = (rxcb->rxb_wri + 1) & rxcb->rxb_siz;
  83. if (idx == rxcb->rxb_rdi) {
  84. /* Receive buffer overflow. */
  85. mem_wr32(dcb->usart_hwif + US_IDR_OFF, US_RXRDY);
  86. } else {
  87. rxcb->rxb_buf[rxcb->rxb_wri] = ch;
  88. rxcb->rxb_wri = idx;
  89. if (rxcb->rxb_cnt++ == 0) {
  90. NutEventPostFromIrq(&rxcb->rxb_que);
  91. }
  92. if ((dcb->usart_mode & USART_MF_RTSCONTROL) != 0 && rxcb->rxb_cnt >= dcb->usart_rx_hiwm) {
  93. /* Disable handshake. */
  94. mem_wr8(NPL_RSCR, mem_rd8(NPL_RSCR) & ~NPL_RSRTS);
  95. }
  96. }
  97. }
  98. if (sr & US_TXRDY) {
  99. USARTCB_TXBUFF *txcb = &dcb->usart_tx_buff;
  100. idx = txcb->txb_rdi;
  101. if (idx == txcb->txb_wri) {
  102. /* Transmit buffer underrun. */
  103. mem_wr32(dcb->usart_hwif + US_IDR_OFF, US_TXRDY);
  104. NutEventPostFromIrq(&txcb->txb_que);
  105. }
  106. else if ((dcb->usart_mode & USART_MF_CTSSENSE) == 0 || CtsSense()) {
  107. //ch = txcb->txb_buf[idx];
  108. mem_wr32(dcb->usart_hwif + US_THR_OFF, txcb->txb_buf[idx]);
  109. txcb->txb_rdi = (idx + 1) & txcb->txb_siz;
  110. if (txcb->txb_cnt-- == txcb->txb_siz) {
  111. NutEventPostFromIrq(&txcb->txb_que);
  112. }
  113. #if 0
  114. if (ch > 31 && ch < 127)
  115. putchar(ch);
  116. else
  117. putchar('.');
  118. #endif
  119. }
  120. else {
  121. mem_wr32(dcb->usart_hwif + US_IDR_OFF, US_TXRDY);
  122. mem_wr16(NPL_IMR, mem_rd16(NPL_IMR) | NPL_RSCTS);
  123. }
  124. }
  125. }
  126. void NplUsartCbRxStart(USARTCB_DCB *dcb)
  127. {
  128. /* Enable receive interrupt. */
  129. mem_wr32(dcb->usart_hwif + US_IER_OFF, US_RXRDY);
  130. if (dcb->usart_mode & USART_MF_RTSCONTROL) {
  131. if (dcb->usart_rx_buff.rxb_cnt <= dcb->usart_rx_lowm) {
  132. /* Enable RTS handshake output. */
  133. mem_wr8(NPL_RSCR, mem_rd8(NPL_RSCR) | NPL_RSRTS);
  134. }
  135. }
  136. if (dcb->usart_mode & USART_MF_DTRCONTROL) {
  137. /* Enable DTR handshake output. */
  138. mem_wr8(NPL_RSCR, mem_rd8(NPL_RSCR) | NPL_RSDTR);
  139. }
  140. }
  141. void NplUsartCbTxStart(USARTCB_DCB *dcb)
  142. {
  143. if ((dcb->usart_mode & USART_MF_CTSSENSE) == 0 || CtsSense()) {
  144. /* Enable transmit interrupt. */
  145. mem_wr32(dcb->usart_hwif + US_IER_OFF, US_TXRDY);
  146. } else {
  147. /* Enable CTS interrupt. */
  148. NplIrqEnable(&sig_RSCTS);
  149. }
  150. }