lpc_debug.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright (C) 2011-2012 by egnite GmbH
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. #include <cfg/uart.h>
  35. #include <dev/debug.h>
  36. #include <sys/timer.h>
  37. #include <arch/cm3/nxp/mach/lpc1700.h>
  38. #include <arch/cm3/nxp/lpc_debug.h>
  39. /*!
  40. * \addtogroup xgDevDebugLpc
  41. */
  42. /*@{*/
  43. /*!
  44. * \brief Open debug device.
  45. *
  46. * \param dev Pointer to a previously registered \ref NUTDEVICE structure.
  47. * \param name Ignored, typically points to an empty string.
  48. * \param mode Ignored, operation mode.
  49. * \param acc Ignored, should be zero.
  50. *
  51. * \return Pointer to a static NUTFILE structure.
  52. */
  53. NUTFILE *LpcDevDebugOpen(NUTDEVICE * dev, const char *name, int mode, int acc)
  54. {
  55. NUTFILE *fp = (NUTFILE *) (dev->dev_dcb);
  56. fp->nf_dev = dev;
  57. fp->nf_fcb = NULL;
  58. return fp;
  59. }
  60. /*!
  61. * \brief Close debug device.
  62. *
  63. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a previous
  64. * call to LpcDevDebugOpen().
  65. *
  66. * \return Always 0.
  67. */
  68. int LpcDevDebugClose(NUTFILE * fp)
  69. {
  70. return 0;
  71. }
  72. /*!
  73. * \brief Handle I/O controls for debug device 2.
  74. *
  75. * The debug device supports UART_SETSPEED only.
  76. *
  77. * \param dev Identifies the device that receives the device-control
  78. * function.
  79. * \param req Requested control function. May be set to one of the
  80. * following constants:
  81. * - UART_SETSPEED, conf points to an uint32_t value containing the baudrate.
  82. * \param conf Points to a variable that contains any data required for
  83. * the given control function or receives data from that
  84. * function.
  85. *
  86. * \return 0 on success, -1 otherwise.
  87. */
  88. int LpcDevDebugIOCtl(NUTDEVICE * dev, int req, void *conf)
  89. {
  90. return -1;
  91. }
  92. /*!
  93. * \brief Send a single character to debug device.
  94. *
  95. * A newline character will be automatically prepended by a carriage
  96. * return.
  97. */
  98. static void DebugPut(const NUTDEVICE * dev, char ch)
  99. {
  100. if (ch == '\n') {
  101. DebugPut(dev, '\r');
  102. }
  103. while ((mem_rd32(dev->dev_base + UART_LSR_OFF) & UART_THRE) == 0);
  104. mem_wr32_mb(dev->dev_base + UART_THR_OFF, ch);
  105. }
  106. /*!
  107. * \brief Send characters to debug device 0.
  108. *
  109. * This function is called by the low level input routines of the
  110. * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_write
  111. * entry.
  112. *
  113. * A newline character will be automatically prepended by a carriage
  114. * return.
  115. *
  116. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a previous
  117. * call to LpcDevDebugOpen().
  118. *
  119. * \return Number of characters sent.
  120. */
  121. int LpcDevDebugWrite(NUTFILE * fp, const void *buffer, int len)
  122. {
  123. int c = len;
  124. const char *cp = buffer;
  125. while (c--) {
  126. DebugPut(fp->nf_dev, *cp++);
  127. }
  128. return len;
  129. }
  130. #ifdef NUT_DEV_DEBUG_READ
  131. /*!
  132. * \brief Read characters from debug device.
  133. *
  134. * This function is called by the low level input routines of the
  135. * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_read
  136. * entry.
  137. *
  138. * The function will block the calling thread until at least one
  139. * character has been received.
  140. *
  141. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a
  142. * previous call to LpcDevDebugOpen().
  143. * \param buffer Pointer to the buffer that receives the data. If zero,
  144. * then all characters in the input buffer will be
  145. * removed.
  146. * \param size Maximum number of bytes to read.
  147. *
  148. * \return The number of bytes read, which may be less than the number
  149. * of bytes specified. A return value of -1 indicates an error,
  150. * while zero is returned in case of a timeout.
  151. */
  152. int LpcDevDebugRead(NUTFILE * fp, void *buffer, int size)
  153. {
  154. int rc;
  155. unsigned int ch;
  156. char *bp = (char *) buffer;
  157. /* Wait for the first character, forever. */
  158. for (rc = 0; rc < size; rc++) {
  159. while ((mem_rd32(fp->nf_dev->dev_base + UART_LSR_OFF) & UART_RDR) == 0) {
  160. NutSleep(1);
  161. if ((rc || bp == NULL) &&
  162. (mem_rd32(fp->nf_dev->dev_base + UART_LSR_OFF) & UART_RDR) == 0) {
  163. return rc;
  164. }
  165. }
  166. ch = mem_rd32_mb(fp->nf_dev->dev_base + UART_RBR_OFF);
  167. if (bp) {
  168. if (ch == '\r') {
  169. *bp++ = '\n';
  170. } else {
  171. *bp++ = (char) ch;
  172. }
  173. }
  174. }
  175. return rc;
  176. }
  177. /*!
  178. * \brief Retrieves the number of characters in input buffer.
  179. *
  180. * This function is called by the low level size routine of the C runtime
  181. * library, using the _NUTDEVICE::dev_size entry.
  182. *
  183. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a previous
  184. * call to LpcDevDebugOpen().
  185. *
  186. * \return The number of bytes currently stored in input buffer.
  187. */
  188. long LpcDevDebugSize(NUTFILE *fp)
  189. {
  190. if (mem_rd32(fp->nf_dev->dev_base + UART_LSR_OFF) & UART_RDR) {
  191. return 1;
  192. }
  193. return 0;
  194. }
  195. #endif /* NUT_DEV_DEBUG_READ */
  196. /*@}*/