//Mainline Loop PWM Service Routine -- use to manage output pulse //...and trigger states //---must run only once per 2ms looptime void service_pwm(void) { //Process Decoding Timeout if (STATE_Pwm_Timeout > 0) STATE_Pwm_Timeout--; if (STATE_Pwm_Timeout == 0) STATE_Pwm_Decode = LOOK_FOR_START; //Process component pulse durations switch(STATE_Pwm) { case PWM_OUTPUT_HIGH: PORTA.OUTSET = B8(10000000); //PA7 output high break; case PWM_OUTPUT_PULSE: if (STATE_Pwm_Counter == 0) { //Done with pulse! PORTA.OUTCLR = B8(10000000); //PA7 output low STATE_Pwm = PWM_OUTPUT_LOW; //Update State (Done with pulse) } else { STATE_Pwm_Counter--; //Decrement Counter PORTA.OUTSET = B8(10000000); //PA7 output high } break; case PWM_OUTPUT_LOW: default: PORTA.OUTCLR = B8(10000000); //PA7 output low }//switch }
int IsThumbBranchImme(INSTR instr) { if(B8(11100)==instr.tb.tB2.be11100 || (B8(1101)==instr.tb.tB1.be1101 && B8(1111)!=instr.tb.tB1.cond && B8(1110)!=instr.tb.tB1.cond) ) return 0; return -1; }
int IsThumbLoadWord(INSTR instr) { if(B8(101)==instr.tloadWord.be101 && B8(1111100)==instr.tloadWord.be1111100) { if(15==instr.tloadWord.bits2) return 0; } return -1; }
//NEW: jonathan inline void start_irclock(){ //8MHz:: OCR0A = 120; //1/8e6MHz * 8 (prescale) * OCR0A = period in seconds (for these values 8/8=1, so OCR0A = period in uS) //OCR0A = 180; //for 16MHz clock; 180= 90uS period OCR0A = 140; //for 16MHz clock; 100 = 50uS period; 140 = 70uS period OCR0B = 0x00; //min out the compare registers so that the interrupt flag register is easier for GCC to read (bits will always be 1 so TIFR0 = B4(0110) if no overflow) TCNT0 = 0xFF; //start with overflow flag set to make GCC processing of byte easier TCCR0A = B8(00000010); //CTC MODE, NO I/O BEHAVIORS TCCR0B = B8(00000010); //8MHZ CLOCK / 8 = 256uS PER PERIOD }
int IsThumbBranchMiscell(INSTR instr) { if(B8(1)==instr.tbranchAndMis.be1 && B8(11110)==instr.tbranchAndMis.be11110) { if((B8(001)==instr.tbranchAndMis.op1&101) || (B8(000)==instr.tbranchAndMis.op1&101)) return 0; } return -1; }
int IsThumbCmpBranch(INSTR instr) { if(B8(1)==instr.compareBranch.be1 && B8(0)==instr.compareBranch.be0 && B8(1011)==instr.compareBranch.be1011) { return 0; } return -1; }
int IsArmDataPocReg(INSTR instr) { if(B8(0)==instr.dataProcssingRes.be0 && B8(000)==instr.dataProcssingRes.be000) { if(15==instr.dataProcssingRes.bits1) return 0; } return -1; }
int IsArmBranchReg(INSTR instr) { if(B8(00)==instr.branchGes.be00 && B8(00010010)==instr.branchGes.be00010010 && B8(00)!=instr.branchGes.notBe00 && B8(1111)!=instr.branchGes.cond) { return 0; } return -1; }
int IsArmLoadSinale(INSTR instr) { if(B8(1)==instr.loadSingle.be1 && B8(0)==instr.loadSingle.be0 && B8(01)==instr.loadSingle.be01) { if(15==instr.loadSingle.rn) //rn:pc return 0; } return -1; }
//This init routine actually begins operation (as soon as interrupts get enabled) //LED_ENCODE is OC2B void init_irtx(){ //TIMER 2: 40kHz 50% Square Wave Generator cbi(PORTD, 3); //so that disabled OCR2B = 0 on output cbi(ASSR, 5); //clock from MCU mainline clock (16MHz) enable_output_irclock(); TCCR2B = B8(00000001); //enable timer with no prescaler = 16MHz OCR2A = 200; //toggle after 12.5mS -> 25mS period = 40kHz freq (16MHz clock) TIMSK2 = B8(00000010); //OC2A match interrupt enabled TIFR2; //Timer interrupt flag register sbi(DDRD, 3); //OCR2B as output }
int IsArmLoadMul(INSTR instr) { if(B8(1)==instr.loadMultiple.be1 && B8(1)==instr.loadMultiple.is1 && B8(100)==instr.loadMultiple.be100) { if(B8(1)==instr.loadMultiple.registers&B16(1000000,00000000)) { return 0; } } return -1; }
void init_ui(){ //LED's are located at PF0 (Lower) and PF1 (Upper) PORTF.DIRSET = B8(00001111); //pins 0,1,2,3 to output PORTF.PIN0CTRL = B8(01000000); //Invert the pin (needed to achieve correct PWM output polarity) PORTF.PIN1CTRL = B8(01000000); //Invert the pin (needed to achieve correct PWM output polarity) PORTF.PIN3CTRL = B8(01000000); //Invert the pin (needed to achieve correct PWM output polarity) TCF0.CTRLA = 0x07; //enable; div1024 TCF0.CTRLB = B8(11110011); //All output channels enabled (A through D); Single-slope PWM TCF0.PER = 0x00FF; //Set the top of the counter to basically force 8 bit operation; we do this for speed when calling dimming functions in the future audio_volume(0x00); led_off(LED_0); led_off(LED_1); led_off(LED_3); }
int main(void) { //GIMSK = 0; bit_clear(BUTTON_DDR, BUTTONS); bit_set(BUTTON_PORT, BUTTONS); LED_DDR = B8(1); // set up an interrupt that goes off at 20Hz - by default TCCR0A = BIT(WGM01); TCCR0B = B8(101); // 1M/1024 = ~977 // REM: prescaler reset? PSR10 = 1 TIMER_THRESH = DEFAULT_TIMER_THRESH; // 977 / 49 = ~20 TIMSK0 = BIT(OCIE0A); // turn on the interrupt sei(); // turn on interrupts TIMER_THRESH_DDR = B8(11111111); TIMER_THRESH_PORT = TIMER_THRESH; LED_PORT = 0; uint8_t count = 0; uint8_t wasBoth = 0; // ENHANCEME: working out how to do this more like a real state machine would rock while (1) { uint8_t changes = debounce(~(BUTTON_PIN & BUTTONS)); // invert button state so 1 means "pressed" if (changes) { if (bit_read(debouncedState, BUTTON_INC) && bit_read(debouncedState, BUTTON_DEC)) { // both buttons were pressed TIMER_THRESH = DEFAULT_TIMER_THRESH; wasBoth = 1; } else if ( wasBoth && ! bit_read(debouncedState, BUTTONS)) { // both buttons were released wasBoth = 0; } else if ( ! wasBoth && bit_read(changes, BUTTON_INC) && bit_read(debouncedState, BUTTON_INC)) { // increment button was pressed TIMER_THRESH -= TIMER_THRESH_STEP; // reducing the timer threshold makes it fire faster } else if ( ! wasBoth && bit_read(changes, BUTTON_DEC) && bit_read(debouncedState, BUTTON_DEC)) { // decrement button was pressed TIMER_THRESH += TIMER_THRESH_STEP; } } //LED_PORT = count; // invert count since the LEDs are being sink-driven TIMER_THRESH_PORT = TIMER_THRESH; _delay_ms(1); } }
void f(void) { int b1 = B1(); if (b1) { int b2 = B2(); if (b2) { B3(); } else { B4(); } } B5(); while (B6()) { B12(); int b14; do { B13(); b14 = B14(); } while(b14); B15(); } int b7 = B7(); if (b7 || B8()) { B9(); } B10(); B11(); }
int IsThumbTableBranch(INSTR instr) { if(B8(000)==instr.ttableBranch.be000 && B16(1110,10001101)==instr.ttableBranch.be111010001101) return 0; return -1; }
int IsArmBranchImm(INSTR instr) { if(B8(101)==instr.branchImmediate.be101) { return 0; } return -1; }
int IsThumbBranchReg(INSTR instr) { if(B8(01000111)==instr.tbranchRes.be01000111) { return 0; } return -1; }
//This init routine actually begins operation (as soon as interrupts get enabled) //LED_ENCODE is OC2B void init_irtx() { //TIMER 2: 40kHz 50% Square Wave Generator cbi(PORTD, 3); //so that disabled OCR2B = 0 on output cbi(ASSR, 5); //clock from MCU mainline clock (16MHz) enable_output_irclock(); TCCR2B = B8(00000001); //enable timer with no prescaler = 16MHz OCR2A = 200; //toggle after 12.5mS -> 25mS period = 40kHz freq (16MHz clock) TIMSK2 = B8(00000000); //no interrupts from this timer TIFR2; //Timer interrupt flag register sbi(DDRD, 3); //OCR2B as output //TIMER 1: Data encoding clock - pulse width determination TCCR1A = B8(00000000); //Normal counter TCCR1B = B8(00000100); //Divide by 256 (16MHz/256 = 62.5kHz) TCCR1C = B8(00000000); //No force compare matches }
int IsThumbAddReg(INSTR instr) { if(B8(01000100)==instr.taddRes.be01000100) { if(15==(instr.taddRes.rd1+instr.taddRes.rd2*8)) return 0; } return -1; }
int IsArmDataPrcImm(INSTR instr) { if(B8(001)==instr.dataProcssingImm.be001) { if(15==instr.dataProcssingImm.bits1&B16(11110000,00000000)) return 0; } return -1; }
int IsArmPopMul(INSTR instr) { if(B16(1000,10111101)==instr.popMul.be100010111101) { if(B8(1)==instr.popMul.bits&B16(1000000,00000000)) return 0; } return -1; }
//USRT MODE! MASTER void init_serial(){ // USART initialization UCSR0A=0x00;//just flags in this register UCSR0C=B8(01000110);//N,8-bit data,1 frame format; Clock polarity = data delta on rising, sample on falling edge UBRR0H=0x00; UBRR0L=3; //2.67 Mbps (megabits per second) from 16MHz clock sbi(DDRD,1); //TXD is output pin (data line) sbi(DDRD,4); //XCK is output pin (USRT clock line) UCSR0B=0x08;//No Rx; TX enabled - last line because operation begins on this flag }
int IsArmPopSingal(INSTR instr) { if(B16(0000,00000100)==instr.popSingal.be000000000100 && B16(0100,10011101)==instr.popSingal.be010010011101) { if(B8(1)==instr.popSingal.rt) return 0; } return -1; }
/** * Initializes game. * Loads tile data for BG and OBJ layers. */ void init() { disable_interrupts(); DISPLAY_OFF; /* * LCD off * Window tile map = 9600 * Window display off * BG & window data 8800 * BG tile map 9800 * OBJ size = 8x8 * OBJ display on * BG display on */ LCDC_REG = B8(01000011); BGP_REG = OBP1_REG = B8(11100100); OBP0_REG = B8(11100000); DISPLAY_ON; enable_interrupts(); }
void init_quadrature(){ /* Resource Map ============ PK6: Rotary Channel A PK7: Rotary Channel B */ // SciPSU FP switches have hardware pull-up and hardware debounce PORTK.DIRCLR = B8(11000000); //This is the default condition, but just to be safe PORTK.INT0MASK = B8(01000000); //Enable PORTK.Interrupt0 channel for PK6 PORTK.INT1MASK = B8(10000000); //Enable PORTK.Interrupt1 channel for PK7 PORTK.INTCTRL = B8(00001111); //interrupt 0 & 1 channels set to highest priority //Setup initial edge look directions -- need to enable global interrupts shortly after doing this (so init the quadrature module last in main.c) if ((PORTK.IN & _BV(6)) == 0){PORTK.PIN6CTRL = RISING_EDGE;} else {PORTK.PIN6CTRL = FALLING_EDGE;} if ((PORTK.IN & _BV(7)) == 0){PORTK.PIN7CTRL = RISING_EDGE;} else {PORTK.PIN7CTRL = FALLING_EDGE;} quad_count = 0; quad_state = QUAD_IDLE; }
int IsThumbMovReg(INSTR instr) { if(B8(01000110)==instr.tmoveRes.tMoveRes1.be01000110) { if(15==(instr.tmoveRes.tMoveRes1.rd1+instr.tmoveRes.tMoveRes1.rd2*8)) return 0; } else if(B16(00,00000000)==instr.tmoveRes.tMoveRes2.be0000000000) { if(15==instr.tmoveRes.tMoveRes2.rd) return 0; } return -1; }
void enableIROut(void) { #ifdef TRIPPY_RGB_WAVE TCCR0A = B8(01000010); // COM0A1:0=01 to toggle OC0A on Compare Match // COM0B1:0=00 to disconnect OC0B // bits 3:2 are unused // WGM01:00=10 for CTC Mode (WGM02=0 in TCCR0B) TCCR0B = B8(00000001); // FOC0A=0 (no force compare) // F0C0B=0 (no force compare) // bits 5:4 are unused // WGM2=0 for CTC Mode (WGM01:00=10 in TCCR0A) // CS02:00=001 for divide by 1 prescaler (this starts Timer0) OCR0A = 104; // to output 38,095.2KHz on OC0A (PB0, pin 5) #else TCCR1 = _BV(CS10); // turn on clock, prescale = 1 GTCCR = _BV(PWM1B) | _BV(COM1B0); // toggle OC1B on compare match; PWM mode on OCR1C/B. // these two values give 38khz PWM on IR LED (OC1B == PB4 == pin3), // with 33%ish duty cycle OCR1C = 210; OCR1B = 70; #endif }
/** * Draws the title screen * and halts until START is pushed. */ void showTitle() { UWORD seed; // Load titlescreen and seed RNG DISPLAY_OFF; LCDC_REG = B8(01000001); set_bkg_data(0, title_dataLen, title_data); set_bkg_tiles(0, 0, 20, 18, title_tiles); DISPLAY_ON; waitpad(J_START); seed = DIV_REG; waitpadup(); seed |= (UWORD)DIV_REG << 8; initarand(seed); }
/* read instruction from RAM within 32-bits ARM mode */ bool ARMV5::inst_arm_read(void) { int fault = FAULT_NONE; uint32_t addr = 0; bool cachable = true; if ((rf.pc & B8(11)) != 0) { printb(core_id, d_armv5, "instruction address is not word boundary aligned: 0x%X", rf.pc); } /* address translation */ if (mmu_enable) { fault = vir2phy(rf.pc, &addr, CPSR_MODE(rf.cpsr), false, &cachable); } else { addr = rf.pc; fault = FAULT_NONE; } /* memory access */ if (fault == FAULT_NONE) { if (icache_enable && cachable) { if (!icache_read(rf.pc)) { delay += CYC_ICACHE_MISS; } } else { delay += 2; } if (bus_read(&inst, addr, 4)) { return true; } else { fault = FAULT_EXTERNAL; } } /* fault handler */ cp15.c5_ifsr = fault; cp15.c6_far = rf.pc; return false; }
void pwm_enable() { //TIMER (PORTD.TC0) TCE0.CTRLA = B8(00000101); //Timer Clock source is 32MHz/64; ~130ms Range @ 2uS resolution TCE0.CTRLB = 0x00; //Turn off output pins (for both input capture and waveform generation) TCE0.CTRLC = 0x00; //Only for the compare output unit TCE0.CTRLD = B8(00000000); //Disable Event Unit TCE0.CTRLE = 0x00; //Leave the counter in 16 (rather than 8) bit mode //DIGITAL-TO-ANALOG CONVERTER (DAC) //PORTB.DAC0 -- Vbackground; value set by calibration routine; dac_output0(ENABLE); dac_out1(2000); //about mid scale //ANALOG COMPARATOR ACA.AC0MUXCTRL = B8(00000011); //Pos. input = PA0; Neg. Input = PA5 (DAC1); //ACA.CTRLB = 20; //VCC Scaler = VCC/2 = 1.65V ac_output(DISABLE); //Turn off PA7 output pin (we'll use it directly to control the external peripheral) ACA.AC0CTRL = B8(00111101); //enable AC0; 50mV hysterysis; high priority interrupt on edge toggle; high-speed mode PORTA.OUTCLR = B8(10000000); //PA7 output low PORTA.DIRSET = B8(10000000); //Set PA7 as output (should be anyway) //BUTTON STATE_Autolevel = AUTOLEVEL_IDLE; }