unsigned int baud_time_get() { #ifdef ___MAPLE timer4.pause(); unsigned int tmp = timer4.getCount(); //get current timer count timer4.setCount(0); // reset timer count timer4.refresh(); timer4.resume(); #endif #ifdef ___ARDUINO TCCR1B &= 0xF8; // Clear CS10/CS11/CS12 bits, stopping the timer unsigned int tmp = int(TCNT1/2); // get current timer count, dividing by two // because Arduino timer is counting at 2Mhz instead of 1Mhz // due to limited prescaler selection tmp += 0x8000 * baudOverflow; // if timer overflowed, we will add 0xFFFF/2 TCNT1 = 0; // reset timer count baudOverflow = false; // reset baudOverflow after resetting timer TCCR1B |= (1 << CS11); // Configure for 8 prescaler, restarting timer #endif #ifdef ___TEENSY unsigned int tmp = int(FTM0_CNT*2.8); FTM0_CNT = 0x0; #endif return tmp; }
void setup() { // Setup our pins pinMode(BOARD_LED_PIN, OUTPUT); pinMode(VGA_R, OUTPUT); pinMode(VGA_G, OUTPUT); pinMode(VGA_B, OUTPUT); pinMode(VGA_V, OUTPUT); pinMode(VGA_H, OUTPUT); digitalWrite(VGA_R, LOW); digitalWrite(VGA_G, LOW); digitalWrite(VGA_B, LOW); digitalWrite(VGA_H, HIGH); digitalWrite(VGA_V, HIGH); // Fill the logo array with color patterns corresponding to its // truth value. Note that we could get more tricky here, since // there are 3 bits of color. for (int y = 0; y < y_max; y++) { for (int x = 0; x < x_max; x++) { logo[y][x] = logo[y][x] ? ON_COLOR : OFF_COLOR; } } // This gets rid of the majority of the interrupt artifacts; // there's still a glitch for low values of y, but let's not worry // about that. (Probably due to the hackish way vsync is done). SerialUSB.end(); systick_disable(); // Configure timer.pause(); // while we configure timer.setPrescaleFactor(1); // Full speed timer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); timer.setMode(TIMER_CH2, TIMER_OUTPUT_COMPARE); timer.setMode(TIMER_CH3, TIMER_OUTPUT_COMPARE); timer.setMode(TIMER_CH4, TIMER_OUTPUT_COMPARE); timer.setOverflow(2287); // Total line time timer.setCompare(TIMER_CH1, 200); timer.attachInterrupt(TIMER_CH1, isr_porch); timer.setCompare(TIMER_CH2, 300); timer.attachInterrupt(TIMER_CH2, isr_start); timer.setCompare(TIMER_CH3, 2170); timer.attachInterrupt(TIMER_CH3, isr_stop); timer.setCompare(TIMER_CH4, 1); // Could be zero, I guess timer.attachInterrupt(TIMER_CH4, isr_update); timer.setCount(0); // Ready... timer.resume(); // Go! }
void baud_timer_restart() { #ifdef ___MAPLE timer4.setCount(0); timer4.refresh(); #endif #ifdef ___ARDUINO TCNT1 = 0; baudOverflow = false; #endif #ifdef ___TEENSY FTM0_CNT = 0x0; #endif }
//Timer control routines void baud_timer_init() { #ifdef ___MAPLE timer4.pause(); // Pause the timer while configuring it timer4.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE); // Set up interrupt on channel 1 timer4.setCount(0); // Reset count to zero timer4.setPrescaleFactor(72); // Timer counts at 72MHz/72 = 1MHz 1 count = 1uS timer4.setOverflow(0xFFFF); // reset occurs at 15.259Hz timer4.refresh(); // Refresh the timer's count, prescale, and overflow timer4.resume(); // Start the timer counting #endif #ifdef ___ARDUINO cli(); // stop interrupts during configuration TCCR1A = 0; // Clear TCCR1A register TCCR1B = 0; // Clear TCCR1B register TCNT1 = 0; // Initialize counter value OCR1A = 0xFFFF; // Set compare match register to maximum value TCCR1B |= (1 << WGM12); // CTC mode // We want 1uS ticks, for 16MHz CPU, we use prescaler of 16 // as 1MHz = 1uS period, but Arduino is lame and only has // 3 bit multiplier, we can have 8 (overflows too quickly) // or 64, which operates at 1/4 the desired resolution TCCR1B |= (1 << CS11); // Configure for 8 prescaler TIMSK1 |= (1 << OCIE1A); // enable compare interrupt sei(); // re-enable interrupts #endif #ifdef ___TEENSY FTM0_MODE |= FTM_MODE_WPDIS; FTM0_CNT = 0; FTM0_CNTIN = 0; FTM0_SC |= FTM_SC_PS(7); FTM0_SC |= FTM_SC_CLKS(1); FTM0_MOD = 0xFFFF; FTM0_MODE |= FTM_MODE_FTMEN; /* PIT_LDVAL1 = 0x500000; PIT_TCTRL1 = TIE; PIT_TCTRL1 |= TEN; PIT_TFLG1 |= 1; */ #endif }
//invoked as configured by the DMA mode flags. void dma_isr() { dma_irq_cause cause = dma_get_irq_cause(DMA1, DMA_CH1); //using serialusb to print messages here is nice, but //it takes so long, we may never exit this isr invocation //before the next one comes in.. (dma is fast.. m'kay) timer4.setCount(0); // clear counter if(ppm_timeout) ppm_timeout=0; switch(cause) { case DMA_TRANSFER_COMPLETE: // Transfer completed //SerialUSB.println("DMA Complete"); dma_data_captured=1; break; case DMA_TRANSFER_HALF_COMPLETE: // Transfer is half complete SerialUSB.println("DMA Half Complete"); break; case DMA_TRANSFER_ERROR: // An error occurred during transfer SerialUSB.println("DMA Error"); dma_data_captured=1; break; default: // Something went horribly wrong. // Should never happen. SerialUSB.println("DMA WTF"); dma_data_captured=1; break; } }
void init_ppm_timer() { timer4.pause(); timer4.setPrescaleFactor(TIMER_PRESCALE); timer4.setOverflow(65535); timer4.setCount(0); // use channel 2 to detect when we stop receiving // a ppm signal from the encoder. timer4.setMode(TIMER_CH2, TIMER_OUTPUT_COMPARE); timer4.setCompare(TIMER_CH2, 65535); timer4.attachCompare2Interrupt(ppm_timeout_isr); timer4.refresh(); //capture compare regs TIMx_CCRx used to hold val after a transition on corresponding ICx //when cap occurs, flag CCXIF (TIMx_SR register) is set, //and interrupt, or dma req can be sent if they are enabled. //if cap occurs while flag is already high CCxOF (overcapture) flag is set.. //CCIX can be cleared by writing 0, or by reading the capped data from TIMx_CCRx //CCxOF is cleared by writing 0 to it. //Clear the CC1E bit to disable capture from the counter as we set it up. //CC1S bits aren't writeable when CC1E is set. //CC1E is bit 0 of CCER (page 401) bitClear(r.gen->CCER,0); //Capture/Compare 1 Selection // set CC1S bits to 01 in the capture compare mode register 1. // 01 selects TI1 as the input to use. (page 399 stm32 reference) // (assuming here that TI1 is D16, according to maple master pin map) //CC1S bits are bits 1,0 bitClear(r.gen->CCMR1, 1); bitSet(r.gen->CCMR1, 0); //Input Capture 1 Filter. // need to set IC1F bits according to a table saying how long // we should wait for a signal to be 'stable' to validate a transition // on the input. // (page 401 stm32 reference) //IC1F bits are bits 7,6,5,4 bitClear(r.gen->CCMR1, 7); bitClear(r.gen->CCMR1, 6); bitSet(r.gen->CCMR1, 5); bitSet(r.gen->CCMR1, 4); //sort out the input capture prescaler IC1PSC.. //00 no prescaler.. capture is done at every edge detected bitClear(r.gen->CCMR1, 3); bitClear(r.gen->CCMR1, 2); //select the edge for the transition on TI1 channel using CC1P in CCER //CC1P is bit 1 of CCER (page 401) // 0 = rising (non-inverted. capture is done on a rising edge of IC1) // 1 = falling (inverted. capture is done on a falling edge of IC1) bitClear(r.gen->CCER,1); //set the CC1E bit to enable capture from the counter. //CC1E is bit 0 of CCER (page 401) bitSet(r.gen->CCER,0); //enable dma for this timer.. //sets the Capture/Compare 1 DMA request enable bit on the DMA/interrupt enable register. //bit 9 is CC1DE as defined on page 393. bitSet(r.gen->DIER,9); }