unsigned timer_single(uint32_t period) { unsigned err = E_OK; if (period == 0) { timer_disable(); } else { IOWR16(A_TIMER, NIOS2_TIMER_PERIODL, period & 0x0000ffff); IOWR16(A_TIMER, NIOS2_TIMER_PERIODH, period >> 16); IOWR16(A_TIMER, NIOS2_TIMER_CONTROL, NIOS2_TIMER_CONTROL_ITO | NIOS2_TIMER_CONTROL_START); } return err; }
/* * Setup timers */ static void hal_priv_timer_setup() { // init the two timers for dwell and fire // enable interrupt for three timers // timer 0 will be the rtc, timer 1 will be for ignition dwell and timer 2 // will be ignition fire uint32_t ienable_register = __rdctl_ienable(); ienable_register |= A_TIMER_0 | A_TIMER_1 | A_TIMER_2; __wrctl_ienable(ienable_register); // set interval of TIMER_0 so the interrupt will be called every 125µs (RTC) IOWR16(A_TIMER_0, NIOS2_TIMER_PERIODL, RTC_PRESCALER_LOW); IOWR16(A_TIMER_0, NIOS2_TIMER_PERIODH, RTC_PRESCALER_HIGH); IOWR16(A_TIMER_1, NIOS2_TIMER_PERIODL, 0x0); IOWR16(A_TIMER_1, NIOS2_TIMER_PERIODH, 0x0); IOWR16(A_TIMER_2, NIOS2_TIMER_PERIODL, 0x0); IOWR16(A_TIMER_2, NIOS2_TIMER_PERIODH, 0x0); IOWR16(A_TIMER_0, NIOS2_TIMER_CONTROL, NIOS2_TIMER_CONTROL_START | NIOS2_TIMER_CONTROL_CONT | NIOS2_TIMER_CONTROL_ITO); IOWR16(A_TIMER_1, NIOS2_TIMER_CONTROL, NIOS2_TIMER_CONTROL_ITO); IOWR16(A_TIMER_2, NIOS2_TIMER_CONTROL, NIOS2_TIMER_CONTROL_ITO); // init the SCCT timer // This timer is used to read the input signal of the RPM meter, and controll // the output for injection ienable_register = __rdctl_ienable(); ienable_register |= IRQ_SCCT_BIT; __wrctl_ienable(ienable_register); // set frequency to the same as TIMER_0 // the prescaler will allways be the value in the SCCT_PSC + 1, so we have to // subtract one from TIMER_0_PERIOD IOWR32(A_SCCT, SCCT_PSC, TIMER_0_PERIOD -1); // enable interrupt of the SCCT IOWR32(A_SCCT, SCCT_CTR_IE, 0x1); // set mode of the first two channels to IC (RPM) and set the mode of the next // six channels to OC (injection) int32_t channelModeFlagMask = SCCT_CH_MS_IC | (SCCT_CH_MS_IC<<1) | (SCCT_CH_MS_OC<<2) | (SCCT_CH_MS_OC<<3) | (SCCT_CH_MS_OC<<4) | (SCCT_CH_MS_OC<<5) | (SCCT_CH_MS_OC<<6) | (SCCT_CH_MS_OC<<7); IOWR32(A_SCCT, SCCT_CH_MS, channelModeFlagMask); // set channels to generate interrupt on rising edge IOWR32(A_SCCT, SCCT_CH_AS, SCCT_IC_POSEDGE | (SCCT_IC_POSEDGE<<2)); // enable interrupt for IC event on both channels IOWR32(A_SCCT, SCCT_CH_IE, 0x3); // interrupt and period of the OC channels will be set during runtime, so // nothing has to be done here. }
/* * setMUX function for a pad + additional pad flags */ static u16 omap_cfg_reg_L(u32 pad_func_index) { static u8 sanity_check = 1; u32 reg_vma; u16 cur_val, wr_val, rdback_val; /* * do sanity check on the omap_mux_pin_cfg[] table */ cy_as_hal_print_message(KERN_INFO" OMAP pins user_pad cfg with address"); if (sanity_check) { if ((omap_mux_pin_cfg[END_OF_TABLE].name[0] == 'E') && (omap_mux_pin_cfg[END_OF_TABLE].name[1] == 'N') && (omap_mux_pin_cfg[END_OF_TABLE].name[2] == 'D')) { cy_as_hal_print_message(KERN_INFO "table is good.\n"); } else { cy_as_hal_print_message(KERN_WARNING "table is bad, fix it"); } /* * do it only once */ sanity_check = 0; } /* * get virtual address to the PADCNF_REG */ reg_vma = (u32)iomux_vma + omap_mux_pin_cfg[pad_func_index].offset; /* * add additional USER PU/PD/EN flags */ wr_val = omap_mux_pin_cfg[pad_func_index].mux_val; cur_val = IORD16(reg_vma); /* * PADCFG regs 16 bit long, packed into 32 bit regs, * can also be accessed as u16 */ IOWR16(reg_vma, wr_val); rdback_val = IORD16(reg_vma); /* * in case if the caller wants to save the old value */ return wr_val; }
/** * @author Andreas Meixner * @brief The one ISR NIOS calls * Whenever an interrupt is pending, NIOS2 will call this ISR. * This function will check which interrupts are pending and will call the * appropriate handler functions of FreeEMS. */ void do_irq() { uint32_t pending = __rdctl_ipending(); // if the flag for a pending timer event ist set if(pending & 0x40) { // see if timer 0 (RTC) is the interrupt source uint32_t timerFlag = IORD16(A_TIMER_0, NIOS2_TIMER_STATUS); //log_printf("t0F: %X\r\n", timerFlag); if((timerFlag & NIOS2_TIMER_STATUS_TO)) { // FreeEMS internaly keeps track of time. For this purpose it assumes the // hardware has a 16bit clock running at 1.25MHz, which generates a tick // interrupt on every tick, and an overflow interrupt everytime the 16bit // counter overflows (every 65536 ticks) NIOS2 has a 32 bit counter, so // the overflow has to be simulated, by generating the interrupt in the // software. check if the high word of the counter value has changed since // the last tick, if so call TimerOverfolw() uint16_t currentTickHighWord = IORD16(A_TIMER_0, NIOS2_TIMER_SNAPH); if(currentTickHighWord != lastTickHighWord) { lastTickHighWord = currentTickHighWord; TimerOverflow(); } // advance the internal RTC RTIISR(); // clear the flag IOWR16(A_TIMER_0, NIOS2_TIMER_STATUS, timerFlag & ~NIOS2_TIMER_STATUS_TO); } // see if Timer_1 (ignition dwell) is the interrupt source timerFlag = IORD16(A_TIMER_1, NIOS2_TIMER_STATUS); if((timerFlag & NIOS2_TIMER_STATUS_TO)) { IgnitionDwellISR(); // clear the flag IOWR16(A_TIMER_1, NIOS2_TIMER_STATUS, timerFlag & ~(NIOS2_TIMER_STATUS_TO)); } // see if Timer_2 (ignition fire) is the interrupt source timerFlag = IORD16(A_TIMER_2, NIOS2_TIMER_STATUS); if((timerFlag & NIOS2_TIMER_STATUS_TO)) { IgnitionFireISR(); IOWR16(A_TIMER_2, NIOS2_TIMER_STATUS, timerFlag & ~(NIOS2_TIMER_STATUS_TO)); } } // if the flag for a pending SCCT timer event is set if(pending & 0x400) { // external interrupt (SCCT) // see if the oc channel 0 (scct) was the interrupt source uint32_t isFlags = IORD32(A_SCCT, SCCT_CH_IS); // if IC channel 0 has a pending interrupt, call PrimaryRPMISR if(isFlags & SCCT_CH_BITS_1(0,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(0,1)); PrimaryRPMISR(); } // if IC channel 1 has a pending interrupt, call SecondaryRPMISR if(isFlags & SCCT_CH_BITS_1(1,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(1,1)); SecondaryRPMISR(); } // if OC channel 2 has a pending interrupt, call Injector1ISR if(isFlags & SCCT_CH_BITS_1(2,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(2,1)); Injector1ISR(); } // if OC channel 3 has a pending interrupt, call Injector2ISR if(isFlags & SCCT_CH_BITS_1(3,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(3,1)); Injector2ISR(); } // if OC channel 4 has a pending interrupt, call Injector3ISR if(isFlags & SCCT_CH_BITS_1(4,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(4,1)); Injector3ISR(); } // if OC channel 5 has a pending interrupt, call Injector4ISR if(isFlags & SCCT_CH_BITS_1(5,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(5,1)); Injector4ISR(); } // if OC channel 6 has a pending interrupt, call Injector5ISR if(isFlags & SCCT_CH_BITS_1(6,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(6,1)); Injector5ISR(); } // if OC channel 7 has a pending interrupt, call Injector6ISR if(isFlags & SCCT_CH_BITS_1(7,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(7,1)); Injector6ISR(); } } }
void timer_disable(void) { IOWR16(A_TIMER, NIOS2_TIMER_CONTROL, NIOS2_TIMER_CONTROL_STOP); }
uint32_t timer_getsnap(void) { IOWR16(A_TIMER, NIOS2_TIMER_SNAPL, 1); return IORD32(A_TIMER, NIOS2_TIMER_SNAPL); }