Exemple #1
0
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;
}
Exemple #2
0
/*
 * 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();
    }
  }
}
Exemple #5
0
void timer_disable(void) {
  IOWR16(A_TIMER, NIOS2_TIMER_CONTROL, NIOS2_TIMER_CONTROL_STOP);
}
Exemple #6
0
uint32_t timer_getsnap(void) {
  IOWR16(A_TIMER, NIOS2_TIMER_SNAPL, 1);
  return IORD32(A_TIMER, NIOS2_TIMER_SNAPL);
}