pic24_stdio_uart.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00063 #include "pic24_all.h"
00064 #include <stdio.h>
00065
00066
00067
00068 #define SERIAL_BREAK_CR // Break input stream on CR if specified
00069 #define SERIAL_BREAK_NL // Break input stream on NL if specified
00070
00071
00072 #define _LIBC_FUNCTION __attribute__((__weak__, __section__(".libc")))
00073 #define SUCCESS 0
00074 #define FAIL -1
00075 #define CHAR_ACCESS 0x4000
00076 #define DATA_ACCESS 0x8000 //this flag assumed if CHAR_ACCESS not set
00077 #define READ_ACCESS 0x0
00078 #define WRITE_ACCESS 0x1
00079 #define READ_WRITE_ACCESS 0x2
00080 #define ACCESS_RW_MASK 0x3 // bits set to 0 or 2 for read and 1 or 2 for write
00081 #define ACCESS_SET_OPEN DATA_ACCESS // expedient - reuse bit position to indicate open
00082
00083
00084 #ifndef DEFAULT_BAUDRATE1
00085 #define DEFAULT_BAUDRATE1 DEFAULT_BAUDRATE
00086 #endif
00087 #ifndef DEFAULT_BAUDRATE2
00088 #define DEFAULT_BAUDRATE2 DEFAULT_BAUDRATE
00089 #endif
00090 #ifndef DEFAULT_BAUDRATE3
00091 #define DEFAULT_BAUDRATE3 DEFAULT_BAUDRATE
00092 #endif
00093 #ifndef DEFAULT_BAUDRATE4
00094 #define DEFAULT_BAUDRATE4 DEFAULT_BAUDRATE
00095 #endif
00096
00097 #define MAX_ALLOWED_HANDLES (NUM_UART_MODS+3) // number of handles allowed
00098 #define RANGECK_HANDLE(xxhandlexx) ((xxhandlexx >= 0) && (xxhandlexx < MAX_ALLOWED_HANDLES))
00099 enum ALLOWED_HANDLES {
00100 HANDLE_STDIN=0,
00101 HANDLE_STDOUT=1,
00102 HANDLE_STDERR=2,
00103 HANDLE_UART1,
00104 HANDLE_UART2,
00105 HANDLE_UART3,
00106 HANDLE_UART4
00107 };
00108
00109 struct {
00110 void (*pfnv_outChar)();
00111 uint8 (*pfn_inChar)();
00112 uint16 u16_read_access;
00113 uint16 u16_write_access;
00114 } FILES[MAX_ALLOWED_HANDLES] = {
00115 { 0, 0 },
00116 { 0, 0 },
00117 { 0, 0 },
00118 #if (NUM_UART_MODS >= 1)
00119 { (void *)&outChar1, &inChar1 },
00120 #if (NUM_UART_MODS >= 2)
00121 { (void *)&outChar2, &inChar2 },
00122 #if (NUM_UART_MODS >= 3)
00123 { (void *)&outChar3, &inChar3 },
00124 #if (NUM_UART_MODS >= 4)
00125 { (void *)&outChar4, &inChar4 }
00126 #endif
00127 #endif
00128 #endif
00129 #endif
00130 };
00131
00132
00133
00134
00135
00143 static int16 stdioOpen(void)
00144 {
00145 #if (NUM_UART_MODS >= 1)
00146 if (__C30_UART == 1) {
00147 FILES[HANDLE_STDERR].pfnv_outChar = (void *)&outChar1;
00148 FILES[HANDLE_STDOUT].pfnv_outChar = (void *)&outChar1;
00149 FILES[HANDLE_STDIN].pfn_inChar = &inChar1;
00150 if (!U1MODEbits.UARTEN) {
00151 configUART1(DEFAULT_BAUDRATE1);
00152 }
00153 return SUCCESS;
00154 }
00155 #if (NUM_UART_MODS >= 2)
00156 if (__C30_UART == 2) {
00157 FILES[HANDLE_STDERR].pfnv_outChar = (void *)&outChar2;
00158 FILES[HANDLE_STDOUT].pfnv_outChar = (void *)&outChar2;
00159 FILES[HANDLE_STDIN].pfn_inChar = &inChar2;
00160 if (!U2MODEbits.UARTEN) {
00161 configUART2(DEFAULT_BAUDRATE2);
00162 }
00163 return SUCCESS;
00164 }
00165 #if (NUM_UART_MODS >= 3)
00166 if (__C30_UART == 3) {
00167 FILES[HANDLE_STDERR].pfv_outChar = (void *)&outChar3;
00168 FILES[HANDLE_STDOUT].pfv_outChar = (void *)&outChar3;
00169 FILES[HANDLE_STDIN].pfui8_inChar = &inChar3;
00170 if (!U3MODEbits.UARTEN) {
00171 configUART3(DEFAULT_BAUDRATE3);
00172 }
00173 return SUCCESS;
00174 }
00175 #if (NUM_UART_MODS >= 4)
00176 if (__C30_UART == 4) {
00177 FILES[HANDLE_STDERR].pfv_outChar = (void *)&outChar4;
00178 FILES[HANDLE_STDOUT].pfv_outChar = (void *)&outChar4;
00179 FILES[HANDLE_STDIN].pfui8_inChar = &inChar4;
00180 if (!U4MODEbits.UARTEN) {
00181 configUART4(DEFAULT_BAUDRATE4);
00182 }
00183 return SUCCESS;
00184 }
00185 #endif
00186 #endif
00187 #endif
00188 #endif
00189 return FAIL;
00190 }
00191
00192
00193
00194
00195
00215 int _LIBC_FUNCTION
00216 open(const char *name, int access, int mode)
00217 {
00218 enum ALLOWED_HANDLES ie_handle;
00219 uint16 u16_masked_access;
00220 uint16 u16_set_access;
00221
00222 switch (name[4]) {
00223 case 'n':
00224 if (stdioOpen()) return FAIL;
00225 ie_handle = HANDLE_STDIN;
00226 break;
00227 case 'u':
00228 if (stdioOpen()) return FAIL;
00229 ie_handle = HANDLE_STDOUT;
00230 break;
00231 case 'r':
00232 if (stdioOpen()) return FAIL;
00233 ie_handle = HANDLE_STDERR;
00234 break;
00235 #if (NUM_UART_MODS >= 1)
00236 case '1':
00237 if (__C30_UART == 1) return FAIL;
00238 if (!U1MODEbits.UARTEN) {
00239 configUART1(DEFAULT_BAUDRATE1);
00240 }
00241 ie_handle = HANDLE_UART1;
00242 break;
00243 #endif
00244 #if (NUM_UART_MODS >= 2)
00245 case '2':
00246 if (__C30_UART == 2) return FAIL;
00247 if (!U2MODEbits.UARTEN) {
00248 configUART2(DEFAULT_BAUDRATE2);
00249 }
00250 ie_handle = HANDLE_UART2;
00251 break;
00252 #endif
00253 #if (NUM_UART_MODS >= 3)
00254 case '3':
00255 if (__C30_UART == 3) return FAIL;
00256 if (!U3MODEbits.UARTEN) {
00257 configUART3(DEFAULT_BAUDRATE3);
00258 }
00259 ie_handle = HANDLE_UART3;
00260 break;
00261 #endif
00262 #if (NUM_UART_MODS >= 4)
00263 case '4':
00264 if (__C30_UART == 4) return FAIL;
00265 if (!U4MODEbits.UARTEN) {
00266 configUART4(DEFAULT_BAUDRATE4);
00267 }
00268 ie_handle = HANDLE_UART4;
00269 break;
00270 #endif
00271 default:
00272 return FAIL;
00273 }
00274
00275 u16_masked_access = access & ACCESS_RW_MASK;
00276 u16_set_access = ACCESS_SET_OPEN | access;
00277 if ((u16_masked_access == READ_ACCESS) || (u16_masked_access == READ_WRITE_ACCESS)) {
00278 FILES[ie_handle].u16_read_access = u16_set_access;
00279 }
00280 if ((u16_masked_access == WRITE_ACCESS) || (u16_masked_access == READ_WRITE_ACCESS)) {
00281 FILES[ie_handle].u16_write_access = u16_set_access;
00282 }
00283 return ie_handle;
00284 }
00285
00296 int _LIBC_FUNCTION
00297 read(int handle, void *buffer, unsigned int len)
00298 {
00299 uint16 u16_char_count;
00300
00301 if(!RANGECK_HANDLE(handle)) return FAIL;
00302 if ((handle == HANDLE_STDIN) && !(FILES[HANDLE_STDIN].u16_read_access & ACCESS_SET_OPEN)) {
00303 open("stdin", (CHAR_ACCESS | READ_ACCESS), 0);
00304 }
00305 if (!FILES[handle].u16_read_access) return FAIL;
00306 for (u16_char_count = 0; u16_char_count < len; u16_char_count++) {
00307 ((unsigned char *)buffer)[u16_char_count] = (*FILES[handle].pfn_inChar)();
00308 #ifdef SERIAL_BREAK_NL
00309 if ((FILES[handle].u16_read_access & CHAR_ACCESS) && (((unsigned char *)buffer)[u16_char_count] == '\n')) {
00310 ++u16_char_count;
00311 break;
00312 }
00313 #endif
00314 #ifdef SERIAL_BREAK_CR
00315 if ((FILES[handle].u16_read_access & CHAR_ACCESS) && (((unsigned char *)buffer)[u16_char_count] == '\r')) {
00316 ++u16_char_count;
00317 break;
00318 }
00319 #endif
00320 }
00321
00322 return u16_char_count;
00323 }
00324
00335 int _LIBC_FUNCTION
00336 write(int handle, void *buffer, unsigned int len)
00337 {
00338 uint16 u16_char_count;
00339
00340 if(!RANGECK_HANDLE(handle)) return FAIL;
00341 if ((handle == HANDLE_STDOUT) && !(FILES[HANDLE_STDOUT].u16_write_access & ACCESS_SET_OPEN)) {
00342 open("stdout", (CHAR_ACCESS | WRITE_ACCESS), 0);
00343 }
00344 if ((handle == HANDLE_STDERR) && !(FILES[HANDLE_STDERR].u16_write_access & ACCESS_SET_OPEN)) {
00345 open("stderr", (CHAR_ACCESS | WRITE_ACCESS), 0);
00346 }
00347 if (!FILES[handle].u16_write_access) return FAIL;
00348 for (u16_char_count = 0; u16_char_count < len; u16_char_count++) {
00349 if ((FILES[handle].u16_write_access & CHAR_ACCESS) && (((unsigned char *)buffer)[u16_char_count] == '\n')) {
00350 #if (SERIAL_EOL_DEFAULT==SERIAL_EOL_CR)
00351 (*FILES[handle].pfv_outChar)('\r');
00352 continue;
00353 #endif
00354 #if (SERIAL_EOL_DEFAULT==SERIAL_EOL_CR_LF)
00355 (*FILES[handle].pfv_outChar)('\r');
00356 #endif
00357 (*FILES[handle].pfnv_outChar)('\n');
00358 continue;
00359 }
00360 (*FILES[handle].pfnv_outChar)(((unsigned char *)buffer)[u16_char_count]);
00361 }
00362
00363 return u16_char_count;
00364 }
00365
00372 int _LIBC_FUNCTION
00373 close(int handle) {
00374 return SUCCESS;
00375 }
00376
00385 long _LIBC_FUNCTION
00386 lseek(int handle, long offset, int origin) {
00387 return SUCCESS;
00388 }