//Logical interrupt handler static void interrupt_proc(void){ int i = 0; //Processing the queue REG_VAL* regs = int_queue[gInterruptIndex]; //Setting GPIO pins configuration while (regs[i].reg != 0){//Set registers for gpio up and down volatile unsigned long* addr = (volatile unsigned long*)(regs[i].reg); if (regs[i].set){ *addr |= regs[i].val; //dbg_print("set %x, %x\r\n", (int)addr, (int)(regs[i].val) ); } else { *addr &= ~(regs[i].val); //dbg_print("reset %x, %x\r\n", (int)addr, (int)(regs[i].val) ); } i++; } gInterruptIndex++; if ( gInterruptIndex == (int_timing.tm_size) ){//If the queue is over - tryt update the queue if (g_UpdateFlag){//If there are new data - just reload it into int_queue dbg_print("Update int queue\r\n"); update_int_queue(); g_UpdateFlag = FALSE; } gInterruptIndex = 0; } //Set next timer moment set_timer3(int_timing.time[gInterruptIndex]); //increment interrupt counter //Wow!!! Interrupt is handled }
static void start_timer_interrupts(void){ int i = 0; volatile TIMER_REGS* tptr = (volatile TIMER_REGS*)TMR3_BASE; dbg_print("Start timer interrupts %x\r\n", (unsigned int)TMR3_BASE); if (!TMR3_BASE) return;//if timer3 base value not set we cant do any if (drv_timing.tm_size < 2) return;//This means that some error occurs gInterruptIndex = 0; update_int_queue(); set_timer3(int_timing.time[gInterruptIndex]); tptr->tim12 = 0; tptr->prd12 = 1000;//once we enable interrupts it really occurs at the same moment tptr->intctl_stat = 0;//Interrupts are disabled tptr->tcr = MD12_CONT_RELOAD;//MD12_CONT;//SET CONTINIOUS MODE - ENABLE TIMER tptr->tgcr = TIMMOD_DUAL_UNCHAINED|BW_COMPATIBLE; tptr->tgcr |= (TIM12RS);//out from reset tptr->intctl_stat = CMP_INT_EN12;//Interrupts are enabled tptr->tcr = MD12_CONT_RELOAD;//MD12_CONT;//SET CONTINIOUS MODE - ENABLE TIMER //once the timer starts it generates interrupt so we load correct prd value and so on }
void main(void) { setup_adc(ADC_CLOCK_DIV_8); setup_adc_ports(sAN0); set_adc_channel(0); setup_wdt(WDT_ON); setup_timer_1(T1_EXTERNAL | T1_ENABLE_SOSC); // Set up the timekeeping timer setup_timer_2(T2_DIV_BY_1, 0x28, 1); // Set up SPI clock timer setup_timer_3(T3_INTERNAL | T3_DIV_BY_8); // Set up scheduler timer output_low(ALARM_PIN); enable_interrupts(INT_RDA); // Enable serial interrupt enable_interrupts(INT_TIMER1); // Enable timekeeping timer interrupt enable_interrupts(INT_TIMER3); // Enable scheduler timer interrupt enable_interrupts(GLOBAL); // Enable interrupts globally if(read_eeprom(EEPROM_RESET)==0x42) { time.hours=read_eeprom(EEPROM_HOURS); time.minutes=read_eeprom(EEPROM_MINUTES); time.seconds=read_eeprom(EEPROM_SECONDS); #IFDEF DRINKING_GAME shot_count=read_eeprom(EEPROM_SHOTS); #ENDIF write_eeprom(EEPROM_RESET,0x00); } else { #IFDEF DRINKING_GAME time.seconds=0; #ELSE time.seconds=(((uint8_t)timestr[6]-48)*10)+((uint8_t)timestr[7]-46); #ENDIF time.minutes=(((uint8_t)timestr[3]-48)*10)+((uint8_t)timestr[4]-48); time.hours=(((uint8_t)timestr[0]-48)*10)+((uint8_t)timestr[1]-48); // Parse timestr to time struct } memset(command_buffer, 0, sizeof(command_buffer)); memset(command, 0, sizeof(command)); restart_wdt(); init_display(); fprintf(COM1, "HELLO!\r\n"); // Say hello! set_timer1(-32768); // Begin timekeeping t10ms=0; t100ms=0; t100ms0=0; t1s0=0; set_timer3(-20000); // Reset and set scheduler while(TRUE) { restart_wdt(); if(t10ms0==1) { t10ms0=0; if(command_waiting) process_command(); } if(t100ms0==1) { t100ms0=0; update_brightness(); if((alarm)&&(alarm_count<5)) { if(alarm_count==0) output_high(ALARM_PIN); alarm_count++; } else { output_low(ALARM_PIN); alarm=FALSE; alarm_count=0; } } if(t100ms1==5) { t100ms1=0; } if(t1s0==1) { t1s0=0; #IFNDEF DRINKING_GAME toggle_colon(); #ENDIF update_display(); if(manual_alarm==FALSE) wallclock_alarm(); } } }