mcf5_uart_debug.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * Copyright 2012 by Embedded Technologies s.r.o
  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. #include <cfg/peripherals.h>
  33. #include <arch/m68k.h>
  34. #include <dev/debug.h>
  35. #include <dev/gpio.h>
  36. #include <sys/timer.h>
  37. /*!
  38. * \brief Handle I/O controls for the debug device.
  39. *
  40. * \param dev Identifies the device that receives the device-control
  41. * request.
  42. * \param req Requested control function.
  43. * \param conf Points to a buffer that contains any data required for
  44. * the given control function or receives data from that
  45. * function.
  46. *
  47. * \return 0 on success, -1 if the function fails or is not available.
  48. */
  49. static int IOCtl(NUTDEVICE * dev, int req, void *conf)
  50. {
  51. return -1;
  52. }
  53. /*!
  54. * \brief Send a single character to debug device.
  55. *
  56. * The function will automatically prepend any newline character
  57. * (ASCII 10) with a carriage return character (ASCII 13).
  58. *
  59. * \param ch The character to send.
  60. */
  61. static void Put(uintptr_t devnum, char ch)
  62. {
  63. /* Prepend NL with CR. */
  64. if (ch == '\n') {
  65. Put(devnum, '\r');
  66. }
  67. /* Wait until space is available in the FIFO */
  68. while (!(MCF_UART_USR(devnum) & MCF_UART_USR_TXRDY))
  69. ;
  70. /* Send the character */
  71. MCF_UART_UTB(devnum) = (uint8_t) ch;
  72. }
  73. /*!
  74. * \brief Send a buffer contents to the debug device.
  75. *
  76. * This function is called by the low level input routines of the
  77. * \ref xrCrtLowio "C runtime library", using the _NUTDEVICE::dev_read
  78. * entry.
  79. *
  80. * Applications must not call this function, but use the stdio
  81. * functions instead.
  82. *
  83. * The debug driver is not interrupt driven and has no internal buffer
  84. * and no timeout control. Thus, it can be safely used in interrupt routines.
  85. * Of course, this will significantly decrease interrupt latency and overall
  86. * system performance.
  87. *
  88. * \param fp Identifies the device to send to. This may be used by
  89. * the driver to retrieve the \ref NUTDEVICE pointer.
  90. * \param buffer Pointer to the data to be written.
  91. * \param len Number of characters to write. If 0, then the caller
  92. * requests to flush the drivers internal output buffer.
  93. * In this case the pointer to the data is ignored.
  94. *
  95. * \return The number of characters written, which is the same as the
  96. * number of characters specified.
  97. */
  98. static int Write(NUTFILE * fp, const void *buffer, int len)
  99. {
  100. int c = len;
  101. const char *cp = (const char *) buffer;
  102. uintptr_t devnum = fp->nf_dev->dev_base;
  103. while (c--) {
  104. Put(devnum, *cp++);
  105. }
  106. return len;
  107. }
  108. /*!
  109. * \brief Read bytes from file
  110. *
  111. * \return Number of characters read.
  112. */
  113. static int Read(NUTFILE * nf, void *buffer, int len)
  114. {
  115. return 0;
  116. }
  117. /*!
  118. * \brief Open debug device.
  119. *
  120. * \return Pointer to a static NUTFILE structure.
  121. */
  122. static NUTFILE *Open(NUTDEVICE * dev, const char *name, int mode, int acc)
  123. {
  124. NUTFILE *fp = (NUTFILE *) (dev->dev_dcb);
  125. fp->nf_dev = dev;
  126. fp->nf_fcb = NULL;
  127. return fp;
  128. }
  129. /*!
  130. * \brief Close debug device.
  131. *
  132. * \param fp Pointer to a \ref _NUTFILE structure, obtained by a
  133. * previous call to ZeroDebugOpen().
  134. *
  135. * \return Always 0.
  136. */
  137. static int Close(NUTFILE * fp)
  138. {
  139. /* Nothing to do for this simple driver. */
  140. return 0;
  141. }
  142. /*!
  143. * \brief Initialize debug device.
  144. *
  145. * This function is called by NutRegisterDevice(), using the
  146. * _NUTDEVICE::dev_init entry.
  147. *
  148. * Applications must not call this function, they must call
  149. * NutRegisterDevice() instead.
  150. *
  151. * \param dev Pointer to the device information structure.
  152. *
  153. * \return Always 0.
  154. */
  155. static int Init(NUTDEVICE * dev)
  156. {
  157. uint8_t devnum = dev->dev_base;
  158. uint32_t sysclk = NutGetCpuClock();
  159. int baud = 115200;
  160. register uint16_t ubgs;
  161. /* Enable UART Port on GPIO */
  162. switch (devnum) {
  163. #ifdef UART0_TXD_PIN
  164. case 0:
  165. GpioPinConfigSet(UART0_TXD_PORT, UART0_TXD_PIN, UART0_TXD_PERIPHERAL);
  166. GpioPinConfigSet(UART0_RXD_PORT, UART0_RXD_PIN, UART0_RXD_PERIPHERAL);
  167. break;
  168. #endif
  169. #ifdef UART1_TXD_PIN
  170. case 1:
  171. GpioPinConfigSet(UART1_TXD_PORT, UART1_TXD_PIN, UART1_TXD_PERIPHERAL);
  172. GpioPinConfigSet(UART1_RXD_PORT, UART1_RXD_PIN, UART1_RXD_PERIPHERAL);
  173. break;
  174. #endif
  175. #ifdef UART2_TXD_PIN
  176. case 2:
  177. GpioPinConfigSet(UART2_TXD_PORT, UART2_TXD_PIN, UART2_TXD_PERIPHERAL);
  178. GpioPinConfigSet(UART2_RXD_PORT, UART2_RXD_PIN, UART2_RXD_PERIPHERAL);
  179. break;
  180. #endif
  181. default:
  182. return 0;
  183. }
  184. /* Reset Transmitter */
  185. MCF_UART_UCR(devnum) = MCF_UART_UCR_RESET_TX;
  186. /* Reset Receiver */
  187. MCF_UART_UCR(devnum) = MCF_UART_UCR_RESET_RX;
  188. /* Reset Mode Register */
  189. MCF_UART_UCR(devnum) = MCF_UART_UCR_RESET_MR;
  190. /* No parity, 8-bits per character */
  191. MCF_UART_UMR(devnum) = MCF_UART_UMR_PM_NONE | MCF_UART_UMR_BC_8;
  192. /* Normal mode(No echo or loopback), 1 stop bit */
  193. MCF_UART_UMR(devnum) = MCF_UART_UMR_CM_NORMAL | MCF_UART_UMR_SB_STOP_BITS_1;
  194. /* Select Rx and Tx clocks */
  195. MCF_UART_UCSR(devnum) = MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK;
  196. /* Calculate baud settings */
  197. ubgs = (uint16_t)(sysclk / (baud * 32));
  198. MCF_UART_UBG1(devnum) = (uint8_t)((ubgs & 0xFF00) >> 8);
  199. MCF_UART_UBG2(devnum) = (uint8_t)(ubgs & 0x00FF);
  200. /* Enable receiver and transmitter */
  201. MCF_UART_UCR(devnum) = MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED;
  202. return 0;
  203. }
  204. /*
  205. * While most drivers allocate this structure from the heap during
  206. * the open call and release it during close, this driver uses a
  207. * static structure. Therefore, concurrent open calls are not
  208. * allowed.
  209. */
  210. static NUTFILE dbgfile;
  211. /*!
  212. * \brief Debug device information structure.
  213. *
  214. * Usually, the device structure is the only public symbol that may be
  215. * referenced by the application code using
  216. *
  217. * \code
  218. * #include <dev/debug.h>
  219. *
  220. * {
  221. * ...
  222. * NutRegisterDevice(&devDebug0, 0, 0);
  223. * ...
  224. * }
  225. * \endcode
  226. *
  227. * If not referenced, the driver code (and this structure) will not be
  228. * included in the final binary.
  229. *
  230. * The name of the structure may differ among platforms. Portable
  231. * applications should avoid it and instead make use of dev/board.h.
  232. *
  233. * \code
  234. * #include <dev/board.h>
  235. *
  236. * {
  237. * ...
  238. * NutRegisterDevice(&DEV_DEBUG, 0, 0);
  239. * ...
  240. * }
  241. * \endcode
  242. *
  243. * While output is supported by default, input may be not. If input is
  244. * required, applications may replace \ref DEV_DEBUG by \ref DEV_CONSOLE.
  245. * In this case the debug driver is selected only, if it has input
  246. * capability (see \ref NUT_DEV_DEBUG_READ). Otherwise an interrupt
  247. * driven UART driver will be used.
  248. *
  249. * Note, that this polling driver has certain advantages
  250. * - very low memory usage
  251. * - allows stdio output functions in interrupt context
  252. * - allows stdio output functions in early system stage
  253. * - no internal buffering, output is synchronous
  254. * - atomic output with multiple threads
  255. *
  256. * but also some disadvantages
  257. * - concurrent threads are blocked during output
  258. * - most or all UART settings are hard coded
  259. * - may not work with non-ASCII (binary) data
  260. * - often only output is supported, not input
  261. * - only one instance (open) is allowed
  262. *
  263. * When used with Harvard architectures, additional functions may
  264. * be offered to access data in program space.
  265. */
  266. #ifdef UART0_TXD_PIN
  267. NUTDEVICE devDebug0 = {
  268. NULL, /*!< _NUTDEVICE::dev_next, must be NULL */
  269. { 'u', 'a', 'r', 't', '0', 0, 0, 0, 0 }, /*!< _NUTDEVICE::dev_name, use for all UART0 drivers. */
  270. IFTYP_CHAR, /*!< _NUTDEVICE::dev_type, probably not used, may be 0. */
  271. 0, /*!< _NUTDEVICE::dev_base, device number = 2(COM2). */
  272. 0, /*!< _NUTDEVICE::dev_irq, not used by this driver. */
  273. NULL, /*!< _NUTDEVICE::dev_icb, not used by this driver. */
  274. &dbgfile, /*!< _NUTDEVICE::dev_dcb, stores the \ref NUTFILE handle. */
  275. Init, /*!< _NUTDEVICE::dev_init. */
  276. IOCtl, /*!< _NUTDEVICE::dev_ioctl. */
  277. Read, /*!< _NUTDEVICE::dev_read, optional, may be NULL. */
  278. Write, /*!< _NUTDEVICE::dev_write. */
  279. Open, /*!< _NUTDEVICE::dev_open. */
  280. Close, /*!< _NUTDEVICE::dev_close. */
  281. NULL, /*!< _NUTDEVICE::dev_size, optional, may be NULL. */
  282. NULL, /*!< _NUTDEVICE::dev_select, optional, may be NULL */
  283. };
  284. #endif
  285. #ifdef UART1_TXD_PIN
  286. NUTDEVICE devDebug1 = {
  287. NULL, /*!< _NUTDEVICE::dev_next, must be NULL */
  288. { 'u', 'a', 'r', 't', '1', 0, 0, 0, 0 }, /*!< _NUTDEVICE::dev_name, use for all UART0 drivers. */
  289. IFTYP_CHAR, /*!< _NUTDEVICE::dev_type, probably not used, may be 0. */
  290. 1, /*!< _NUTDEVICE::dev_base, device number = 2(COM2). */
  291. 0, /*!< _NUTDEVICE::dev_irq, not used by this driver. */
  292. NULL, /*!< _NUTDEVICE::dev_icb, not used by this driver. */
  293. &dbgfile, /*!< _NUTDEVICE::dev_dcb, stores the \ref NUTFILE handle. */
  294. Init, /*!< _NUTDEVICE::dev_init. */
  295. IOCtl, /*!< _NUTDEVICE::dev_ioctl. */
  296. Read, /*!< _NUTDEVICE::dev_read, optional, may be NULL. */
  297. Write, /*!< _NUTDEVICE::dev_write. */
  298. Open, /*!< _NUTDEVICE::dev_open. */
  299. Close, /*!< _NUTDEVICE::dev_close. */
  300. NULL, /*!< _NUTDEVICE::dev_size, optional, may be NULL. */
  301. NULL, /*!< _NUTDEVICE::dev_select, optional, may be NULL */
  302. };
  303. #endif
  304. #ifdef UART2_TXD_PIN
  305. NUTDEVICE devDebug2 = {
  306. NULL, /*!< _NUTDEVICE::dev_next, must be NULL */
  307. { 'u', 'a', 'r', 't', '2', 0, 0, 0, 0 }, /*!< _NUTDEVICE::dev_name, use for all UART0 drivers. */
  308. IFTYP_CHAR, /*!< _NUTDEVICE::dev_type, probably not used, may be 0. */
  309. 2, /*!< _NUTDEVICE::dev_base, device number = 2(COM2). */
  310. 0, /*!< _NUTDEVICE::dev_irq, not used by this driver. */
  311. NULL, /*!< _NUTDEVICE::dev_icb, not used by this driver. */
  312. &dbgfile, /*!< _NUTDEVICE::dev_dcb, stores the \ref NUTFILE handle. */
  313. Init, /*!< _NUTDEVICE::dev_init. */
  314. IOCtl, /*!< _NUTDEVICE::dev_ioctl. */
  315. Read, /*!< _NUTDEVICE::dev_read, optional, may be NULL. */
  316. Write, /*!< _NUTDEVICE::dev_write. */
  317. Open, /*!< _NUTDEVICE::dev_open. */
  318. Close, /*!< _NUTDEVICE::dev_close. */
  319. NULL /*!< _NUTDEVICE::dev_size, optional, may be NULL. */
  320. NULL, /*!< _NUTDEVICE::dev_select, optional, may be NULL */
  321. };
  322. #endif