PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
esos_pc_stdio.c
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 // Documentation for this file. If the \file tag isn't present,
31 // this file won't be documented.
32 /*
33  * To do.
34  */
35 
36 /*** I N C L U D E S ****
37 *********************************************/
38 #include "esos_pc_stdio.h"
39 #ifdef USE_NCURSES
40 #include <ncurses.h>
41 #else
42 #include <stdio.h>
43 #include <sys/select.h>
44 #include <termios.h>
45 #include <unistd.h>
46 #endif
47 
48 
49 
50 //#define USE_NCURSES
51 
52 /*** G L O B A L S *************************************************/
53 struct termios stored_settings;
54 
55 /*** T H E C O D E *************************************************/
56 
57 /*********************************************************
58  * Public functions intended to be called by other files *
59  *********************************************************/
60 void __esos_hw_signal_start_tx(void) {
61  while (__st_TxBuffer.u16_Head != __st_TxBuffer.u16_Tail) {
62  __st_TxBuffer.u16_Tail++; //increment tail pointer
63  if (__st_TxBuffer.u16_Tail == ESOS_SERIAL_IN_EP_SIZE)
64  __st_TxBuffer.u16_Tail = 0; //wrap if needed
65  //transfer character from software buffer to transmit buffer
66 #ifdef USE_NCURSES
67  waddch( __st_TxBuffer.pau8_Data[__st_TxBuffer.u16_Tail] );
68 #else
69  printf("%c", __st_TxBuffer.pau8_Data[__st_TxBuffer.u16_Tail]);
70  // make the stdout do its thing right away
71  fflush(stdout);
72 #endif
73  }
74 }
75 
76 void __esos_hw_signal_stop_tx(void) {
77 
78 }
79 
80 ESOS_USER_TASK( __Linux_check_keyboard ) {
81  static uint8_t u8_c;
82 
84  set_keypress();
85  while (TRUE) {
86  ESOS_TASK_WAIT_UNTIL( kbhit() );
87  u8_c = getchar(); //read character
88  __st_RxBuffer.u16_Head++; //increment head pointer
89  if (__st_RxBuffer.u16_Head == ESOS_SERIAL_OUT_EP_SIZE)
90  __st_RxBuffer.u16_Head = 0; //wrap if needed
91 
92  __st_RxBuffer.pau8_Data[__st_RxBuffer.u16_Head] = u8_c; //place in buffer
93  } // endof while(TRUE)
94  ESOS_TASK_END();
95 } // endof TASK
96 
97 
98 /*
99 ** POSIX systems do NOT have a kbhit() function in their stdio
100 ** libraries. So we will write our own here. This function
101 ** returns TRUE when there is some keypress, else FALSE. So,
102 ** we can poll or wait on kbhit(). When it is true, we can
103 ** call the normal getch()
104 */
105 uint8_t kbhit(void) {
106  struct timeval tv;
107  fd_set read_fd;
108 
109  tv.tv_sec = 0;
110  tv.tv_usec = 0;
111  FD_ZERO(&read_fd);
112  FD_SET(0,&read_fd);
113 
114  if (select(1, &read_fd, NULL, NULL, &tv) == -1)
115  return FALSE;
116 
117  if (FD_ISSET(0,&read_fd))
118  return TRUE;
119 
120  return FALSE;
121 } //end kbhit())
122 
123 
124 void set_keypress(void) {
125  struct termios new_settings;
126 
127  tcgetattr(0,&stored_settings);
128  new_settings = stored_settings;
129 
130  /* Disable canonical mode, set buffer size to 1 byte, turn OFF echo */
131  new_settings.c_lflag &= (~ICANON);
132  new_settings.c_cc[VTIME] = 0;
133  new_settings.c_cc[VMIN] = 1;
134  new_settings.c_lflag &= (~ECHO);
135  tcsetattr(0,TCSANOW,&new_settings);
136  return;
137 }
138 
139 void reset_keypress(void) {
140  tcsetattr(0,TCSANOW,&stored_settings);
141  return;
142 }
143 
144 
145 
146 /* ########################################################################### */
147 
148 
149 /******************************************************************************
150  * Function: void _esos_hw_InitSerialUart( void )
151  *
152  * PreCondition: None
153  *
154  * Input: None
155  *
156  * Output: ptr to ESOS_COMM_BUFF_DSC structure with initialized ptrs
157  *
158  * Side Effects: Turns on USART hardware
159  *
160  *****************************************************************************/
161 void __esos_hw_InitCommSystem(void) {
162  // Init the NCURSES system instead of the serial port....
163  uint8_t u8_char;
164 
165 #if 0
166  initscr(); /* Start curses mode */
167  raw(); /* Line buffering disabled */
168  keypad(stdscr, TRUE); /* We get F1, F2 etc.. */
169  noecho(); /* Don't echo() while we do getch */
170 
171  printw("Hello from ESOS -- the PC/Linux version w/ NCURSES\n");
172  refresh(); /* Print it on to the real screen */
173  getch(); /* Wait for user input */
174 #else
175  printf ("Hello from ESOS -- the PC/Linux version\n");
176 #endif
177 
178  // Since the PC does not support background interrupts (easily),
179  // we will just mimic that by creating an ESOS task to read the
180  // from the keyboard. The transmits will be done with printf
181  // and occur immediately.
182  //
183  // NOTE: When this task runs, the KDE debugger (kdbg) does not
184  // run very well. When stepping, try to structure the application
185  // to run without input from stdin and COMMENT OUT THE FOLLOWING LINE!
186  esos_RegisterTask( __Linux_check_keyboard );
187 
188 } // end __esos_hw_InitCommSystem()
189 
190 
191 /******************************************************************************
192  * Function: uint8_t esos_GetCommSystemMaxInDataLen(void)
193  *
194  * PreCondition: None.
195  *
196  * Input: None
197  *
198  * Output: the maximum number of uint8_ts that the comm system will
199  * receive in a single buffer transfer from the host -- OR --
200  * in the case of single uint8_t xfers (like RS232), the maximum
201  * number of uint8_ts that can be RX-ed before the buffers
202  * overflow
203  *
204  * Side Effects: None
205  *
206  * Overview: A way for a run-time determination of the maximum buffer
207  * size that the user can can expect. This number is
208  * actually hard-coded in the USB CDC header file, but this
209  * method will allow the user code to be more generic, if
210  * it chooses to be.
211  *
212  *****************************************************************************/
214  return ESOS_SERIAL_OUT_EP_SIZE;
215 } //end esos_GetCommSystemMaxInDataLen()
216 
217 /******************************************************************************
218  * Function: uint8_t esos_GetCommSystemMaxOutDataLen(void)
219  *
220  * PreCondition: None.
221  *
222  * Input: None
223  *
224  * Output: the maximum number of uint8_ts that the comm system will
225  * transfer back to the host in a single buffer -- OR --
226  * in the case of singe uint8_t xfers (like RS232), the maximum
227  * number of uint8_ts in the output buffer before overflow
228  *
229  * Side Effects: None
230  *
231  * Overview: A way for a run-time determination of the maximum buffer
232  * size that the user can can send efficiently. The USB system
233  * will send a bigger buffer than getUSBCdcTxMax() size, but
234  * will do so in several smaller getUSBCdcTxMax()-sized chunks.
235  *
236  * This number is actually hard-coded in the USB CDC header file,
237  * but this method will allow the user code to be more generic,
238  * if it chooses to be.
239  *
240  *****************************************************************************/
242  return ESOS_SERIAL_IN_EP_SIZE;
243 } //end esos_GetCommSystemMaxOutDataLen()
244 
245 /******************************************************************************
246  * Function: uint8_t _esos_hw_GetUartVersion(void)
247  *
248  * PreCondition: None.
249  *
250  * Input: None
251  *
252  * Output: Return the version number of the MSU Bulk CDC driver firmware
253  * currently running.
254  * The most-significant bit denotes we're running USB
255  * The most-significant nibble is the major revision number
256  * The least-significant nibble is the minor revision number
257  *
258  * Side Effects: None
259  *
260  *****************************************************************************/
261 uint8_t _esos_hw_GetSerialUartVersion(void) {
262  return ESOS_COMM_SYS_SERIAL_REV;
263 } //end _esos_hw_GetUartVersion()