00001 /* 00002 * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")" 00003 * All rights reserved. 00004 * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University) 00005 * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University) 00006 * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University) 00007 * 00008 * Permission to use, copy, modify, and distribute this software and its 00009 * documentation for any purpose, without fee, and without written agreement is 00010 * hereby granted, provided that the above copyright notice, the following 00011 * two paragraphs and the authors appear in all copies of this software. 00012 * 00013 * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR 00014 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT 00015 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS" 00016 * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00017 * 00018 * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES, 00019 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00020 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 00021 * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO 00022 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." 00023 * 00024 * Please maintain this header in its entirety when copying/modifying 00025 * these files. 00026 * 00027 * 00028 */ 00029 00030 // Documentation for this file. If the \file tag isn't present, 00031 // this file won't be documented. 00032 /* 00033 * To do. 00034 */ 00035 00036 /*** I N C L U D E S **** 00037 *********************************************/ 00038 #include "esos_pc_stdio.h" 00039 #ifdef USE_NCURSES 00040 #include <ncurses.h> 00041 #else 00042 #include <stdio.h> 00043 #include <sys/select.h> 00044 #include <termios.h> 00045 #include <unistd.h> 00046 #endif 00047 00048 00049 00050 //#define USE_NCURSES 00051 00052 /*** G L O B A L S *************************************************/ 00053 struct termios stored_settings; 00054 00055 /*** T H E C O D E *************************************************/ 00056 00057 /********************************************************* 00058 * Public functions intended to be called by other files * 00059 *********************************************************/ 00060 void __esos_hw_signal_start_tx(void) { 00061 while (__st_TxBuffer.u16_Head != __st_TxBuffer.u16_Tail) { 00062 __st_TxBuffer.u16_Tail++; //increment tail pointer 00063 if (__st_TxBuffer.u16_Tail == ESOS_SERIAL_IN_EP_SIZE) 00064 __st_TxBuffer.u16_Tail = 0; //wrap if needed 00065 //transfer character from software buffer to transmit buffer 00066 #ifdef USE_NCURSES 00067 waddch( __st_TxBuffer.pau8_Data[__st_TxBuffer.u16_Tail] ); 00068 #else 00069 printf("%c", __st_TxBuffer.pau8_Data[__st_TxBuffer.u16_Tail]); 00070 // make the stdout do its thing right away 00071 fflush(stdout); 00072 #endif 00073 } 00074 } 00075 00076 void __esos_hw_signal_stop_tx(void) { 00077 00078 } 00079 00080 ESOS_USER_TASK( __Linux_check_keyboard ) { 00081 static uint8 u8_c; 00082 00083 ESOS_TASK_BEGIN(); 00084 set_keypress(); 00085 while (TRUE) { 00086 ESOS_TASK_WAIT_UNTIL( kbhit() ); 00087 u8_c = getchar(); //read character 00088 __st_RxBuffer.u16_Head++; //increment head pointer 00089 if (__st_RxBuffer.u16_Head == ESOS_SERIAL_OUT_EP_SIZE) 00090 __st_RxBuffer.u16_Head = 0; //wrap if needed 00091 00092 __st_RxBuffer.pau8_Data[__st_RxBuffer.u16_Head] = u8_c; //place in buffer 00093 } // endof while(TRUE) 00094 ESOS_TASK_END(); 00095 } // endof TASK 00096 00097 00098 /* 00099 ** POSIX systems do NOT have a kbhit() function in their stdio 00100 ** libraries. So we will write our own here. This function 00101 ** returns TRUE when there is some keypress, else FALSE. So, 00102 ** we can poll or wait on kbhit(). When it is true, we can 00103 ** call the normal getch() 00104 */ 00105 uint8 kbhit(void) { 00106 struct timeval tv; 00107 fd_set read_fd; 00108 00109 tv.tv_sec = 0; 00110 tv.tv_usec = 0; 00111 FD_ZERO(&read_fd); 00112 FD_SET(0,&read_fd); 00113 00114 if (select(1, &read_fd, NULL, NULL, &tv) == -1) 00115 return FALSE; 00116 00117 if (FD_ISSET(0,&read_fd)) 00118 return TRUE; 00119 00120 return FALSE; 00121 } //end kbhit()) 00122 00123 00124 void set_keypress(void) { 00125 struct termios new_settings; 00126 00127 tcgetattr(0,&stored_settings); 00128 new_settings = stored_settings; 00129 00130 /* Disable canonical mode, set buffer size to 1 byte, turn OFF echo */ 00131 new_settings.c_lflag &= (~ICANON); 00132 new_settings.c_cc[VTIME] = 0; 00133 new_settings.c_cc[VMIN] = 1; 00134 new_settings.c_lflag &= (~ECHO); 00135 tcsetattr(0,TCSANOW,&new_settings); 00136 return; 00137 } 00138 00139 void reset_keypress(void) { 00140 tcsetattr(0,TCSANOW,&stored_settings); 00141 return; 00142 } 00143 00144 00145 00146 /* ########################################################################### */ 00147 00148 00149 /****************************************************************************** 00150 * Function: void _esos_hw_InitSerialUart( void ) 00151 * 00152 * PreCondition: None 00153 * 00154 * Input: None 00155 * 00156 * Output: ptr to ESOS_COMM_BUFF_DSC structure with initialized ptrs 00157 * 00158 * Side Effects: Turns on USART hardware 00159 * 00160 *****************************************************************************/ 00161 void __esos_hw_InitCommSystem(void) { 00162 // Init the NCURSES system instead of the serial port.... 00163 uint8 u8_char; 00164 00165 #if 0 00166 initscr(); /* Start curses mode */ 00167 raw(); /* Line buffering disabled */ 00168 keypad(stdscr, TRUE); /* We get F1, F2 etc.. */ 00169 noecho(); /* Don't echo() while we do getch */ 00170 00171 printw("Hello from ESOS -- the PC/Linux version w/ NCURSES\n"); 00172 refresh(); /* Print it on to the real screen */ 00173 getch(); /* Wait for user input */ 00174 #else 00175 printf ("Hello from ESOS -- the PC/Linux version\n"); 00176 #endif 00177 00178 // Since the PC does not support background interrupts (easily), 00179 // we will just mimic that by creating an ESOS task to read the 00180 // from the keyboard. The transmits will be done with printf 00181 // and occur immediately. 00182 // 00183 // NOTE: When this task runs, the KDE debugger (kdbg) does not 00184 // run very well. When stepping, try to structure the application 00185 // to run without input from stdin and COMMENT OUT THE FOLLOWING LINE! 00186 esos_RegisterTask( __Linux_check_keyboard ); 00187 00188 } // end __esos_hw_InitCommSystem() 00189 00190 00191 /****************************************************************************** 00192 * Function: uint8 esos_GetCommSystemMaxInDataLen(void) 00193 * 00194 * PreCondition: None. 00195 * 00196 * Input: None 00197 * 00198 * Output: the maximum number of uint8s that the comm system will 00199 * receive in a single buffer transfer from the host -- OR -- 00200 * in the case of single uint8 xfers (like RS232), the maximum 00201 * number of uint8s that can be RX-ed before the buffers 00202 * overflow 00203 * 00204 * Side Effects: None 00205 * 00206 * Overview: A way for a run-time determination of the maximum buffer 00207 * size that the user can can expect. This number is 00208 * actually hard-coded in the USB CDC header file, but this 00209 * method will allow the user code to be more generic, if 00210 * it chooses to be. 00211 * 00212 *****************************************************************************/ 00213 uint8 esos_GetCommSystemMaxInDataLen(void) { 00214 return ESOS_SERIAL_OUT_EP_SIZE; 00215 } //end esos_GetCommSystemMaxInDataLen() 00216 00217 /****************************************************************************** 00218 * Function: uint8 esos_GetCommSystemMaxOutDataLen(void) 00219 * 00220 * PreCondition: None. 00221 * 00222 * Input: None 00223 * 00224 * Output: the maximum number of uint8s that the comm system will 00225 * transfer back to the host in a single buffer -- OR -- 00226 * in the case of singe uint8 xfers (like RS232), the maximum 00227 * number of uint8s in the output buffer before overflow 00228 * 00229 * Side Effects: None 00230 * 00231 * Overview: A way for a run-time determination of the maximum buffer 00232 * size that the user can can send efficiently. The USB system 00233 * will send a bigger buffer than getUSBCdcTxMax() size, but 00234 * will do so in several smaller getUSBCdcTxMax()-sized chunks. 00235 * 00236 * This number is actually hard-coded in the USB CDC header file, 00237 * but this method will allow the user code to be more generic, 00238 * if it chooses to be. 00239 * 00240 *****************************************************************************/ 00241 uint8 esos_GetCommSystemMaxOutDataLen(void) { 00242 return ESOS_SERIAL_IN_EP_SIZE; 00243 } //end esos_GetCommSystemMaxOutDataLen() 00244 00245 /****************************************************************************** 00246 * Function: uint8 _esos_hw_GetUartVersion(void) 00247 * 00248 * PreCondition: None. 00249 * 00250 * Input: None 00251 * 00252 * Output: Return the version number of the MSU Bulk CDC driver firmware 00253 * currently running. 00254 * The most-significant bit denotes we're running USB 00255 * The most-significant nibble is the major revision number 00256 * The least-significant nibble is the minor revision number 00257 * 00258 * Side Effects: None 00259 * 00260 *****************************************************************************/ 00261 uint8 _esos_hw_GetSerialUartVersion(void) { 00262 return ESOS_COMM_SYS_SERIAL_REV; 00263 } //end _esos_hw_GetUartVersion()