📄 config.c
字号:
/* * picasm -- config.c * * handles configuration fuse setting with the CONFIG-directive * * Timo Rossi <trossi@iki.fi> * */#include <stdio.h>#include <string.h>#include "picasm.h"/* * Check Yes/No (or Disable(d)/Enable(d) or On/Off) strings for CONFIG * * returns: 0=no, 1=yes, -1=error * */static intconfig_yes_no(char *s){ if(strcasecmp(s, "yes") == 0 || strcasecmp(s, "on") == 0 || strncasecmp(s, "enable", 6) == 0) return 1; else if(strcasecmp(s, "no") == 0 || strcasecmp(s, "off") == 0 || strncasecmp(s, "disable", 7) == 0) return 0; else return -1; /* error */}/* * selstr consists of NUL-terminated strings with two NULs in the end * If str matches one of the components of selstr, the index of * that component (starting from zero) is returned, * if no match is found, -1 is returned. */static intstrsel(char *selstr, char *str){ int sel = 0; while(*selstr != '\0') { if(strcasecmp(selstr, str) == 0) return sel; selstr += strlen(selstr)+1; sel++; } return -1;}/* * parse the CONFIG directive * * (the separate code protections of PIC14000 are not currently, * and neither are the partial protections on some PICs) * */voidparse_config(void){ static char symname[256]; int t; for(;;) { if(token_type != TOK_IDENTIFIER) {cfg_error: error(1, "CONFIG syntax error"); return; } strcpy(symname, token_string); get_token(); /* hmm... this is a little kludge, but as the tokenizer now makes 'local id's from the valid config strings, this must be used... */ if(token_type != TOK_LOCAL_ID) { if(token_type != TOK_EQUAL) { error(1, "'=' expected"); return; } get_token(); if(token_type != TOK_IDENTIFIER) goto cfg_error; } switch(strsel("OSC\0WDT\0CP\0PWRT\0MCLR\0BOD\0MPE\0", symname)) { case 0: /* OSC */ if((t = strsel("LP\0XT\0HS\0RC\0INTRC\0INTRC_CLKOUT\0" "EXTRC\0EXTRC_CLKOUT\0IN\0", token_string)) < 0) goto cfg_error; switch(pic_type->fusetype) { case FUSE_12C5XX: if(t >= 2 && t != 4 && t != 6) { error(1, "Invalid oscillator type %s for PIC%s", token_string, pic_type->name); return; } if(t >= 2) t >>= 2; config_fuses = (config_fuses & 0xffc) | t; break; case FUSE_12C6XX: if(t == 3 || t >= 8) { error(1, "Invalid oscillator type %s for PIC%s", token_string, pic_type->name); return; } config_fuses = (config_fuses & 0x3ff8) | t; break; case FUSE_14000: if(t != 2 && t != 4 && t != 8) { /* accept both IN and INTRC */ error(1, "Invalid oscillator type %s for PIC%s", token_string, pic_type->name); return; } config_fuses = (config_fuses & 0x3ffe) | (t != 2); break; case FUSE_16C5X: case FUSE_16F8X: case FUSE_16CXX1: case FUSE_16CXX2: case FUSE_16C55X: case FUSE_16C62X: case FUSE_16C6XA: case FUSE_16C71X: case FUSE_16C715: if(t >= 4) { error(1, "Invalid oscillator type %s for PIC%s", token_string, pic_type->name); return; } config_fuses = (config_fuses & 0x3ffc) | t; break; } break; case 1: /* WDT - watchdog timer */ if((t = config_yes_no(token_string)) < 0) goto cfg_error; switch(pic_type->fusetype) { case FUSE_12C6XX: config_fuses = (config_fuses & 0x3ff7) | (t ? 8 : 0); break; default: config_fuses = (config_fuses & 0x3ffb) | (t ? 4 : 0); break; } break; case 2: /* CP - code protect */ /* partial protection is not supported */ if((t = config_yes_no(token_string)) < 0) goto cfg_error; switch(pic_type->fusetype) { case FUSE_16C5X: case FUSE_12C5XX: config_fuses = (config_fuses & 0xff7) | (t ? 0 : 8); break; case FUSE_12C6XX: config_fuses = (config_fuses & 0x009f) | (t ? 0 : 0x3f60); break; case FUSE_16CXX1: /* 1 code protect bit */ config_fuses = (config_fuses & 0x3fef) | (t ? 0 : 0x10); break; case FUSE_16CXX2: /* 2 code protect bits */ config_fuses = (config_fuses & 0x3fcf) | (t ? 0 : 0x30); break; case FUSE_16F8X: config_fuses = (config_fuses & 0x000f) | (t ? 0 : 0x3ff0); break; case FUSE_16C71X: config_fuses = (config_fuses & 0x004f) | (t ? 0 : 0x3fb0); break; case FUSE_16C6XA: case FUSE_16C62X: /* 2 code protect bits, replicated */ case FUSE_16C55X: case FUSE_16C715: config_fuses = (config_fuses & 0x00cf) | (t ? 0 : 0x3f30); break; case FUSE_14000: config_fuses = (config_fuses & 0x3f4f) | (t ? 0 : 0x00b0); break; } break; case 3: /* PWRT - power-up timer */ if((t = config_yes_no(token_string)) < 0) goto cfg_error; switch(pic_type->fusetype) { case FUSE_16CXX1: case FUSE_16CXX2: config_fuses = (config_fuses & 0x3ff7) | (t ? 8 : 0); break; case FUSE_16C6XA: case FUSE_16C55X: case FUSE_16F8X: case FUSE_16C71X: case FUSE_16C715: case FUSE_16C62X: case FUSE_14000: config_fuses = (config_fuses & 0x3ff7) | (t ? 0 : 8); break; case FUSE_12C6XX: config_fuses = (config_fuses & 0x3fef) | (t ? 0 : 0x10); break; case FUSE_16C5X: case FUSE_12C5XX: error(1, "No power-up timer in PIC%s", pic_type->name); return; } break; case 4: /* MCLR - enable/disable MCLR (8-pin PICs) */ if((t = config_yes_no(token_string)) < 0) goto cfg_error; switch(pic_type->fusetype) { case FUSE_12C5XX: config_fuses = (config_fuses & 0xfef) | (t ? 0x10 : 0); break; case FUSE_12C6XX: config_fuses = (config_fuses & 0x3f7f) | (t ? 0x80 : 0); break; default: error(1,"No MCLRE in PIC%s", pic_type->name); return; } break; case 5: /* BOD - brown-out detect */ if((t = config_yes_no(token_string)) < 0) goto cfg_error; switch(pic_type->fusetype) { case FUSE_16C62X: case FUSE_16C6XA: case FUSE_16C71X: case FUSE_16C715: config_fuses = (config_fuses & 0x3fbf) | (t ? 0x40 : 0); break; default: error(1,"No BODEN in PIC%s", pic_type->name); return; } break; case 6: /* MPE - memory parity error */ if((t = config_yes_no(token_string)) < 0) goto cfg_error; switch(pic_type->fusetype) { case FUSE_16C715: config_fuses = (config_fuses & 0x3f7f) | (t ? 0x80 : 0); break; default: error(1,"No MPEEN in PIC%s", pic_type->name); return; } break; default: goto cfg_error; } get_token(); if(token_type != TOK_COMMA) break; get_token(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -