void tim2_isr(void) { if (TIM_SR(TIM2) & TIM_SR_CC2IF) { timer_clear_flag(TIM2, TIM_SR_CC2IF); gpsdo_1pps_irq_handler(&gpsdo); // printf("%u ticks=%u out=%d error=%d phase_error=%d pps_setpoint=%u\n", timer_get_counter(TIM2), gpsdo.pps_time_ticks, gpsdo.pps_steer, (int32_t)gpsdo.pps_error, (int32_t)gpsdo.phase_error, gpsdo.pps_setpoint); } if (TIM_SR(TIM2) & TIM_SR_CC3IF) { timer_clear_flag(TIM2, TIM_SR_CC3IF); gpsdo_housekeeping_irq_handler(&gpsdo); struct gpsdo_sync_stats stats; gpsdo_get_sync_status(&gpsdo, &stats); /* printf("gpsdo sync stats:\n"); printf(" phase error: %d ns\n", stats.phase_error); printf(" period error: %d ns\n", stats.period_error); const char *status_str = "?"; switch (stats.status) { case GPSDO_SYNC_STATUS_UNKNOWN: status_str = "UNKNOWN"; break; case GPSDO_SYNC_STATUS_ADJUSTING: status_str = "ADJUSTING"; break; case GPSDO_SYNC_OK: status_str = "OK"; break; } printf(" sync status: %s\n", status_str); */ } }
void tim1_cc_isr(void) { if (TIM_SR(TIM1) & TIM_SR_CC1IF) { sampler_stop(&sampler); sampler_save_buffer(&sampler); /* Do not start again, otherwise we overwrite old data. * There is no buffer management yet. */ } }
void tim2_isr() { /* LED2 on/off */ gpio_toggle(GPIOB, GPIO6); /* clear interrrupt flag */ TIM_SR(TIM2) &= ~TIM_SR_UIF; }
bool timer_get_flag(u32 timer_peripheral, u32 flag) { if (((TIM_SR(timer_peripheral) & flag) != 0) && ((TIM_DIER(timer_peripheral) & flag) != 0)) { return true; } return false; }
void tim6_isr(void) { TIM_SR(TIM6) &= ~TIM_SR_UIF; if (t6ovf++ > 1000) { printf("TICK %d\n", state.tickcount++); t6ovf = 0; gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN); } }
void tim3_isr(void) { TIM_SR(TIM3) &= ~TIM_SR_UIF; if ( 1||vblank ) { uint16_t a = gpio_port_read ( GPIOB ); if ( a = 37 ) { gpio_toggle_blinkenlight(); __asm__("nop"); } } }
/** * Timer 2 interrupt service routine */ void tim2_isr(void) { TIM_SR(SSI_TIMER) &= ~TIM_SR_UIF;// Clear Interrupt Flag // Check state and run correct handler action switch(ssi_state) { case(SSI_START): // SSI Start of Frame { gpio_clear(SSI_GPIO, SSI_CLK_PIN);// Set the clock low ssi_state = SSI_CLK_LOW; // Change SSI state break; } case(SSI_CLK_HIGH): // SSI Clock High-to-Low { gpio_clear(SSI_GPIO, SSI_CLK_PIN);// Set clock low u8 input_bit = GPIO_IDR(SSI_GPIO) & SSI_DATA_PIN;// Read bit on pin 10 ssi_bit_handler(input_bit); // Call bit handler ssi_state = SSI_CLK_LOW; break; } case(SSI_CLK_LOW): // SSI Clock Low-to-High { // Set clock high gpio_set(SSI_GPIO, SSI_CLK_PIN); if(ssi_counter == 0) { ssi_state = SSI_IDLE; ssi_data_ready_flag = true; TIM_CR1(SSI_TIMER) &= ~TIM_CR1_CEN; // Turn off timer } else ssi_state = SSI_CLK_HIGH; break; } case(SSI_IDLE): // SSI Idle (Not Used) break; default: break; } }
void timer_clear_flag(u32 timer_peripheral, u32 flag) { TIM_SR(timer_peripheral) &= ~flag; }
void tim2_isr ( void ) { //TIM2_SR &= ~TIM_SR_UIF; //clearing update interrupt flag TIM_SR(TIM2) &= ~TIM_SR_UIF; /* Clear interrrupt flag. */ /* ISR HAS TO DO SOMRTHING A LITTLE HEAVY // https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Problem%20with%20DMA-USART%20Rx%20on%20STM32F407VG&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=148 // ie: after setting SR, you need to pause read/writes // ie: if the ISR is too quick, there may be a spurious re-invocation (tail chain), so you need to do a little something to avoid cpu race condition // -- another way to do it, is to do a SR read (which blocks until its 'set' finishes), thus stalling until the ISR is 'done': //void SPI2_IRQHandler(void) //{ // volatile unsigned int dummy; // ... some code... // SPI2_CR2 &= ~SPI_CR2_RXNEIE; // Turn off RXE interrupt enable // ...some code... // dummy = SPI2_SR; // Prevent tail-chaining. // return; //} */ // VGA line logic // // line1 // line2 // .. // line600 // front porch blank 1 line // vsync pulse 4 lines // back porch blank 23 lines // \__> back to top // // handle vblank stuff // - front porch, leads to // - vsync, leads to // - back porch // vsync is normally HIGH, but goes to LOW during pulse done_sync = 0; if ( front_porch_togo ) { front_porch_togo --; vblank_active(); if ( ! front_porch_togo ) { // on exit front porch, start vsync pulse vsync_go_low(); vsync_togo = 2; } done_sync = 1; goto hsync; //return; // do nothing.. } if ( vsync_togo ) { vsync_togo --; if ( ! vsync_togo ) { // on exit vsync pulse, start back porch vsync_go_high(); back_porch_togo = 33; } done_sync = 1; goto hsync; //return; } if ( back_porch_togo ) { back_porch_togo --; if ( ! back_porch_togo ) { line_count = 1; vblank_inactive(); } done_sync = 1; goto hsync; //return; // do nothing.. } hsync: // hsync period.. // should use timer/interupt to 'end the line' and go hsync? // /* horiz Front Porch */ i = 16; while ( i-- ) { __asm__("nop"); } /* Horizontal Sync pulse (low) */ hsync_go_low(); i = 103; while ( i-- ) { __asm__("nop"); } /* horiz Back Porch */ hsync_go_high(); i = 50; while ( i-- ) { __asm__("nop"); } if ( done_sync ) { return; } // center horizontally; burn some time so image isn't fully on left #ifndef VGA_DMA i = 40; while ( i-- ) { __asm__("nop"); } #endif // actual line data // // line data on/off/on/off.. // off for hsync/porch business! #if RENDER_ATALL // pull from array // center vertically .. dma seems blurry with this so only for non-DMA #if 1 if ( line_count < 40 ) { goto scanline_done; } i = (line_count-40)/2; #else i = (line_count)/2; #endif // done? if ( i >= FBHEIGHT ) { goto scanline_done; } #ifdef VGA_DMA uint8_t *p = fb_active + ( i * FBWIDTH ); dma_memcpy ( p, (unsigned char*) &(GPIO_ODR(GPIOC)) /*&GPIOC->ODR*/, FBWIDTH, DMA_MEMCPY_INCSRC ); scanline_done: #else #define OLD_EMIT_PIXEL() \ GPIO_ODR(GPIOC) = *p++; \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); \ __asm__("nop"); // 11 NOP's is pretty ideal unsigned char c; #define EMIT_PIXEL() \ c = *p++; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; \ GPIO_ODR(GPIOC) = c; // paint the image uint8_t *p = fb_active + ( i * FBWIDTH ); i = (FBWIDTH) / 16; while ( i-- ) { EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); // 8 EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); EMIT_PIXEL(); // 8 } // disable all colour pins (dma does it itself in its isr) //GPIO_BSRR(GPIOC) = 0x00; scanline_done: gpio_clear ( GPIOC, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 ); #endif // DMA? #endif // entering vblank period? // if ( line_count > VISIBLE_ROWS ) { front_porch_togo = 10; _vblank_count++; // entering vblank return; // entering front porch } line_count++; }
int main ( void ) { #if 1 // go for 120MHz, built into libopencm3 // requires: external 8MHz crystal on pin5/6 with associated caps to ground rcc_clock_setup_hse_3v3 ( &hse_8mhz_3v3 [ CLOCK_3V3_120MHZ ] ); #endif #if 1 // fill framebuffer with offset squares //unsigned char i; unsigned int x, y; unsigned char v; for ( y = 0; y < FBHEIGHT; y++ ) { //i = 0; i = ( y / 10 ) % 5; for ( x = 0; x < FBWIDTH; x++ ) { if ( x % 10 == 0 ) { i++; } if ( i == 0 ) { v = (unsigned char) GPIO0; } else if ( i == 1 ) { v = (unsigned char) GPIO1; } else if ( i == 2 ) { v = (unsigned char) GPIO2; } else if ( i == 3 ) { v = (unsigned char) GPIO3; } else if ( i == 4 ) { v = (unsigned char) GPIO4; } else if ( i == 5 ) { v = (unsigned char) GPIO5; } else { i = 0; v = (unsigned char) GPIO0; } *( framebuffer + ( y * FBWIDTH ) + x ) = v; //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char) 0; //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO3 ); //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO5 ); //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO1 | GPIO3 ); //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO1 | GPIO0 ); //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO0 | GPIO1 ); //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO0 | GPIO1 | GPIO2 | GPIO3 ); //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO2 | GPIO3 ); //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO4 | GPIO5 ); } // x } // y #endif #if 0 // fill framebuffer with vertical stripes of all colours (1px per colour) //unsigned char i; unsigned int x, y; unsigned char v; for ( y = 0; y < FBHEIGHT; y++ ) { i = 0; for ( x = 0; x < FBWIDTH; x++ ) { *( framebuffer + ( y * FBWIDTH ) + x ) = i / 6; //*( framebuffer + ( y * FBWIDTH ) + x ) = (unsigned char)( GPIO0 | GPIO1 ); i++; } // x } // y #endif #if 0 // vertical strip every 10 pixels //unsigned char i; unsigned int x, y; for ( y = 0; y < FBHEIGHT; y++ ) { i = 0; for ( x = 0; x < FBWIDTH; x++ ) { if ( i >= 9 ) { *( framebuffer + ( y * FBWIDTH ) + x ) = GPIO0; } if ( i == 12 ) { i = 0; } i++; } // x } // y #endif gpio_setup(); /* Enable TIM2 clock. */ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM2EN); //__enable_irq(); //cm_enable_interrupts(); nvic_setup(); timer2_setup(); dma_setup(); gpio_set ( GPIOB, GPIO12 ); TIM_SR(TIM2) &= ~TIM_SR_UIF; /* Clear interrrupt flag. */ while ( 1 ) { __asm__("nop"); } // while forever return 0; }
void tim2_isr ( void ) { //TIM2_SR &= ~TIM_SR_UIF; //clearing update interrupt flag TIM_SR(TIM2) &= ~TIM_SR_UIF; /* Clear interrrupt flag. */ /* ISR HAS TO DO SOMRTHING A LITTLE HEAVY // https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Problem%20with%20DMA-USART%20Rx%20on%20STM32F407VG&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=148 // ie: after setting SR, you need to pause read/writes // ie: if the ISR is too quick, there may be a spurious re-invocation (tail chain), so you need to do a little something to avoid cpu race condition // -- another way to do it, is to do a SR read (which blocks until its 'set' finishes), thus stalling until the ISR is 'done': //void SPI2_IRQHandler(void) { volatile unsigned int dummy; ... some code... SPI2_CR2 &= ~SPI_CR2_RXNEIE; // Turn off RXE interrupt enable ...some code... dummy = SPI2_SR; // Prevent tail-chaining. return; } */ #if 0 __asm__("nop"); gpio_toggle(GPIOB, GPIO12); /* LED on/off. */ #endif // VGA line logic // // line1 // line2 // .. // line600 // front porch blank 1 line // vsync pulse 4 lines // back porch blank 23 lines // \__> back to top // // handle vblank stuff // - front porch, leads to // - vsync, leads to // - back porch // vsync is normally HIGH, but goes to LOW during pulse done_sync = 0; if ( front_porch_togo ) { front_porch_togo --; if ( ! front_porch_togo ) { // on exit front porch, start vsync pulse vsync_go_low(); vsync_togo = 4; } done_sync = 1; goto hsync; //return; // do nothing.. } if ( vsync_togo ) { vsync_togo --; if ( ! vsync_togo ) { // on exit vsync pulse, start back porch vsync_go_high(); back_porch_togo = 23; } done_sync = 1; goto hsync; //return; } if ( back_porch_togo ) { back_porch_togo --; if ( ! back_porch_togo ) { line_count = 1; } done_sync = 1; goto hsync; //return; // do nothing.. } hsync: // hsync period.. // should use timer/interupt to 'end the line' and go hsync? // /* 1uS Front Porch */ /* 1uS */ i = 22; while ( i-- ) { __asm__("nop"); } /* 3.2uS Horizontal Sync */ hsync_go_low(); i = 60; while ( i-- ) { __asm__("nop"); } /* 2.2uS Back Porch */ hsync_go_high(); i = 45; while ( i-- ) { __asm__("nop"); } if ( done_sync ) { return; } // actual line data // // line data on/off/on/off.. // off for hsync/porch business! #if 1 // pull from array //i = line_count % FBHEIGHT; i = line_count/4; unsigned char *p = framebuffer + ( i * FBWIDTH ); // 240 //p = framebuffer + ( (line_count%240) * 240 ); #if 1 dma_memcpy ( p, 320 ); #else i = 90 / 10; // 120 while ( i-- ) { rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); rgb_go_level ( (*p++) ); //gpio_set ( GPIOC, *p++ ); //GPIO_BSRR(GPIOC) = *p++; //GPIO_BSRR(GPIOC) = 1<<6; } // disable all colour pins (dma does it itself in its isr) //GPIO_BSRR(GPIOC) = 0x00; gpio_clear ( GPIOC, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 ); //rgb_go_level ( 0 ); #endif #endif // entering vblank period? // if ( line_count > VISIBLE_ROWS ) { front_porch_togo = 1; return; // entering front porch } line_count++; }