Changeset 11
- Timestamp:
- Jul 31, 2019, 5:43:21 PM (5 years ago)
- Location:
- trunk/software/firmware
- Files:
-
- 3 added
- 1 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/software/firmware/Makefile
r1 r11 5 5 CFLAGS= -I${.CURDIR} -I${.CURDIR}/../lib/J1939 -I${.CURDIR}/../lib/eeprom 6 6 CFLAGS+= --fomit-frame-pointer --denable-peeps --optimize-cmp --optimize-df 7 OBJECTS= main.o serial.o 8 HEADERS= my_serial.h 7 OBJECTS= main.o serial.o serial2.o 8 HEADERS= my_serial.h my_serial2.h 9 9 10 10 all: capteur.bin … … 18 18 19 19 capteur.hex: ${OBJECTS} 20 ${CC} -V -Wl,-s${.CURDIR}/pic18f27j 53.lkr --no-crt --ivt-loc=0x400 --obanksel=2 -mpic16 -p18f27j53 -Wl,libc18f.lib ${.ALLSRC} -o ${.TARGET} -llibm18f.lib20 ${CC} -V -Wl,-s${.CURDIR}/pic18f27j13.lkr --no-crt --ivt-loc=0x400 --obanksel=2 -mpic16 -p18f27j13 -Wl,libc18f.lib ${.ALLSRC} -o ${.TARGET} -llibm18f.lib 21 21 22 22 ${OBJECTS}: ${HEADERS} Makefile 23 23 24 24 .c.o: 25 ${CC} ${CFLAGS} -V --no-crt --ivt-loc=0x400 --obanksel=2 -mpic16 -p18f27j 53 -c ${.IMPSRC} -o ${.TARGET}25 ${CC} ${CFLAGS} -V --no-crt --ivt-loc=0x400 --obanksel=2 -mpic16 -p18f27j13 -c ${.IMPSRC} -o ${.TARGET} 26 26 27 27 .s.o: -
trunk/software/firmware/main.c
r1 r11 3 3 #include <math.h> 4 4 #include <my_serial.h> 5 #include <my_serial2.h> 5 6 6 7 extern char stack; … … 14 15 static char counter_1hz; 15 16 static volatile short counter_10hz; 16 static volatile unsigned int softintrs; 17 #define INT_10HZ 0x0001 18 #define INT_AD 0x0002 19 #define INT_DOAD 0x0004 17 static volatile unsigned char softintrs; 18 #define INT_10HZ (unsigned char)0x01 19 #define INT_AD (unsigned char)0x02 20 #define INT_RX1 (unsigned char)0x08 21 #define INT_RX1OF (unsigned char)0x10 22 23 static volatile unsigned char status; 24 #define STAT_WAIT (unsigned char)0x00 25 #define STAT_MEASURE (unsigned char)0x01 26 #define STAT_EXIT (unsigned char)0x02 27 #define STAT_CONSOLE (unsigned char)0x04 28 29 static volatile unsigned char adstatus; 30 #define ADSTAT_MEASURE (unsigned char)0x01 31 static unsigned char ad_resh; 32 static unsigned char ad_resl; 33 static unsigned char ad_channel; 34 20 35 21 36 #define TIMER0_5MS 192 /* 48 without PLL */ 22 37 23 38 #define TIMER2_10HZ 1000 39 40 #define LEDR LATAbits.LATA7 41 #define LEDG LATAbits.LATA6 42 #define PWRON LATCbits.LATC2 43 #define RL1 LATCbits.LATC4 44 #define RL2 LATCbits.LATC5 45 #define SENSE PORTAbits.RA5 24 46 25 47 #define CLRWDT __asm__("clrwdt") 26 48 #define SLEEP __asm__("sleep") 27 49 28 static char ad_channel; 29 static long ad_i_result; 30 static long ad_v_result; 31 50 static void do_measure(void); 51 static void do_console(void); 52 static void do_cal_data(void); 53 static void parse_rx(void); 54 55 static char buf[84]; 56 57 /* address of calibration data in RAM */ 58 #define cal_data 0x01F000 59 60 61 #if 1 32 62 #define PRINTHEX(v) \ 33 63 { \ 34 64 unsigned char c = (v); \ 35 65 if (c < 10) { \ 36 putchar('0' + c); \66 uart_putchar_hard('0' + c); \ 37 67 } else { \ 38 putchar(('a' - 10) + c ); \68 uart_putchar_hard(('a' - 10) + c ); \ 39 69 } \ 40 70 } 71 #else 72 #define PRINTHEX(v) {} 73 #endif 41 74 42 75 void 43 76 main(void) __naked 44 77 { 45 unsigned char c;46 78 softintrs = 0; 47 79 counter_1hz = 10; … … 50 82 ANCON1 = 0x3f; /* an8-12 digital */ 51 83 52 TRISCbits.TRISC1 = 0; 84 RL1 = 0; 85 TRISCbits.TRISC4 = 0; 86 RL2 = 0; 87 TRISCbits.TRISC5 = 0; 88 PWRON = 0; 53 89 TRISCbits.TRISC2 = 0; 54 PORTCbits.RC1 = 0; 55 PORTCbits.RC2 = 0; 56 90 LEDR = 1; 91 TRISAbits.TRISA7 = 0; 92 LEDG = 0; 93 TRISAbits.TRISA6 = 0; 57 94 58 95 /* switch PLL on */ … … 91 128 SPBRG1 = 12; 92 129 130 /* pre-configure UART2 */ 131 /* turn off PPS write protect */ 132 __asm 133 banksel _PPSCON 134 movlw 0x55 135 movwf _EECON2, a 136 movlw 0xAA 137 movwf _EECON2, a 138 BCF _PPSCON, _IOLOCK, b 139 __endasm; 140 141 TRISCbits.TRISC0 = 1; 142 LATCbits.LATC1 = 1; 143 TRISCbits.TRISC1 = 0; 144 RPINR16 = 11; /* RC0 = RX */ 145 RPOR12 = 6; /* RC1 = TX */ 146 TXSTA2 = 0x24; /* TXEN, BRGH set, others clear */ 147 RCSTA2 = 0x90; /* UART enable, receiver disabled */ 148 BAUDCON2 = 0x08; /* BRG16 */ 149 93 150 USART_INIT(0); 151 USART2_INIT(0); 152 94 153 stdout = STREAM_USER; /* Use the macro PUTCHAR with printf */ 95 154 … … 115 174 PIE1bits.TMR2IE = 1; 116 175 176 status = STAT_WAIT; 177 adstatus = 0; 117 178 118 179 INTCONbits.GIE_GIEH=1; /* enable high-priority interrupts */ … … 143 204 /* enable watch dog timer */ 144 205 WDTCON = 0x01; 206 LEDR = 0; 145 207 146 208 printf("\nready\n"); 147 /* start I calibration process */148 209 ad_channel = 0; 149 210 ADCON0bits.CHS = 0; 150 softintrs &= ~INT_DOAD; 151 PORTCbits.RC1 = 1; 152 PORTCbits.RC2 = 0; 153 154 again: 155 while (1) { 211 LEDG = 1; 212 PWRON = 0; 213 214 while ((status & STAT_EXIT) == 0) { 156 215 CLRWDT; 157 if (softintrs & INT_AD) { 158 softintrs &= ~INT_AD; 159 if (ad_channel == 0) { 160 PRINTHEX(PORTB & 0xf); 161 PRINTHEX(ADRESH & 0xf); 162 PRINTHEX(ADRESL >> 4); 163 PRINTHEX(ADRESL & 0xf); 164 165 //printf("%1x%3x", (PORTB & 0xf), ADRESL | (ADRESH << 8)); 166 /* 167 * needs 2Tac, or 32 instrutions 168 * before next sample. assume we 169 * already have them since the 170 * interrupt 171 */ 172 ad_channel = 1; 173 ADCON0bits.CHS = 1; 174 } else { 175 ad_channel = 0; 176 ADCON0bits.CHS = 0; 177 PRINTHEX(ADRESH & 0xf); 178 PRINTHEX(ADRESL >> 4); 179 PRINTHEX(ADRESL & 0xf); 180 putchar('X'); 181 //printf("%3xX", ADRESL | (ADRESH << 8)); 182 } 183 } 184 185 if ((softintrs & INT_AD) == 0 && 186 (softintrs & INT_DOAD) && 187 ADCON0bits.GO_NOT_DONE == 0) { 188 ADCON0bits.GO_NOT_DONE = 1; 189 softintrs &= ~INT_DOAD; 190 } 191 192 if (RCREG1 == 'r') 193 break; 194 SLEEP; 195 196 } 197 198 end: 199 200 while ((c = getchar()) != 'r') { 201 printf("got %c\n", c); 202 goto again; 216 if (softintrs & INT_10HZ) { 217 softintrs &= ~INT_10HZ; 218 LEDG ^= 1; 219 } 220 if (softintrs & INT_RX1) { 221 parse_rx(); 222 } else { 223 SLEEP; 224 continue; 225 } 226 if (status & STAT_MEASURE) 227 do_measure(); 228 else if (status & STAT_CONSOLE) 229 do_console(); 203 230 } 204 231 printf("returning\n"); … … 209 236 } 210 237 211 unsigned int 238 static void 239 parse_rx() 240 { 241 char c; 242 char c2; 243 char ok = 1; 244 char err = 0; 245 long br; 246 short brgreg = 0; 247 248 softintrs &= ~INT_RX1; 249 c = uart_getchar(); 250 switch(c) { 251 case 'B': 252 c = uart_getchar(); 253 br = 0; 254 while(c != '\n') { 255 if (c < '0' || c > '9') { 256 err = 1; 257 break; 258 } 259 br = br * 10 + c - '0'; 260 c = uart_getchar(); 261 } 262 if (br > 0) { 263 /* 264 * brg = F / 16 / (n + 1) 265 * brg * (n + 1) = F / 16 266 * n + 1 = F / 16 / brg 267 * n = F / 16 / brg - 1 268 * with F = 48Mhz 269 * n = 3000000 / brg - 1 270 */ 271 brgreg = (12000000L + br / 2) / br - 1; 272 printf("brgreg %d\n", brgreg); 273 } 274 if (err == 0) { 275 if (br > 0) { 276 SPBRGH2 = (brgreg >> 8); 277 SPBRG2 = (brgreg & 0xff); 278 } 279 status = STAT_CONSOLE; 280 } 281 break; 282 case 'C': 283 do_cal_data(); 284 c = '\n'; 285 break; 286 case 'E': 287 status = STAT_EXIT; 288 break; 289 case 'M': 290 c = uart_getchar(); 291 if (c == '0') { 292 if (status == STAT_MEASURE) 293 ok = 0; 294 status = STAT_WAIT; 295 } else if (c == '1') { 296 status = STAT_MEASURE; 297 } else { 298 err = 1; 299 } 300 break; 301 case 'P': 302 c = uart_getchar(); 303 if (c == '0') 304 PWRON = 0; 305 else if (c == '1') 306 PWRON = 1; 307 else 308 err = 1; 309 break; 310 case 'R': 311 c = uart_getchar(); 312 if (c != '\n') { 313 c2 = uart_getchar(); 314 if (c == '1') { 315 if (c2 == '0') 316 RL1 = 0; 317 else if (c2 == '1') 318 RL1 = 1; 319 else 320 err = 1; 321 } else if (c == '2') { 322 if (c2 == '0') 323 RL2 = 0; 324 else if (c2 == '1') 325 RL2 = 1; 326 else 327 err = 1; 328 } else { 329 err = 1; 330 } 331 c = c2; 332 } 333 break; 334 case 'S': 335 printf("power %s RL %s %s SENSE %s GPIO 0x%x\n", 336 PWRON ? "on" : "off", 337 RL1 ? "on" : "off", 338 RL2 ? "on" : "off", 339 SENSE ? "off" : "on", 340 PORTB); 341 break; 342 default: 343 err = 1; 344 break; 345 } 346 while (c != '\n') 347 c = uart_getchar(); 348 if (err) 349 printf("\nERROR\n"); 350 else if (ok) 351 printf("\nOK\n"); 352 353 if (softintrs & INT_RX1OF) { 354 PIE1bits.RC1IE = 0; 355 softintrs &= ~INT_RX1OF; 356 softintrs &= ~INT_RX1; 357 uart_rxbuf_prod = uart_rxbuf_cons = 0; 358 PIE1bits.RC1IE = 1; 359 } 360 } 361 362 static void 363 printhex(unsigned char c) __wparam __naked 364 { 365 (void)c; 366 __asm 367 andlw 0x0f; 368 sublw 9; 369 bc decimal; 370 sublw '@'; 371 goto _uart_putchar_hard; 372 decimal: 373 sublw '9'; 374 goto _uart_putchar_hard; 375 __endasm; 376 } 377 378 static void 379 do_measure() 380 { 381 softintrs &= ~INT_AD; 382 adstatus = ADSTAT_MEASURE; 383 ADCON0bits.CHS = 0; 384 385 LEDR = 0; 386 LEDG = 1; 387 UART_FLUSH(); 388 uart_putchar_hard('X'); 389 while (status & STAT_MEASURE) { 390 CLRWDT; 391 if (softintrs & INT_AD) { 392 if (ad_channel == 0) { 393 printhex(PORTB >> 4); 394 printhex(PORTB); 395 printhex(ad_resh); 396 printhex(ad_resl >> 4); 397 printhex(ad_resl); 398 } else { 399 printhex(ad_resh); 400 printhex(ad_resl >> 4); 401 printhex(ad_resl); 402 uart_putchar_hard('X'); 403 } 404 softintrs &= ~INT_AD; 405 } 406 if (softintrs & INT_RX1) { 407 parse_rx(); 408 } else { 409 SLEEP; 410 } 411 } 412 adstatus = 0; 413 printf("\nOK\n"); 414 } 415 416 static void 417 do_console() 418 { 419 char previous_rx1 = 0; 420 char c; 421 char more_work = 0; 422 423 printf("connecting to console - exit with #.\n"); 424 /* clear buffer */ 425 PIE3bits.RC2IE = 0; 426 uart2_rxbuf_prod = uart2_rxbuf_cons = 0; 427 PIE3bits.RC2IE = 1; 428 RCSTA2bits.SPEN = 1; 429 while ((status & STAT_CONSOLE) || more_work) { 430 CLRWDT; 431 more_work = 0; 432 if (softintrs & INT_10HZ) { 433 softintrs &= ~INT_10HZ; 434 LEDG ^= 1; 435 } 436 if (uart_rxbuf_cons != uart_rxbuf_prod) { 437 c = uart_getchar(); 438 /* 439 * #. exits console mode 440 * ## sends # 441 * anything else send both char unmodified 442 */ 443 if (previous_rx1 == '#') { 444 if (c == '.') { 445 status = STAT_WAIT; 446 } else if (c == '#') { 447 uart2_putchar_raw(c); 448 } else { 449 uart2_putchar_raw(previous_rx1); 450 uart2_putchar_raw(c); 451 } 452 } else { 453 uart2_putchar_raw(c); 454 } 455 previous_rx1 = c; 456 more_work = 1; 457 } 458 if (uart2_rxbuf_cons != uart2_rxbuf_prod) { 459 c = uart2_getchar(); 460 uart_putchar_raw(c); 461 more_work = 1; 462 } 463 if (more_work == 0 && (status & STAT_CONSOLE)) 464 SLEEP; 465 } 466 RCSTA2bits.SPEN = 0; 467 printf("exit from console\n"); 468 } 469 470 static void 471 do_write(void) 472 { 473 EECON2 = 0x55; 474 EECON2 = 0xaa; 475 EECON1bits.WR = 1; 476 while (EECON1bits.WR) 477 ; /* wait */ 478 } 479 480 static void 481 do_cal_data() 482 { 483 char i = 0; 484 char err = 0; 485 char c; 486 487 c = uart_getchar(); 488 while (c != '\n') { 489 if ((c < '0' || c > '9') && c != ' ' && c != '.') { 490 printf("cal error at %c (%d)\n", c, i); 491 err = 1; 492 } 493 if (i > 82) { 494 printf("cal error at %c (%d)\n", c, i); 495 err = 1; 496 } else { 497 buf[i] = c; 498 i++; 499 } 500 c = uart_getchar(); 501 } 502 if (err == 0 && i != 0 && i != 83) { 503 printf("cal error: %d\n", i); 504 } else if (err == 0 && i != 0) { 505 /* erase 1k block */ 506 INTCONbits.GIE_GIEH=0; /* disable interrupts */ 507 INTCONbits.PEIE_GIEL=0; 508 TBLPTRU = ((long)cal_data >> 16) & 0xff; 509 TBLPTRH = ((long)cal_data >> 8) & 0xff; 510 TBLPTRL = (long)cal_data & 0xff; 511 EECON1 = 0x14; /* enable write+erase */ 512 do_write(); 513 EECON1 = 0x00; /* disable write */ 514 for (i = 0; i < 83; i++) { 515 TABLAT = buf[i]; 516 __asm__("tblwt*+"); 517 if (i == 63) { 518 __asm__("tblrd*-"); 519 EECON1 = 0x04; /* enable write */ 520 do_write(); 521 EECON1 = 0x00; /* disable write */ 522 __asm__("tblrd*+"); 523 } 524 } 525 __asm__("tblrd*-"); 526 EECON1 = 0x04; /* enable write */ 527 do_write(); 528 EECON1 = 0x00; /* disable write */ 529 INTCONbits.PEIE_GIEL=1; 530 INTCONbits.GIE_GIEH=1; /* enable interrupts */ 531 } 532 printf("cal_data "); 533 TBLPTRU = ((long)cal_data >> 16) & 0xff; 534 TBLPTRH = ((long)cal_data >> 8) & 0xff; 535 TBLPTRL = (long)cal_data & 0xff; 536 EECON1 = 0x00; /* disable writes */ 537 for (i = 0; i < 83; i++) { 538 __asm__("tblrd*+"); 539 putchar(TABLAT); 540 } 541 printf("\n"); 542 } 543 544 unsigned short 212 545 timer0_read() __naked 213 546 { … … 267 600 * so we have to be carefull with C code ! 268 601 */ 269 #if 0270 602 counter_10hz--; 271 603 if (counter_10hz == 0) { … … 273 605 softintrs |= INT_10HZ; 274 606 } 275 #endif 276 if (softintrs & INT_DOAD) { 277 PORTCbits.RC2=1; 278 } 279 softintrs |= INT_DOAD; 607 if (adstatus & ADSTAT_MEASURE) { 608 if (PIR1bits.ADIF) { 609 LEDR = 1; 610 } 611 ADCON0bits.GO_NOT_DONE = 1; 612 } 280 613 __asm 281 614 retfie 1 … … 287 620 { 288 621 USART_INTR; 622 USART2_INTR; 289 623 if (PIE1bits.ADIE && PIR1bits.ADIF) { 624 if (softintrs & INT_AD) { 625 LEDR = 1; 626 } 627 ad_channel = ADCON0bits.CHS; 628 ad_resl = ADRESL; 629 ad_resh = ADRESH; 630 /* 631 * needs 2Tac, or 32 instrutions 632 * before next sample. assume we'll 633 * have them at timer2 interrupt 634 */ 635 if (ad_channel == 0) 636 ADCON0bits.CHS = 1; 637 else 638 ADCON0bits.CHS = 0; 290 639 PIR1bits.ADIF = 0; 291 640 softintrs |= INT_AD; -
trunk/software/firmware/my_serial.h
r1 r11 11 11 extern volatile unsigned char uart_txbuf_cons; 12 12 13 extern char uart_rxbuf[UART_BUFSIZE]; 14 extern volatile unsigned char uart_rxbuf_prod; 15 extern unsigned char uart_rxbuf_cons; 16 17 char uart_getchar(void); 18 void uart_putchar_raw(char); 19 #if 0 20 #define UART_PUTCHAR_HARD(c) { \ 21 while (PIR1bits.TX1IF == 0) \ 22 ; \ 23 TXREG1 = c; \ 24 } 25 #endif 26 void uart_putchar_hard(char) __wparam; 27 28 #define UART_FLUSH() { \ 29 while (PIE1bits.TX1IE) \ 30 ; \ 31 } 32 33 13 34 #define USART_INIT { \ 14 35 uart_txbuf_prod = uart_txbuf_cons = 0; \ 36 uart_rxbuf_prod = uart_rxbuf_cons = 0; \ 37 (void)RCREG1; \ 38 PIE1bits.RC1IE = 1; \ 15 39 } 16 40 … … 25 49 } \ 26 50 } \ 51 if (PIE1bits.RC1IE && PIR1bits.RC1IF) { \ 52 register char c = RCREG1; \ 53 if (RCSTA1bits.OERR) { \ 54 RCSTA1bits.CREN = 0; \ 55 RCSTA1bits.CREN = 1; \ 56 } \ 57 if (status & STAT_CONSOLE) { \ 58 uart_rxbuf_prod = (uart_rxbuf_prod + 1) & UART_BUFSIZE_MASK;\ 59 uart_rxbuf[uart_rxbuf_prod] = c; \ 60 } else { \ 61 if (c == '\r') c = '\n';\ 62 if (c != '\n' || uart_rxbuf[uart_rxbuf_prod] != '\n') { \ 63 uart_rxbuf_prod = (uart_rxbuf_prod + 1) & UART_BUFSIZE_MASK;\ 64 uart_rxbuf[uart_rxbuf_prod] = c; \ 65 if (c == '\n') { \ 66 if (softintrs & INT_RX1) \ 67 softintrs |= INT_RX1OF; \ 68 softintrs |= INT_RX1; \ 69 } \ 70 } \ 71 } \ 72 }\ 27 73 } -
trunk/software/firmware/serial.c
r1 r11 6 6 unsigned char uart_txbuf_prod; 7 7 volatile unsigned char uart_txbuf_cons; 8 9 char uart_rxbuf[UART_BUFSIZE]; 10 volatile unsigned char uart_rxbuf_prod; 11 unsigned char uart_rxbuf_cons; 12 13 #define LEDR LATAbits.LATA7 8 14 9 15 PUTCHAR(c) /* Macro */ … … 41 47 } 42 48 49 void 50 uart_putchar_raw(char c) 51 { 52 unsigned char new_uart_txbuf_prod; 53 new_uart_txbuf_prod = (uart_txbuf_prod + 1) & UART_BUFSIZE_MASK; 54 while (new_uart_txbuf_prod == uart_txbuf_cons) { 55 PIE1bits.TX1IE = 1; /* ensure we'll make progress */ 56 } 57 uart_txbuf[uart_txbuf_prod] = c; 58 uart_txbuf_prod = new_uart_txbuf_prod; 59 PIE1bits.TX1IE = 1; 60 } 61 62 void 63 uart_putchar_hard(char c) __wparam { 64 while (PIR1bits.TX1IF == 0) 65 ; 66 TXREG1 = c; 67 } 68 43 69 char 44 70 getchar(void) 45 71 { 46 72 char c; 73 char en; 74 en = PIE1bits.RC1IE; 75 PIE1bits.RC1IE = 0; 47 76 while (!PIR1bits.RC1IF); /* wait for a char */ 48 77 c = RCREG1; … … 51 80 RCSTA1bits.CREN = 1; 52 81 } 82 PIE1bits.RC1IE = en; 53 83 return c; 54 84 } 85 86 char 87 uart_getchar() 88 { 89 register char c; 90 LEDR = 1; 91 while (uart_rxbuf_cons == uart_rxbuf_prod) 92 ; 93 94 uart_rxbuf_cons = (uart_rxbuf_cons + 1) & UART_BUFSIZE_MASK; 95 c = uart_rxbuf[uart_rxbuf_cons]; 96 LEDR = 0; 97 return c; 98 }
Note: See TracChangeset
for help on using the changeset viewer.