debug_at91.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright (C) 2001-2006 by egnite Software GmbH
  3. * Copyright (C) 2010-2011 by egnite 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. /*!
  36. * \file arch/arm/dev/debug_at91.c
  37. * \brief AT91 debug output device.
  38. *
  39. * \verbatim
  40. * $Id: debug_at91.c 5472 2013-12-06 00:16:28Z olereinhardt $
  41. * \endverbatim
  42. */
  43. #include <cfg/uart.h>
  44. #include <arch/arm/atmel/debug_at91.h>
  45. #include <dev/debug.h>
  46. #include <sys/timer.h>
  47. /*!
  48. * \addtogroup xgDevDebugAt91
  49. */
  50. /*@{*/
  51. /*!
  52. * \brief Calculate divisor for a given baud rate.
  53. *
  54. * \param baud Baud rate.
  55. *
  56. * \return Calculated divisor.
  57. */
  58. uint32_t At91BaudRateDiv(uint32_t baud)
  59. {
  60. return (NutClockGet(NUT_HWCLK_PERIPHERAL) / (8 * baud) + 1) / 2;
  61. }
  62. /*!
  63. * \brief Handle I/O controls for debug device 2.
  64. *
  65. * The debug device supports UART_SETSPEED only.
  66. *
  67. * \return 0 on success, -1 otherwise.
  68. */
  69. int At91DevDebugIOCtl(NUTDEVICE * dev, int req, void *conf)
  70. {
  71. if(req == UART_SETSPEED) {
  72. outr(dev->dev_base + US_BRGR_OFF, At91BaudRateDiv(*((uint32_t *)conf)));
  73. return 0;
  74. }
  75. return -1;
  76. }
  77. /*!
  78. * \brief Send a single character to debug device 0.
  79. *
  80. * A newline character will be automatically prepended
  81. * by a carriage return.
  82. */
  83. static void DebugPut(const NUTDEVICE * dev, char ch)
  84. {
  85. if (ch == '\n') {
  86. while ((inr(dev->dev_base + US_CSR_OFF) & US_TXRDY) == 0);
  87. outr(dev->dev_base + US_THR_OFF, '\r');
  88. }
  89. while ((inr(dev->dev_base + US_CSR_OFF) & US_TXRDY) == 0);
  90. outr(dev->dev_base + US_THR_OFF, ch);
  91. }
  92. /*!
  93. * \brief Send characters to debug device 0.
  94. *
  95. * A newline character will be automatically prepended
  96. * by a carriage return.
  97. *
  98. * \return Number of characters sent.
  99. */
  100. int At91DevDebugWrite(NUTFILE * fp, const void *buffer, int len)
  101. {
  102. int c = len;
  103. const char *cp = buffer;
  104. while (c--) {
  105. DebugPut(fp->nf_dev, *cp++);
  106. }
  107. return len;
  108. }
  109. #ifdef NUT_DEV_DEBUG_READ
  110. /*!
  111. * \brief Read characters from debug device.
  112. *
  113. * This function is called by the low level input routines of the
  114. * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_read
  115. * entry.
  116. *
  117. * The function will block the calling thread until at least one
  118. * character has been received.
  119. *
  120. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a
  121. * previous call to At91DevDebugOpen().
  122. * \param buffer Pointer to the buffer that receives the data. If zero,
  123. * then all characters in the input buffer will be
  124. * removed.
  125. * \param size Maximum number of bytes to read.
  126. *
  127. * \return The number of bytes read, which may be less than the number
  128. * of bytes specified. A return value of -1 indicates an error,
  129. * while zero is returned in case of a timeout.
  130. */
  131. int At91DevDebugRead(NUTFILE * fp, void *buffer, int size)
  132. {
  133. int rc;
  134. unsigned int ch;
  135. char *bp = (char *) buffer;
  136. /* Wait for the first character, forever. */
  137. for (rc = 0; rc < size; rc++) {
  138. while ((inr(fp->nf_dev->dev_base + US_CSR_OFF) & US_RXRDY) == 0) {
  139. NutSleep(1);
  140. if ((rc || bp == NULL) &&
  141. (inr(fp->nf_dev->dev_base + US_CSR_OFF) & US_RXRDY) == 0) {
  142. return rc;
  143. }
  144. }
  145. ch = inr(fp->nf_dev->dev_base + US_RHR_OFF);
  146. if (bp) {
  147. if (ch == '\r') {
  148. *bp++ = '\n';
  149. } else {
  150. *bp++ = (char) ch;
  151. }
  152. }
  153. }
  154. return rc;
  155. }
  156. /*!
  157. * \brief Retrieves the number of characters in input buffer.
  158. *
  159. * This function is called by the low level size routine of the C runtime
  160. * library, using the _NUTDEVICE::dev_size entry.
  161. *
  162. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a
  163. * previous call to UsartOpen().
  164. *
  165. * \return The number of bytes currently stored in input buffer.
  166. */
  167. long At91DevDebugSize(NUTFILE *fp)
  168. {
  169. if (inr(fp->nf_dev->dev_base + US_CSR_OFF) & US_RXRDY) {
  170. return 1;
  171. }
  172. return 0;
  173. }
  174. #endif
  175. /*!
  176. * \brief Open debug device.
  177. *
  178. * \return Pointer to a static NUTFILE structure.
  179. */
  180. NUTFILE *At91DevDebugOpen(NUTDEVICE * dev, const char *name, int mode, int acc)
  181. {
  182. NUTFILE *fp = (NUTFILE *) (dev->dev_dcb);
  183. fp->nf_dev = dev;
  184. fp->nf_fcb = NULL;
  185. return fp;
  186. }
  187. /*!
  188. * \brief Close debug device.
  189. *
  190. * \return Always 0.
  191. */
  192. int At91DevDebugClose(NUTFILE * fp)
  193. {
  194. return 0;
  195. }
  196. /*@}*/