/** * \fn void note(char temps, int note) * \brief Permet de jouer une note pendant un certain temps * \param [IN] temps est la duree pendant laquelle on souhaite jouer la note - temps ne doit pas depasser la valeur 11 ( 2^8 / 5760 ) [IN] note est la fréquence d'OCR0A que l'on souhaite jouer */ void note(char temps, int note) { start_timer0(note); start_timer1(temps * 5760); // 100 ms wait_OCR1A_timer1(); stop_timer1(); stop_timer0(); }
uint8_t process_ARE_frame(uint8_t status_code) { uint8_t ack_needed; uint8_t data_size=0; uint8_t command; // LEDs_ToggleLEDs(LED0); // indicate correct frame command=(uint8_t)ARE_frame.request_code; CIM_frame.cim_feature=ARE_frame.cim_feature; CIM_frame.serial_number=ARE_frame.serial_number; CIM_frame.reply_code=(((uint16_t)status_code)<<8) + command; data_size=(uint8_t)ARE_frame.data_size; ack_needed=1; // if ((status_code & (CIM_ERROR_INVALID_ARE_VERSION | CIM_ERROR_CRC_MISMATCH)) == 0) if ((status_code & CIM_ERROR_INVALID_ARE_VERSION) == 0) { // UART_Print(" feature "); UART_Putchar(command); // no serious packet error switch (command) { // process requested command case CMD_REQUEST_FEATURELIST: if (data_size==0) { reply_FeatureList(); // reply requested feature list ack_needed=0; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_RESET_CIM: if (data_size!=0) status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_START_CIM: if (data_size==0) { cli(); init_CIM_frame(); setupHardware(); start_timer1(); sei(); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_STOP_CIM: if (data_size==0) { first_packet=1; // reset first frame indicator etc. stop_timer1(); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_READ_FEATURE: // read feature from CIM switch (ARE_frame.cim_feature) { case TEENSY_CIM_FEATURE_UNIQUENUMBER: // read unique serial number if (data_size==0) { reply_UniqueNumber(); ack_needed=0; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; default: // not a valid read feature; status_code |= CIM_ERROR_INVALID_FEATURE; } break; case CMD_REQUEST_WRITE_FEATURE: // write feature to CIM switch (ARE_frame.cim_feature) { // which feature address ? case TEENSY_CIM_FEATURE_MODE_SELECTION: if (data_size==2) { cli(); selection = (uint16_t)ARE_frame.data[0]; selection += ((uint16_t)ARE_frame.data[1])<<8; sei(); } break; case TEENSY_CIM_FEATURE_SET_THRESHOLD: if (data_size==2) { cli(); threshold = (uint16_t)ARE_frame.data[0]; threshold += ((uint16_t)ARE_frame.data[1])<<8; sei(); } break; /*case TEENSY_CIM_FEATURE_SET_ADCPERIOD: if (data_size==2) { cli(); ADC_updatetime= (uint16_t)ARE_frame.data[0]; ADC_updatetime+= ((uint16_t)ARE_frame.data[1])<<8; sei(); } break;*/ default: // not a valid write feature; status_code |= CIM_ERROR_INVALID_FEATURE; } } } if (status_code & CIM_ERROR_INVALID_FEATURE) { // invalid data size or feature // LEDs_ToggleLEDs(LED5); // indicate wrong feature // UART_Print(" invalid data size or no feature "); } if (ack_needed) { reply_Acknowledge(); } return(1); }
static irqreturn_t timer1_handler(int irq, void *dev_id) { struct fast_timer *t; unsigned long flags; /* We keep interrupts disabled not only when we modify the * fast timer list, but any time we hold a reference to a * timer in the list, since del_fast_timer may be called * from (another) interrupt context. Thus, the only time * when interrupts are enabled is when calling the timer * callback function. */ local_irq_save(flags); /* Clear timer1 irq */ *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr); /* First stop timer, then ack interrupt */ /* Stop timer */ *R_TIMER_CTRL = r_timer_ctrl_shadow = (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) | IO_STATE(R_TIMER_CTRL, tm1, stop_ld); /* Ack interrupt */ *R_TIMER_CTRL = r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i1, clr); fast_timer_running = 0; fast_timer_ints++; t = fast_timer_list; while (t) { struct fasttime_t tv; fast_timer_function_type *f; unsigned long d; /* Has it really expired? */ do_gettimeofday_fast(&tv); D1(printk(KERN_DEBUG "t: %is %06ius\n", tv.tv_jiff, tv.tv_usec)); if (fasttime_cmp(&t->tv_expires, &tv) <= 0) { /* Yes it has expired */ #ifdef FAST_TIMER_LOG timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t; #endif fast_timers_expired++; /* Remove this timer before call, since it may reuse the timer */ if (t->prev) { t->prev->next = t->next; } else { fast_timer_list = t->next; } if (t->next) { t->next->prev = t->prev; } t->prev = NULL; t->next = NULL; /* Save function callback data before enabling * interrupts, since the timer may be removed and * we don't know how it was allocated * (e.g. ->function and ->data may become overwritten * after deletion if the timer was stack-allocated). */ f = t->function; d = t->data; if (f != NULL) { /* Run callback with interrupts enabled. */ local_irq_restore(flags); f(d); local_irq_save(flags); } else DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints); } else { /* Timer is to early, let's set it again using the normal routines */ D1(printk(".\n")); } if ((t = fast_timer_list) != NULL) { /* Start next timer.. */ long us = 0; struct fasttime_t tv; do_gettimeofday_fast(&tv); /* time_after_eq takes care of wrapping */ if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff)) us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * 1000000 / HZ + t->tv_expires.tv_usec - tv.tv_usec); if (us > 0) { if (!fast_timer_running) { #ifdef FAST_TIMER_LOG timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; #endif start_timer1(us); } break; } else { /* Timer already expired, let's handle it better late than never. * The normal loop handles it */ D1(printk("e! %d\n", us)); } } } local_irq_restore(flags); if (!t) { D1(printk("t1 stop!\n")); } return IRQ_HANDLED; }
/* In version 1.4 this function takes 27 - 50 us */ void start_one_shot_timer(struct fast_timer *t, fast_timer_function_type *function, unsigned long data, unsigned long delay_us, const char *name) { unsigned long flags; struct fast_timer *tmp; D1(printk("sft %s %d us\n", name, delay_us)); local_irq_save(flags); do_gettimeofday_fast(&t->tv_set); tmp = fast_timer_list; #ifdef FAST_TIMER_SANITY_CHECKS /* Check so this is not in the list already... */ while (tmp != NULL) { if (tmp == t) { printk(KERN_WARNING "timer name: %s data: " "0x%08lX already in list!\n", name, data); sanity_failed++; goto done; } else tmp = tmp->next; } tmp = fast_timer_list; #endif t->delay_us = delay_us; t->function = function; t->data = data; t->name = name; t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000; t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ; if (t->tv_expires.tv_usec > 1000000) { t->tv_expires.tv_usec -= 1000000; t->tv_expires.tv_jiff += HZ; } #ifdef FAST_TIMER_LOG timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t; #endif fast_timers_added++; /* Check if this should timeout before anything else */ if (tmp == NULL || fasttime_cmp(&t->tv_expires, &tmp->tv_expires) < 0) { /* Put first in list and modify the timer value */ t->prev = NULL; t->next = fast_timer_list; if (fast_timer_list) { fast_timer_list->prev = t; } fast_timer_list = t; #ifdef FAST_TIMER_LOG timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; #endif start_timer1(delay_us); } else { /* Put in correct place in list */ while (tmp->next && fasttime_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0) { tmp = tmp->next; } /* Insert t after tmp */ t->prev = tmp; t->next = tmp->next; if (tmp->next) { tmp->next->prev = t; } tmp->next = t; } D2(printk("start_one_shot_timer: %d us done\n", delay_us)); done: local_irq_restore(flags); } /* start_one_shot_timer */
/*************************************************************************** Declaration : int main(void) Function : Main Loop ***************************************************************************/ int main(void) { init_mcu(); init_rf(); init_buffer(); init_protocol(); init_freq(); #ifdef TEST_TX_CW test_rf_transmitter(78); #endif #ifdef TEST_TX_MOD test_rf_modulator(81); #endif #ifdef TEST_RX test_rf_receiver(78); #endif /* Main Background loop */ call_state = CALL_IDLE; while(1) { /* Call States */ switch (call_state) { case CALL_IDLE: #ifdef DONGLE sleep(WDT_TIMEOUT_60MS,STANDBY_MODE); call_status = CALL_NO_ACTIVITY; #ifdef USB SET_VOLUME_DOWN; SET_VOLUME_UP; SET_MUTE_PLAY; SET_MUTE_REC; if(CALL_ACTIVITY_PIN) call_status = CALL_ACTIVITY; #else if(!CALL_SETUP_KEY) call_status = CALL_ACTIVITY; #endif if(call_status == CALL_ACTIVITY) call_state = CALL_SETUP; #endif #ifdef HEADSET sleep(WDT_TIMEOUT_1S,POWER_DOWN_MODE); call_state = CALL_SETUP; #endif break; case CALL_SETUP: #ifdef DONGLE LED_ON; call_status = call_setup(&setup_freq[0],N_FREQ_SETUP); LED_OFF; if(call_status != CALL_SETUP_FAILURE) { init_buffer(); init_rf(); init_protocol(); init_codec(); start_codec(); #ifdef USB // Enable watchdog to handle USB Suspend Mode wdt_enable(WDT_TIMEOUT_15MS); #else start_timer1(0,FRAME_PERIOD, DIV1); #endif call_state = CALL_CONNECTED; } else call_state = CALL_IDLE; #endif #ifdef HEADSET LED_ON; call_status = call_detect(&setup_freq[0],N_FREQ_SETUP,N_REP_SETUP); LED_OFF; if(call_status != CALL_SETUP_FAILURE) { init_buffer(); init_rf(); init_protocol(); init_codec(); call_status &= ~MASTER_SYNC; start_timer1(0,FRAME_PERIOD, DIV1); call_state = CALL_CONNECTED; } else call_state = CALL_IDLE; #endif break; case CALL_CONNECTED: #ifdef DONGLE while(1) { // USB Dongle clears watchdog handling USB Suspend Mode #ifdef USB wdt_reset(); #endif // Send and receive audio packet audio_transfer(); // Handle key code from HEADSET key_code = (signal_in[1] & 0x1F); if(key_code != 0) LED_ON; else LED_OFF; #ifdef USB if(key_code & VOLUME_DOWN) CLEAR_VOLUME_DOWN; else SET_VOLUME_DOWN; if(key_code & VOLUME_UP) CLEAR_VOLUME_UP; else SET_VOLUME_UP; if(key_code & MUTE_PLAY) CLEAR_MUTE_PLAY; else SET_MUTE_PLAY; if(key_code & MUTE_REC) CLEAR_MUTE_REC; else SET_MUTE_REC; #endif // Check if call is to be cleared #ifdef USB if(!CALL_ACTIVITY_PIN) { call_activity_timer += 1; if(call_activity_timer >= TIMEOUT_CALL_ACTIVITY) call_status = CALL_CLEAR; } else call_activity_timer = 0; #else if(!CALL_CLEAR_KEY) call_status = CALL_CLEAR; #endif // Call clearing by HEADSET or DONGLE if((key_code == CALL_CLEARING) || (call_status == CALL_CLEAR)) { signal_out[0] |= SIGNAL_CALL_CLEAR; call_timer += 1; if(call_timer >= TIMEOUT_CALL_CLEAR_MASTER) { call_state = CALL_IDLE; stop_codec(); init_buffer(); init_rf(); init_protocol(); init_codec(); eeprom_write(freq[0],EEPROM_ADR_FREQ0); eeprom_write(freq[1],EEPROM_ADR_FREQ1); LED_OFF; #ifdef USB // Disable watchdog used to handle USB Suspend Mode wdt_disable(); #endif break; } } else signal_out[0] &= ~SIGNAL_CALL_CLEAR; // Call clearing due to Frame Loss if(frame_loss >= TIMEOUT_FRAME_LOSS) { #ifdef USB call_state = CALL_RECONNECT; init_rf(); init_protocol(); // Disable watchdog used to handle USB Suspend Mode wdt_disable(); #else call_state = CALL_RECONNECT; stop_codec(); init_buffer(); init_rf(); init_protocol(); init_codec(); #endif break; } } #endif #ifdef HEADSET while(1) { if(call_status & MASTER_SYNC) { audio_transfer(); } else { call_status = get_sync(); if(call_status & MASTER_SYNC) start_codec(); else frame_loss += 10; } // Read and handle keys key_code = read_key(); signal_out[1] &= 0xE0; signal_out[1] |= key_code; // Call cleared by DONGLE if(signal_in[0] & SIGNAL_CALL_CLEAR) { call_timer += 1; if(call_timer >= TIMEOUT_CALL_CLEAR_SLAVE) { call_state = CALL_IDLE; stop_codec(); init_buffer(); init_rf(); init_protocol(); init_codec(); break; } } else call_timer = 0; // Call clearing due to Frame Loss if(frame_loss >= TIMEOUT_FRAME_LOSS) { call_state = CALL_RECONNECT; stop_codec(); init_buffer(); init_rf(); init_protocol(); init_codec(); break; } } #endif break; case CALL_RECONNECT: #ifdef DONGLE LED_ON; call_status = call_setup(&setup_freq[0],N_FREQ_SETUP); LED_OFF; if(call_status != CALL_SETUP_FAILURE) { #ifdef USB init_rf(); init_protocol(); reset_codec(); call_state = CALL_CONNECTED; #else init_buffer(); init_rf(); init_protocol(); init_codec(); start_codec(); start_timer1(0,FRAME_PERIOD, DIV1); call_state = CALL_CONNECTED; #endif } else { stop_codec(); init_buffer(); init_rf(); init_protocol(); init_codec(); call_state = CALL_IDLE; } #endif #ifdef HEADSET LED_ON; call_status = call_detect(&setup_freq[0],N_FREQ_SETUP,N_REP_RECONNECT); LED_OFF; if(call_status != CALL_SETUP_FAILURE) { init_buffer(); init_rf(); init_protocol(); init_codec(); call_status &= ~MASTER_SYNC; start_timer1(0,FRAME_PERIOD, DIV1); call_state = CALL_CONNECTED; } else call_state = CALL_IDLE; #endif break; default: break; } } }
int main(){ first_time_boot(); //first time boot parameters read_config(); //nuskaitom config is eeprom //------------- I/O nustatymai ------------------ //LED PORTDDR(LED_PORT) |= _BV(LED1_BIT); LED_PORT &= ~_BV(LED1_BIT); PORTDDR(LED_PORT) |= _BV(LED2_BIT); LED_PORT &= ~_BV(LED2_BIT); PORTDDR(LED_PORT) |= _BV(LED3_BIT); LED_PORT &= ~_BV(LED3_BIT); PORTDDR(LCD_LED_PORT) |= _BV(LCD_LED_BIT); //LCD pasvietimas LCD_LED_PORT |= _BV(LCD_LED_BIT); //ijungiam LCD pasvietimas //USART DDRD|=_BV(PD1); //TX PORTD|=_BV(PD1); DDRD&=~_BV(PD0); //RX //ROT ENCODER DDRD&=~_BV(PD3); //INT1 PORTD|=_BV(PD3); DDRD&=~_BV(PD4); PORTD|=_BV(PD4); //ROT ENCODER BUTTON DDRB&=~_BV(PB6); PORTB|=_BV(PB6); //PIR DDRD&=~_BV(PD2); //INT0 // PORTD|=_BV(PD2); //PWM OUT DDRB|=_BV(PB3); //----------------- initai ----------------------------- init_uart(UBRR_VAL); lcd_init(LCD_DISP_ON); INT_init(); ADC_init(); timer_init_0(); timer_init_1(); start_timer1(); // TIMSK |=(_BV(OCIE1A)); //iddle timmer on apie(); //puslapiai(); //Nustatom PWM mode // TCCR2=0x6B; //6E; // OCR2=EEPROM_read(24); // OCR2 is EEPROM work_mode=EEPROM_read(25); wmode(work_mode); show_work_mode(); #if debug_mode send_string("OCR2 eeprome: "); send_string(itoa(OCR2, buff, 10)); send_string("\n\r"); #endif //naudojam ADC nuskaitymui // start_timer0(); _delay_ms(200); LCD_LED_PORT &= ~_BV(LCD_LED_BIT); //isjungiam LCD pasvietima sei(); //fade_in(); //fade_out(); while(5){ PORTDDR(LED_PORT)^= (1<<LED3_BIT); // _delay_ms(50); //-------------------- to go into main menu 00-------------------- // if (bit_is_clear(PINB, PB6)){ // lcd_light=1; // } if(meniu==0 && config==0 && read_keypad()==1){ #if debug_mode PORTDDR(LED_PORT)^= (1<<LED2_BIT); send_string("nuspausta knopke\n\r"); #endif if(lcd_light==0) { clock_second=0; clock_millisecond=0; lcd_light=1; LCD_LED_PORT |= _BV(LCD_LED_BIT); //ijungiam LCD pasvietima } else{ LCD_LED_PORT |= _BV(LCD_LED_BIT); //ijungiam LCD pasvietima meniu=1; menu_page=0; sub_menu_page=0; lcd_light=0; puslapiai(); } #if debug_mode debug_meniu(); #endif } //-------------------- main and sub menu routine -------------- while(meniu!=0 && config==0){ if(read_keypad()==1){ if(meniu==1 && config==0){ if(menu_page<4){ //2inis configas (on/off tipo) meniu=2; sub_menu_page=0; puslapiai_2(); #if debug_mode debug_meniu(); #endif } else if (menu_page==4){ //isejimas i configa meniu=3; config=1; read_config(); //nuskaitom config parametrus is eeprom puslapiai_config(); #if debug_mode debug_meniu(); #endif } //exit meniu punktas else if (menu_page==5){ //iseijimas i work_mode(); meniu=0; config=0; show_work_mode(); LCD_LED_PORT &= ~_BV(LCD_LED_BIT); //isjungiam LCD pasvietima #if debug_mode debug_meniu(); #endif } else meniu=meniu; } //-------------------- end of main menu routine -------------- //-------------------- start of sub menu routine -------------- else if (meniu==2 && config==0){ //2inis configas if(sub_menu_page==1) { //OFF vektorius visiems meniu if(menu_page!=4){ meniu=1; work_mode=0; //OFF - wmode EEPROM_write(25, work_mode); wmode(work_mode); puslapiai(); #if debug_mode debug_meniu(); #endif } } else if (sub_menu_page==0){ //ON vektorius if(menu_page==0){ //ON/OFF meniu punkte work_mode=1; //ON - wmode EEPROM_write(25, work_mode); meniu=0; wmode(work_mode); show_work_mode(); _delay_ms(200); LCD_LED_PORT &= ~_BV(LCD_LED_BIT); //isjungiam LCD pasvietima #if debug_mode debug_meniu(); #endif } else if (menu_page==1){ //PIR meniu punktas work_mode=2; //PIR - wmode EEPROM_write(25, work_mode); meniu=0; show_work_mode(); wmode(work_mode); _delay_ms(200); LCD_LED_PORT &= ~_BV(LCD_LED_BIT); //isjungiam LCD pasvietima } else if (menu_page==2){ //PIR/LDR meniu punktas work_mode=3; //PIR/LDR - wmode EEPROM_write(25, work_mode); meniu=0; show_work_mode(); wmode(work_mode); _delay_ms(200); clock_second=0; clock_millisecond=0; lcd_light=1; //LCD_LED_PORT &= ~_BV(LCD_LED_BIT); //isjungiam LCD pasvietima #if debug_mode debug_meniu(); #endif } else if (menu_page==3){ //LDR meniu punktas work_mode=4; //LDR - wmode EEPROM_write(25, work_mode); meniu=0; show_work_mode(); wmode(work_mode); _delay_ms(200); LCD_LED_PORT &= ~_BV(LCD_LED_BIT); //isjungiam LCD pasvietima #if debug_mode debug_meniu(); #endif } } else meniu=meniu; } } } //-------------------- end of sub menu routine -------------- //-------------------------- config --------------------- while(meniu!=0 && config==1){ if(read_keypad()==1){ #if debug_mode PORTDDR(LED_PORT)^= (1<<LED1_BIT); send_string("nuspausta knopke confige\n\r"); #endif //config meniu vaiksciojimas: arba iseinam i main meniu arba nueinam i sub config meniu if(meniu==3 && config==1){ //exit meniu punktas if (config_menu_page==config_menu_page_max){ //iseijimas i work_mode(); meniu=1; config=0; config_menu_page=0; puslapiai(); #if debug_mode debug_meniu(); #endif } //nuejimas i sub config meniu (minPWM, maxPWM, timeOUT ir LDRth nustatymai) else if (config_menu_page!=config_menu_page_max){ meniu=3; config=2; //nuostato nustatymas (pasiziurim, kelintas fadein[] elementas atinka minPWM/maxPWM reiksme EEProme if (config_menu_page==0) nuostatas=nuostato_radimas(minPWM); else if (config_menu_page==1) nuostatas=nuostato_radimas(maxPWM); else nuostatas=nuostatas; puslapiai_config_2(); #if debug_mode debug_meniu(); #endif // break; } } else config=config; } } //---------------------- end of config ----------------------- //---------------------- sub config routine ------------------------- while(meniu!=0 && config==2){ if(read_keypad()==1){ #if debug_mode PORTDDR(LED_PORT)^= (1<<LED1_BIT); send_string("nuspausta knopke sub confige\n\r"); #endif //isejimas is sub configo meniu=3; config=1; nuostatas=0; puslapiai_config(); write_config(); //OCR2=EEPROM_read(24); timer2_set(EEPROM_read(24)); wmode(work_mode); //kad liktu tikrasis work_mode } else config=config; } //---------------------- end of sub config routine ------------------ } }
static irqreturn_t timer1_handler(int irq, void *dev_id) { struct fast_timer *t; unsigned long flags; /* */ local_irq_save(flags); /* */ *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr); /* */ /* */ *R_TIMER_CTRL = r_timer_ctrl_shadow = (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) | IO_STATE(R_TIMER_CTRL, tm1, stop_ld); /* */ *R_TIMER_CTRL = r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i1, clr); fast_timer_running = 0; fast_timer_ints++; t = fast_timer_list; while (t) { struct fasttime_t tv; fast_timer_function_type *f; unsigned long d; /* */ do_gettimeofday_fast(&tv); D1(printk(KERN_DEBUG "t: %is %06ius\n", tv.tv_jiff, tv.tv_usec)); if (fasttime_cmp(&t->tv_expires, &tv) <= 0) { /* */ #ifdef FAST_TIMER_LOG timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t; #endif fast_timers_expired++; /* */ if (t->prev) { t->prev->next = t->next; } else { fast_timer_list = t->next; } if (t->next) { t->next->prev = t->prev; } t->prev = NULL; t->next = NULL; /* */ f = t->function; d = t->data; if (f != NULL) { /* */ local_irq_restore(flags); f(d); local_irq_save(flags); } else DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints); } else { /* */ D1(printk(".\n")); } if ((t = fast_timer_list) != NULL) { /* */ long us = 0; struct fasttime_t tv; do_gettimeofday_fast(&tv); /* */ if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff)) us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * 1000000 / HZ + t->tv_expires.tv_usec - tv.tv_usec); if (us > 0) { if (!fast_timer_running) { #ifdef FAST_TIMER_LOG timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; #endif start_timer1(us); } break; } else { /* */ D1(printk("e! %d\n", us)); } } } local_irq_restore(flags); if (!t) { D1(printk("t1 stop!\n")); } return IRQ_HANDLED; }
static irqreturn_t timer1_handler(int irq, void *dev_id) { struct fast_timer *t; unsigned long flags; local_irq_save(flags); *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr); *R_TIMER_CTRL = r_timer_ctrl_shadow = (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) | IO_STATE(R_TIMER_CTRL, tm1, stop_ld); *R_TIMER_CTRL = r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i1, clr); fast_timer_running = 0; fast_timer_ints++; t = fast_timer_list; while (t) { struct fasttime_t tv; fast_timer_function_type *f; unsigned long d; do_gettimeofday_fast(&tv); D1(printk(KERN_DEBUG "t: %is %06ius\n", tv.tv_jiff, tv.tv_usec)); if (fasttime_cmp(&t->tv_expires, &tv) <= 0) { #ifdef FAST_TIMER_LOG timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t; #endif fast_timers_expired++; if (t->prev) { t->prev->next = t->next; } else { fast_timer_list = t->next; } if (t->next) { t->next->prev = t->prev; } t->prev = NULL; t->next = NULL; /* Save function callback data before enabling * interrupts, since the timer may be removed and * we don't know how it was allocated * (e.g. ->function and ->data may become overwritten * after deletion if the timer was stack-allocated). */ f = t->function; d = t->data; if (f != NULL) { local_irq_restore(flags); f(d); local_irq_save(flags); } else DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints); } else { D1(printk(".\n")); } if ((t = fast_timer_list) != NULL) { long us = 0; struct fasttime_t tv; do_gettimeofday_fast(&tv); if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff)) us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * 1000000 / HZ + t->tv_expires.tv_usec - tv.tv_usec); if (us > 0) { if (!fast_timer_running) { #ifdef FAST_TIMER_LOG timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; #endif start_timer1(us); } break; } else { D1(printk("e! %d\n", us)); } } } local_irq_restore(flags); if (!t) { D1(printk("t1 stop!\n")); } return IRQ_HANDLED; }