console.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * File : console.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2006-09-15 QiuYi the first version
  13. */
  14. #include <rtthread.h>
  15. #include <rthw.h>
  16. #include <bsp.h>
  17. //#include "serial.h"
  18. static unsigned addr_6845;
  19. static rt_uint16_t *crt_buf;
  20. static rt_int16_t crt_pos;
  21. //extern void rt_serial_init(void);
  22. extern char rt_keyboard_getc(void);
  23. //extern char rt_serial_getc(void);
  24. static void rt_console_putc(int c);
  25. /**
  26. * @addtogroup QEMU
  27. */
  28. /*@{*/
  29. /**
  30. * This function initializes cga
  31. *
  32. */
  33. void rt_cga_init(void)
  34. {
  35. rt_uint16_t volatile *cp;
  36. rt_uint16_t was;
  37. rt_uint32_t pos;
  38. cp = (rt_uint16_t *) (CGA_BUF);
  39. was = *cp;
  40. *cp = (rt_uint16_t) 0xA55A;
  41. if (*cp != 0xA55A)
  42. {
  43. cp = (rt_uint16_t *) (MONO_BUF);
  44. addr_6845 = MONO_BASE;
  45. }
  46. else
  47. {
  48. *cp = was;
  49. addr_6845 = CGA_BASE;
  50. }
  51. /* Extract cursor location */
  52. outb(addr_6845, 14);
  53. pos = inb(addr_6845+1) << 8;
  54. outb(addr_6845, 15);
  55. pos |= inb(addr_6845+1);
  56. crt_buf = (rt_uint16_t *)cp;
  57. crt_pos = pos;
  58. }
  59. /**
  60. * This function will write a character to cga
  61. *
  62. * @param c the char to write
  63. */
  64. static void rt_cga_putc(int c)
  65. {
  66. /* if no attribute given, then use black on white */
  67. if (!(c & ~0xff)) c |= 0x0700;
  68. switch (c & 0xff)
  69. {
  70. case '\b':
  71. if (crt_pos > 0)
  72. {
  73. crt_pos--;
  74. crt_buf[crt_pos] = (c&~0xff) | ' ';
  75. }
  76. break;
  77. case '\n':
  78. crt_pos += CRT_COLS;
  79. /* cascade */
  80. case '\r':
  81. crt_pos -= (crt_pos % CRT_COLS);
  82. break;
  83. case '\t':
  84. rt_console_putc(' ');
  85. rt_console_putc(' ');
  86. rt_console_putc(' ');
  87. rt_console_putc(' ');
  88. rt_console_putc(' ');
  89. break;
  90. default:
  91. crt_buf[crt_pos++] = c; /* write the character */
  92. break;
  93. }
  94. if (crt_pos >= CRT_SIZE)
  95. {
  96. rt_int32_t i;
  97. rt_memcpy(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) << 1);
  98. for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++)
  99. crt_buf[i] = 0x0700 | ' ';
  100. crt_pos -= CRT_COLS;
  101. }
  102. outb(addr_6845, 14);
  103. outb(addr_6845+1, crt_pos >> 8);
  104. outb(addr_6845, 15);
  105. outb(addr_6845+1, crt_pos);
  106. }
  107. /**
  108. * This function will write a character to serial an cga
  109. *
  110. * @param c the char to write
  111. */
  112. static void rt_console_putc(int c)
  113. {
  114. rt_cga_putc(c);
  115. // rt_serial_putc(c);
  116. }
  117. /* RT-Thread Device Interface */
  118. #define CONSOLE_RX_BUFFER_SIZE 64
  119. static struct rt_device console_device;
  120. static rt_uint8_t rx_buffer[CONSOLE_RX_BUFFER_SIZE];
  121. static rt_uint32_t read_index, save_index;
  122. static rt_err_t rt_console_init (rt_device_t dev)
  123. {
  124. return RT_EOK;
  125. }
  126. static rt_err_t rt_console_open(rt_device_t dev, rt_uint16_t oflag)
  127. {
  128. return RT_EOK;
  129. }
  130. static rt_err_t rt_console_close(rt_device_t dev)
  131. {
  132. return RT_EOK;
  133. }
  134. static rt_err_t rt_console_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  135. {
  136. return RT_EOK;
  137. }
  138. static rt_size_t rt_console_write(rt_device_t dev, rt_off_t pos, const void * buffer, rt_size_t size)
  139. {
  140. rt_size_t i = size;
  141. const char* str = buffer;
  142. while(i--)
  143. {
  144. rt_console_putc(*str++);
  145. }
  146. return size;
  147. }
  148. static rt_size_t rt_console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  149. {
  150. rt_uint8_t* ptr = buffer;
  151. rt_err_t err_code = RT_EOK;
  152. /* interrupt mode Rx */
  153. while (size)
  154. {
  155. rt_base_t level;
  156. /* disable interrupt */
  157. level = rt_hw_interrupt_disable();
  158. if (read_index != save_index)
  159. {
  160. /* read a character */
  161. *ptr++ = rx_buffer[read_index];
  162. size--;
  163. /* move to next position */
  164. read_index ++;
  165. if (read_index >= CONSOLE_RX_BUFFER_SIZE)
  166. read_index = 0;
  167. }
  168. else
  169. {
  170. /* set error code */
  171. err_code = -RT_EEMPTY;
  172. /* enable interrupt */
  173. rt_hw_interrupt_enable(level);
  174. break;
  175. }
  176. /* enable interrupt */
  177. rt_hw_interrupt_enable(level);
  178. }
  179. /* set error code */
  180. rt_set_errno(err_code);
  181. return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
  182. }
  183. static void rt_console_isr(int vector, void* param)
  184. {
  185. char c;
  186. rt_base_t level;
  187. while(1)
  188. {
  189. c = rt_keyboard_getc();
  190. if(c == 0)
  191. {
  192. break;
  193. }
  194. else if(c > 0)
  195. {
  196. /* disable interrupt */
  197. level = rt_hw_interrupt_disable();
  198. /* save character */
  199. rx_buffer[save_index] = c;
  200. save_index ++;
  201. if (save_index >= CONSOLE_RX_BUFFER_SIZE)
  202. save_index = 0;
  203. /* if the next position is read index, discard this 'read char' */
  204. if (save_index == read_index)
  205. {
  206. read_index ++;
  207. if (read_index >= CONSOLE_RX_BUFFER_SIZE)
  208. read_index = 0;
  209. }
  210. /* enable interrupt */
  211. rt_hw_interrupt_enable(level);
  212. }
  213. }
  214. /* invoke callback */
  215. if (console_device.rx_indicate != RT_NULL)
  216. {
  217. rt_size_t rx_length;
  218. /* get rx length */
  219. rx_length = read_index > save_index ?
  220. CONSOLE_RX_BUFFER_SIZE - read_index + save_index :
  221. save_index - read_index;
  222. // rt_kprintf("\r\nrx_length %d\r\n", rx_length);
  223. if(rx_length > 0)
  224. {
  225. console_device.rx_indicate(&console_device, rx_length);
  226. }
  227. }
  228. else
  229. {
  230. // rt_kprintf("\r\nconsole_device.rx_indicate == RT_NULL\r\n");
  231. }
  232. }
  233. /**
  234. * This function initializes console
  235. *
  236. */
  237. void rt_hw_console_init(void)
  238. {
  239. rt_cga_init();
  240. /* install keyboard isr */
  241. rt_hw_interrupt_install(INTKEYBOARD, rt_console_isr, RT_NULL, "kbd");
  242. rt_hw_interrupt_umask(INTKEYBOARD);
  243. console_device.type = RT_Device_Class_Char;
  244. console_device.rx_indicate = RT_NULL;
  245. console_device.tx_complete = RT_NULL;
  246. console_device.init = rt_console_init;
  247. console_device.open = rt_console_open;
  248. console_device.close = rt_console_close;
  249. console_device.read = rt_console_read;
  250. console_device.write = rt_console_write;
  251. console_device.control = rt_console_control;
  252. console_device.user_data = RT_NULL;
  253. /* register a character device */
  254. rt_device_register(&console_device,
  255. "console",
  256. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
  257. }
  258. /**
  259. * This function is used to display a string on console, normally, it's
  260. * invoked by rt_kprintf
  261. *
  262. * @param str the displayed string
  263. *
  264. * Modified:
  265. * caoxl 2009-10-14
  266. * the name is change to rt_hw_console_output in the v0.3.0
  267. *
  268. */
  269. void rt_hw_console_output(const char* str)
  270. {
  271. while (*str)
  272. {
  273. rt_console_putc (*str++);
  274. }
  275. }
  276. /*@}*/