// TODO: this method is ugly as shit. R_API void r_mem_copybits_delta(ut8 *dst, int doff, const ut8 *src, int soff, int bits) { int i; if (doff < 0 || soff < 0 || !dst || !src) { return; } for (i = 0; i < bits; i++) { bool c = readbit (src, i + soff); // eprintf ("%d %d\n", i, c); writebit (dst, i + doff, c); } }
uint8_t timer_compareMatchIntSetup(uint8_t timerNum, uint8_t outputChannel, uint8_t enable) { if(timerNum != 1) return 1; //outputChannel is ignored... if(enable) { cli(); enable = 1; } writebit(ICIE1, TIMSK1, enable); //Clear the overflow flag... setbit(ICF1, TIFR1); if(enable) sei(); return 0; }
uint8_t timer_compareMatchIntSetup(uint8_t timerNum, uint8_t outputChannel, uint8_t enable) { uint8_t channelNum; if(timerNum >= MAXTIMERS) return 1; if(outputChannel >= 2) //MAXCHANNELSPERTIMER) return 2; //writebit (used later) does not currently handle TRUE and FALSE properly, just 0 and 1... // this should be fixed now... if(enable) enable = 1; //For the sake of our brute-force switch statement... //Combine the timer number and channel into a single variable... //The high nibble contains the timer number, and the low contains the channel number (A=0,B=1) channelNum = (timerNum<<4) + outputChannel; //Don't clear interrupts before disabling this one, or that defeats the purpose! // But do clear so we don't get unexpected overflows on init if(enable) cli(); switch(channelNum) { #if defined(T0_TIMSK) //Case 0x00 is either OC0 or OC0A... #if defined(OCIE0) case 0x00: //Enable the overflow interrupt (don't forget to create a handler!) // setbit(OCIE0, T0_TIMSK); writebit(OCIE0, T0_TIMSK, enable); //Clear the overflow flag (OCD)... setbit(OCF0, T0_TIFR); break; #endif #if defined(OCIE0A) case 0x00: // setbit(OCIE0A, T0_TIMSK); writebit(OCIE0A, T0_TIMSK, enable); // My OCD bit me in the ass, this was set to TIMSK by mistake(?) setbit(OCF0A, T0_TIFR); break; #endif #if defined(OCIE0B) case 0x01: // setbit(OCIE0B, T0_TIMSK); writebit(OCIE0B, T0_TIMSK, enable); // As was this... setbit(OCF0B, T0_TIFR); break; #endif #endif #if defined(T1_TIMSK) #if defined(OCIE1) case 0x10: // setbit(OCIE1, T1_TIMSK); writebit(OCIE1, T1_TIMSK, enable); setbit(OCF1, T1_TIFR); break; #endif #if defined(OCIE1A) case 0x10: // setbit(OCIE1A, T1_TIMSK); writebit(OCIE1A, T1_TIMSK, enable); setbit(OCF1A, T1_TIFR); break; #endif #if defined(OCIE1B) case 0x11: // setbit(OCIE1B, T1_TIMSK); writebit(OCIE1B, T1_TIMSK, enable); setbit(OCF1B, T1_TIFR); break; #endif #endif #if defined(T2_TIMSK) #if defined(OCIE2) case 0x20: // setbit(OCIE2, T2_TIMSK); writebit(OCIE2, T2_TIMSK, enable); setbit(OCF2, T2_TIFR); break; #endif #if defined(OCIE2A) case 0x20: // setbit(OCIE2A, T2_TIMSK); writebit(OCIE2A, T2_TIMSK, enable); setbit(OCF2A, T2_TIFR); break; #endif #if defined(OCIE2B) case 0x21: // setbit(OCIE2B, T2_TIMSK); writebit(OCIE2B, T2_TIMSK, enable); setbit(OCF2B, T2_TIFR); break; #endif #endif #if defined(T3_TIMSK) #if defined(OCIE3) case 0x30: // setbit(OCIE3, T3_TIMSK); writebit(OCIE3, T3_TIMSK, enable); setbit(OCF3, T3_TIFR); break; #endif #if defined(OCIE3A) case 0x30: // setbit(OCIE3A, T3_TIMSK); writebit(OCIE3A, T3_TIMSK, enable); setbit(OCF3A, T3_TIFR); break; #endif #if defined(OCIE3B) case 0x31: // setbit(OCIE3B, T3_TIMSK); writebit(OCIE3B, T3_TIMSK, enable); setbit(OCF3B, T3_TIFR); break; #endif #endif default: return 3; break; } //Don't reenable interrupts here if disabling... just leave them as they were.... // but do enable for init... if(enable) sei(); return 0; }
uint8_t timer_setWGM(uint8_t timerNum, uint8_t wgm) { #if(!defined(__AVR_AT90PWM161__)) uint8_t wgmLb = getbit(0, wgm); uint8_t wgmHb = getbit(1, wgm); #endif //make the whole byte reflect the bit, so it can be used in writeMasked... //This could probably be more efficient if using writeBit instead... // Oddly only minor effect to .stab but not to .text or .data after // other previous changes (below)... // wgmLb *= 0xff; // wgmHb *= 0xff; //Make sure the chosen WGM will be written to the WGM bits properly, as implemented below... // Only modes 0-3 are implemented... if(wgm > 0x03) return 1; switch(timerNum) { //Assuming every AVR has a Timer0... //an error will occur otherwise, and this can be updated accordingly // pwm161 does NOT contain Timer0... #if(!defined(__AVR_AT90PWM161__)) case 0: #ifdef _AVR_IOTNx61_H_ //TinyX61s' Timer0 is an exception... // It only has WGM00, which serves the same functionality as // most others' WGM01 (when their WGM00 == 0) // (No PWM) if(wgmLb) return 1; //Whatever .stab is, this single change reduces it by 36Bytes writebit(WGM00, T0_WGMReg, wgmHb); // writeMasked(wgmHb, (1<<WGM00), T0_WGMReg); #else //This seems to be the "universal" WGM Timer0 settings writebit(WGM00, T0_WGMReg, wgmLb); writebit(WGM01, T0_WGMReg, wgmHb); // writeMasked(wgmLb, (1<<WGM00), T0_WGMReg); // writeMasked(wgmHb, (1<<WGM01), T0_WGMReg); #endif break; #endif //!__AVR_AT90PWM161__ //Also Timer1, since all devices I've explored have both T0 and T1... case 1: #if(defined(__AVR_AT90PWM161__)) if(wgm == WGM_NORMAL) { clrbit(WGM13, TCCR1B); return 0; } else if(wgm == WGM_CLR_ON_COMPARE) { setbit(WGM13, TCCR1B); return 0; } else return 1; #elif(defined(_AVR_IOTNx61_H_)) //TinyX61s' Timer1 is also an exception... // WGM_NORMAL and WGM_CLR_ON_COMPARE are identical... // comparing to OCR1C // AND only possible when PWM1x is zero... // AGAIN: ONLY THE "UNIVERSAL" MODES are currently implemented // This has several fancy features. // Replacing the switch statement below with this didn't save any space // and, frankly, the switch statement is more intuitive // wgmLb=0; // wgmHb=0; // if(wgm == WGM_PHASE_PWM) // wgmLb = 0xff; switch(wgm) { // Moving this case with default saved 10 text and 4 data bytes! // case WGM_FAST_PWM: // wgmLb = 0; // wgmHb = 0; // break; case WGM_PHASE_PWM: wgmLb = 1; //0xff; wgmHb = 0; break; case WGM_FAST_PWM: // This one really has bits = 0 0 case WGM_NORMAL: case WGM_CLR_ON_COMPARE: //For these modes, the WGM bits are Don't Cares // ("Normal" counting is determined by PWM1x = 0) default: //default shouldn't happen... wgmLb = 0; wgmHb = 0; break; } //NOTE: TinyX61s' WGM bits are both in TCCR1D (very unusual) writebit(WGM10, TCCR1D, wgmLb); writebit(WGM11, TCCR1D, wgmHb); // writeMasked(wgmLb, (1<<WGM10), TCCR1D); // writeMasked(wgmHb, (1<<WGM11), TCCR1D); #elif (!defined(WGM10) || !defined(WGM12) || !defined(TCCR1A) \ || !defined(TCCR1B)) //defined(_AVR_IOTNx5_H_) #warning "This device's Timer1 doesn't appear to have (normal) WGM modes." #warning " Or, at least, I haven't figured out how to implement them yet" #warning " calls to timer_setWGM(1,...) will error" return 1; #else //The "Universal" WGM settings for Timer1 are set here... writebit(WGM10, TCCR1A, wgmLb); writebit(WGM12, TCCR1B, wgmHb); // writeMasked(wgmLb, (1<<WGM10), TCCR1A); // writeMasked(wgmHb, (1<<WGM12), TCCR1B); #endif break; //From here, only compile for timers that exist... //at least "exist" as expected... #if defined(T2_WGMReg) case 2: writebit(WGM20, T2_WGMReg, wgmLb); writebit(WGM21, T2_WGMReg, wgmHb); // writeMasked(wgmLb, (1<<WGM20), T2_WGMReg); // writeMasked(wgmHb, (1<<WGM21), T2_WGMReg); break; #endif #if defined(TCCR3A) case 3: writebit(WGM30, TCCR3A, wgmLb); writebit(WGM32, TCCR3B, wgmHb); // writeMasked(wgmLb, (1<<WGM30), TCCR3A); // writeMasked(wgmHb, (1<<WGM32), TCCR3B); break; #endif default: return 1; break; } return 0; }
void fsksym(FILE* file, char symbol){ //Start bit. writebit(file,0); for(int i=0;i<5;i++){ writebit(file,((symbol)>>i)&1); } //Stop bits. writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); writebit(file,1); }
void pack(const char *input, const char *output) { #ifdef STAT clock_t time1, time2; time1 = clock(); #endif int c, i, j; FILE *infile = fopen(input, "r"); assert(infile); int size = ptablebuild(infile, ptable); encode(0, size - 1); printf("code table size: %d\n", size); #ifdef STAT FILE *codetable = fopen("codetable", "wb"); assert(codetable); for (i = 0; i < size; ++i) { fprintf(codetable, "%c %s %f \n", ptable[i].ch, codes[ptable[i].ch], ptable[i].p); printf("%c->%s\n", ptable[i].ch, codes[ptable[i].ch]); } fclose(codetable); #endif for (i = 0; i < size; ++i) printf("%c->%s\n", ptable[i].ch, codes[ptable[i].ch]); FILE *outfile = fopen(output, "wb"); assert(outfile); putc(size - 1, outfile); buffer buff; buff.size = buff.v = 0; char codesize[8], codebit[8], *ch; for (i = 0; i < size; ++i) { c = ptable[i].ch; chartobit(c, codebit); for (j = 0; j < 8; ++j) writebit(outfile, &buff, codebit[j]); // 8 bits of the code chartobit(strlen(codes[c]) - 1, codesize); for (j = 0; j < 8; ++j) writebit(outfile, &buff, codesize[j]); // size of code j = -1; ch = codes[c]; while (ch[++j] != '\0') writebit(outfile, &buff, ch[j]); // code } fseek(infile, 0, SEEK_SET); while ((c = getc(infile)) != EOF) { ch = codes[c]; j = -1; while (ch[++j] != '\0') writebit(outfile, &buff, ch[j]); } if (buff.size != 8) putc(buff.v, outfile); putc(buff.size, outfile); fclose(outfile); fclose(infile); #ifdef STAT time2 = clock(); printf("time:%f\n", (double)(time2 - time1) / (double)CLOCKS_PER_SEC); #endif }