void clock_init(void) { /* * The initial state : * SYSCLK from HSI (=8MHz), no divider on AHB, APB1, APB2 * PLL unlocked, RTC enabled on LSE */ config_hispeed_clock(); /* configure RTC clock */ wait_rtc_ready(); prepare_rtc_write(); /* set RTC divider to /1 */ STM32_RTC_PRLH = 0; STM32_RTC_PRLL = 0; finalize_rtc_write(); /* setup RTC EXTINT17 to wake up us from STOP mode */ STM32_EXTI_IMR |= (1 << 17); STM32_EXTI_RTSR |= (1 << 17); /* * Our deep sleep mode is STOP mode. * clear PDDS (stop mode) , set LDDS (regulator in low power mode) */ STM32_PWR_CR = (STM32_PWR_CR & ~2) | 1; /* Enable RTC interrupts */ task_enable_irq(STM32_IRQ_RTC_WAKEUP); task_enable_irq(STM32_IRQ_RTC_ALARM); }
static void lpc_task_enable_irq(void){ task_enable_irq(NPCX_IRQ_SHM); task_enable_irq(NPCX_IRQ_KBC_IBF); task_enable_irq(NPCX_IRQ_PM_CHAN_IBF); task_enable_irq(NPCX_IRQ_PORT80); }
int __hw_clock_source_init(uint32_t start_t) { /* Set the reload and current value. */ GR_TIMEHS_BGLOAD(0, 1) = 0xffffffff; GR_TIMEHS_LOAD(0, 1) = 0xffffffff; /* HW Timer enabled, periodic, interrupt enabled, 32-bit, wrapping */ GR_TIMEHS_CONTROL(0, 1) = 0xe2; /* Event timer disabled */ __hw_clock_event_clear(); /* Account for the clock speed. */ update_prescaler(); /* Clear any pending interrupts */ GR_TIMEHS_INTCLR(0, 1) = 0x1; /* Force the time to whatever we're told it is */ __hw_clock_source_set(start_t); /* Here we go... */ task_enable_irq(GC_IRQNUM_TIMEHS0_TIMINT1); task_enable_irq(GC_IRQNUM_TIMEHS0_TIMINT2); /* Return the Event timer IRQ number (NOT the HW timer IRQ) */ return GC_IRQNUM_TIMEHS0_TIMINT2; }
static void gpio_init(void) { task_enable_irq(MEC1322_IRQ_GIRQ8); task_enable_irq(MEC1322_IRQ_GIRQ9); task_enable_irq(MEC1322_IRQ_GIRQ10); task_enable_irq(MEC1322_IRQ_GIRQ11); task_enable_irq(MEC1322_IRQ_GIRQ20); }
static void setup_ipc(void) { task_enable_irq(ISH_IPC_HOST2ISH_IRQ); task_enable_irq(ISH_IPC_ISH2HOST_CLR_IRQ); ipc_set_pimr(IPC_PEER_HOST_ID, SET_PIMR, PIMR_SIGNAL_IN); ipc_set_pimr(IPC_PEER_HOST_ID, SET_PIMR, PIMR_SIGNAL_CLR); }
int sps_register_rx_handler(enum sps_mode mode, rx_handler_f rx_handler) { if (sps_rx_handler) return -1; sps_rx_handler = rx_handler; sps_configure(mode, SPI_CLOCK_MODE0); task_enable_irq(GC_IRQNUM_SPS0_RXFIFO_LVL_INTR); task_enable_irq(GC_IRQNUM_SPS0_CS_DEASSERT_INTR); return 0; }
static void i2c_init(void) { /* * TODO(crosbug.com/p/23763): Add config options to determine which * channels to init. */ i2c_init_port(I2C1); i2c_init_port(I2C2); /* Enable event and error interrupts */ task_enable_irq(STM32_IRQ_I2C2_EV); task_enable_irq(STM32_IRQ_I2C2_ER); }
static void adc_init(void) { int i; /* Configure GPIOs */ configure_gpio(); /* * Temporarily enable the PLL when turning on the clock to the ADC * module, to work around chip errata (10.4). No need to notify * other modules; the PLL isn't enabled long enough to matter. */ clock_enable_pll(1, 0); /* Enable ADC0 module in run and sleep modes. */ clock_enable_peripheral(CGC_OFFSET_ADC, 0x1, CGC_MODE_RUN | CGC_MODE_SLEEP); /* * Use external voltage references (VREFA+, VREFA-) instead of * VDDA and GNDA. */ LM4_ADC_ADCCTL = 0x01; /* Use internal oscillator */ LM4_ADC_ADCCC = 0x1; /* Disable the PLL now that the ADC is using the internal oscillator */ clock_enable_pll(0, 0); /* No tasks waiting yet */ for (i = 0; i < LM4_ADC_SEQ_COUNT; i++) task_waiting_on_ss[i] = TASK_ID_INVALID; /* Enable IRQs */ task_enable_irq(LM4_IRQ_ADC0_SS0); task_enable_irq(LM4_IRQ_ADC0_SS1); task_enable_irq(LM4_IRQ_ADC0_SS2); task_enable_irq(LM4_IRQ_ADC0_SS3); /* 2**6 = 64x oversampling */ LM4_ADC_ADCSAC = 6; /* Initialize ADC sequencer */ for (i = 0; i < ADC_CH_COUNT; ++i) adc_configure(adc_channels + i); /* Disable ADC0 module until it is needed to conserve power. */ clock_disable_peripheral(CGC_OFFSET_ADC, 0x1, CGC_MODE_RUN | CGC_MODE_SLEEP); }
int __hw_clock_source_init(uint32_t start_t) { /* * 1. Use ITIM16-1 as internal time reading * 2. Use ITIM16-2 for event handling */ /* Enable clock for ITIM peripheral */ clock_enable_peripheral(CGC_OFFSET_TIMER, CGC_TIMER_MASK, CGC_MODE_RUN | CGC_MODE_SLEEP); /* init tick & event timer first */ init_hw_timer(ITIM32, ITIM_SOURCE_CLOCK_APB2); init_hw_timer(ITIM_EVENT_NO, ITIM_SOURCE_CLOCK_32K); /* Set initial prescaler */ update_prescaler(); /* * Override the count with the start value now that counting has * started. */ hw_clock_source_set_preload(start_t, 1); /* Enable interrupt of ITIM */ task_enable_irq(NPCX_IRQ_ITIM32); return NPCX_IRQ_ITIM32; }
static void i2c_init(void) { const struct i2c_port_t *p = i2c_ports; int i; for (i = 0; i < i2c_ports_used; i++, p++) i2c_init_port(p); #ifdef CONFIG_HOSTCMD_I2C_SLAVE_ADDR STM32_I2C_CR1(I2C_PORT_EC) |= STM32_I2C_CR1_RXIE | STM32_I2C_CR1_ERRIE | STM32_I2C_CR1_ADDRIE | STM32_I2C_CR1_STOPIE | STM32_I2C_CR1_NACKIE; #if defined(CONFIG_LOW_POWER_IDLE) && (I2C_PORT_EC == STM32_I2C1_PORT) /* * If using low power idle and EC port is I2C1, then set I2C1 to wake * from STOP mode on address match. Note, this only works on I2C1 and * only if the clock to I2C1 is HSI 8MHz. */ STM32_I2C_CR1(I2C_PORT_EC) |= STM32_I2C_CR1_WUPEN; #endif STM32_I2C_OAR1(I2C_PORT_EC) = 0x8000 | CONFIG_HOSTCMD_I2C_SLAVE_ADDR; #ifdef TCPCI_I2C_SLAVE /* * Configure TCPC address with OA2[1] masked so that we respond * to CONFIG_TCPC_I2C_BASE_ADDR and CONFIG_TCPC_I2C_BASE_ADDR + 2. */ STM32_I2C_OAR2(I2C_PORT_EC) = 0x8100 | CONFIG_TCPC_I2C_BASE_ADDR; #endif task_enable_irq(IRQ_SLAVE); #endif }
static void ext_timer_ctrl(enum ext_timer_sel ext_timer, enum ext_timer_clock_source ext_timer_clock, int start, int with_int, int32_t count) { uint8_t intc_mask; /* rising-edge-triggered */ intc_mask = et_ctrl_regs[ext_timer].mask; *et_ctrl_regs[ext_timer].mode |= intc_mask; *et_ctrl_regs[ext_timer].polarity &= ~intc_mask; /* clear interrupt status */ task_clear_pending_irq(et_ctrl_regs[ext_timer].irq); /* These bits control the clock input source to the exttimer 3 - 8 */ IT83XX_ETWD_ETXPSR(ext_timer) = ext_timer_clock; /* The count number of external timer n. */ IT83XX_ETWD_ETXCNTLR(ext_timer) = count; ext_timer_stop(ext_timer, 0); if (start) ext_timer_start(ext_timer, 0); if (with_int) task_enable_irq(et_ctrl_regs[ext_timer].irq); else task_disable_irq(et_ctrl_regs[ext_timer].irq); }
void lpc_keyboard_put_char(uint8_t chr, int send_irq) { /* Clear programming data bit 7-4 */ IT83XX_KBC_KBHISR &= 0x0F; /* keyboard */ IT83XX_KBC_KBHISR |= 0x10; /* * bit0 = 0, The IRQ1 is controlled by the IRQ1B bit in KBIRQR. * bit1 = 0, The IRQ12 is controlled by the IRQ12B bit in KBIRQR. */ IT83XX_KBC_KBHICR &= 0xFC; /* * Enable the interrupt to keyboard driver in the host processor * via SERIRQ when the output buffer is full. */ if (send_irq) IT83XX_KBC_KBHICR |= 0x01; udelay(16); task_clear_pending_irq(IT83XX_IRQ_KBC_OUT); /* The data output to the KBC Data Output Register. */ IT83XX_KBC_KBHIKDOR = chr; task_enable_irq(IT83XX_IRQ_KBC_OUT); }
static int i2c_tran_write(int p) { struct i2c_port_data *pd = pdata + p; if (pd->flags & I2C_XFER_START) { /* i2c enable */ IT83XX_SMB_HOCTL2(p) = 0x13; /* * bit0, Direction of the host transfer. * bit[1:7}, Address of the targeted slave. */ IT83XX_SMB_TRASLA(p) = pd->addr; /* Send first byte */ IT83XX_SMB_HOBDB(p) = *(pd->out++); pd->widx++; /* clear start flag */ pd->flags &= ~I2C_XFER_START; /* * bit0, Host interrupt enable. * bit[2:4}, Extend command. * bit6, start. */ IT83XX_SMB_HOCTL(p) = 0x5D; } else { /* Host has completed the transmission of a byte */ if (IT83XX_SMB_HOSTA(p) & HOSTA_BDS) { if (pd->widx < pd->out_size) { /* Send next byte */ IT83XX_SMB_HOBDB(p) = *(pd->out++); pd->widx++; /* W/C byte done for next byte */ IT83XX_SMB_HOSTA(p) = HOSTA_NEXT_BYTE; if (pd->i2ccs == I2C_CH_REPEAT_START) { pd->i2ccs = I2C_CH_NORMAL; task_enable_irq(i2c_ctrl_regs[p].irq); } } else { /* done */ pd->out_size = 0; if (pd->in_size > 0) { /* write to read */ i2c_w2r_change_direction(p); } else { if (pd->flags & I2C_XFER_STOP) { /* set I2C_EN = 0 */ IT83XX_SMB_HOCTL2(p) = 0x11; /* W/C byte done for finish */ IT83XX_SMB_HOSTA(p) = HOSTA_NEXT_BYTE; } else { pd->i2ccs = I2C_CH_REPEAT_START; return 0; } } } } } return 1; }
static void gpio_init(void) { int i; /* Enable IRQs now that pins are set up */ for (i = 0; i < ARRAY_SIZE(gpio_irqs); i++) task_enable_irq(gpio_irqs[i]); }
void keyboard_raw_enable_interrupt(int enable) { if (enable) { task_clear_pending_irq(MEC1322_IRQ_KSC_INT); task_enable_irq(MEC1322_IRQ_KSC_INT); } else { task_disable_irq(MEC1322_IRQ_KSC_INT); } }
int __hw_clock_source_init(uint32_t start_t) { #ifdef BOARD_REI /* reload_val = (0xFFFFFFFF / SECOND) * clock_get_freq(); */ /* reload_val = 0xFFFFFFFF; */ #endif /* defined(BOARD_REI) */ /* * Use Timer 0 as the clock. The clock source for the timer block * cannot be prescaled down to 1MHz, therefore, we'll have to handle the * rollovers. * * There's also no match functionality, so set up an additional timer, * Timer 1, to handle events. */ /* Disable the timers. */ ROTOR_MCU_TMR_TNCR(0) &= ~(1 << 0); ROTOR_MCU_TMR_TNCR(1) &= ~(1 << 0); /* * Timer 0 * * Unmask interrupt, set user-defined count mode, and disable PWM. */ ROTOR_MCU_TMR_TNCR(0) = (1 << 1); /* Use the specified start timer value and start the timer. */ __hw_clock_source_set(start_t); /* * Timer 1 * * Unmask interrupt, set user-defined count mode, and disable PWM. */ ROTOR_MCU_TMR_TNCR(1) = (1 << 1); /* Enable interrupts. */ task_enable_irq(ROTOR_MCU_IRQ_TIMER_0); task_enable_irq(ROTOR_MCU_IRQ_TIMER_1); /* Return event timer IRQ number. */ return ROTOR_MCU_IRQ_TIMER_1; }
void ext_timer_start(enum ext_timer_sel ext_timer, int en_irq) { /* enable external timer n */ IT83XX_ETWD_ETXCTRL(ext_timer) |= 0x03; if (en_irq) { task_clear_pending_irq(et_ctrl_regs[ext_timer].irq); task_enable_irq(et_ctrl_regs[ext_timer].irq); } }
void dma_enable_tc_interrupt(enum dma_channel channel) { stm32_dma_chan_t *chan = dma_get_channel(channel); /* Store task ID so the ISR knows which task to wake */ id[channel] = task_get_current(); chan->ccr |= STM32_DMA_CCR_TCIE; task_enable_irq(dma_get_irq(channel)); }
int gpio_enable_interrupt(enum gpio_signal signal) { int irq = gpio_to_irq(gpio_list[signal].port, gpio_list[signal].mask); if (irq == -1) return EC_ERROR_UNKNOWN; else task_enable_irq(irq); return EC_SUCCESS; }
void dma_enable_tc_interrupt_callback(enum dma_channel stream, void (*callback)(void *), void *callback_data) { stm32_dma_stream_t *dma_stream = dma_get_channel(stream); dma_irq[stream].cb = callback; dma_irq[stream].cb_data = callback_data; dma_stream->scr |= STM32_DMA_CCR_TCIE; task_enable_irq(dma_get_irq(stream)); }
/* Put a char to host buffer and send IRQ if specified. */ void lpc_keyboard_put_char(uint8_t chr, int send_irq) { NPCX_HIKDO = chr; CPRINTS("KB put %02x", chr); /* Enable OBE interrupt to detect host read data out */ SET_BIT(NPCX_HICTRL, NPCX_HICTRL_OBECIE); task_enable_irq(NPCX_IRQ_KBC_OBE); if (send_irq) { keyboard_irq_assert(); } }
static void timers_init(void) { /* TIM2 is a 32-bit free running counter with 1Mhz frequency */ STM32_TIM_CR2(2) = 0x0000; STM32_TIM32_ARR(2) = 0xFFFFFFFF; STM32_TIM32_CNT(2) = 0; STM32_TIM_PSC(2) = CPU_CLOCK / 1000000 - 1; STM32_TIM_EGR(2) = 0x0001; /* Reload the pre-scaler */ STM32_TIM_CR1(2) = 1; STM32_TIM_DIER(2) = 0; task_enable_irq(STM32_IRQ_TIM2); }
static void gpio_init(void) { /* Enable IRQs now that pins are set up */ task_enable_irq(STM32_IRQ_EXTI0); task_enable_irq(STM32_IRQ_EXTI1); task_enable_irq(STM32_IRQ_EXTI2); task_enable_irq(STM32_IRQ_EXTI3); task_enable_irq(STM32_IRQ_EXTI4); task_enable_irq(STM32_IRQ_EXTI9_5); task_enable_irq(STM32_IRQ_EXTI15_10); }
static void lpc_send_response_packet(struct host_packet *pkt) { /* Ignore in-progress on LPC since interface is synchronous anyway */ if (pkt->driver_result == EC_RES_IN_PROGRESS) return; /* Write result to the data byte. This sets the TOH status bit. */ LPC_POOL_CMD[1] = pkt->driver_result; /* Clear the busy bit, so the host knows the EC is done. */ task_disable_irq(LM4_IRQ_LPC); LM4_LPC_ST(LPC_CH_CMD) &= ~LM4_LPC_ST_BUSY; task_enable_irq(LM4_IRQ_LPC); }
static void configure_port(int port, int kbps) { MEC1322_I2C_CTRL(port) = CTRL_PIN; MEC1322_I2C_OWN_ADDR(port) = 0x0; configure_port_speed(port, kbps); MEC1322_I2C_CTRL(port) = CTRL_PIN | CTRL_ESO | CTRL_ACK | CTRL_ENI; MEC1322_I2C_CONFIG(port) |= 1 << 10; /* ENAB */ /* Enable interrupt */ MEC1322_I2C_CONFIG(port) |= 1 << 29; /* ENIDI */ MEC1322_INT_ENABLE(12) |= (1 << port); MEC1322_INT_BLK_EN |= 1 << 12; task_enable_irq(MEC1322_IRQ_I2C_0 + port); }
/* HWTimer event handlers */ void __hw_clock_event_set(uint32_t deadline) { fp_t inv_evt_tick = FLOAT_TO_FP(INT_32K_CLOCK/(float)SECOND); int32_t evt_cnt_us; /* Is deadline min value? */ if (evt_expired_us != 0 && evt_expired_us < deadline) return; /* mark min event value */ evt_expired_us = deadline; evt_cnt_us = deadline - __hw_clock_source_read(); #if DEBUG_TMR evt_cnt_us_dbg = deadline - __hw_clock_source_read(); #endif /* Deadline is behind current timer */ if (evt_cnt_us < 0) evt_cnt_us = 1; /* Event module disable */ CLEAR_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN); /* * ITIM count down : event expired : Unit: 1/32768 sec * It must exceed evt_expired_us for process_timers function */ evt_cnt = FP_TO_INT((fp_inter_t)(evt_cnt_us) * inv_evt_tick); if (evt_cnt > TICK_EVT_MAX_CNT) { CPRINTS("Event overflow! 0x%08x, us is %d\r\n", evt_cnt, evt_cnt_us); evt_cnt = TICK_EVT_MAX_CNT; } /* Wait for module disable to take effect before updating count */ while (IS_BIT_SET(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN)) ; NPCX_ITCNT16(ITIM_EVENT_NO) = MAX(evt_cnt, 1); /* Event module enable */ SET_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN); /* Wait for module enable */ while (!IS_BIT_SET(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN)) ; /* Enable interrupt of ITIM */ task_enable_irq(ITIM16_INT(ITIM_EVENT_NO)); }
void __hw_clock_event_set(uint32_t deadline) { uint32_t wait; /* bit0, disable event timer */ IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) &= ~(1 << 0); /* w/c interrupt status */ event_timer_clear_pending_isr(); /* microseconds to timer counter */ wait = deadline - __hw_clock_source_read(); IT83XX_ETWD_ETXCNTLR(EVENT_EXT_TIMER) = wait < EVENT_TIMER_COUNT_TO_US(0xffffffff) ? EVENT_TIMER_US_TO_COUNT(wait) : 0xffffffff; /* enable and re-start timer */ IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) |= 0x03; task_enable_irq(et_ctrl_regs[EVENT_EXT_TIMER].irq); }
static void usart_variant_enable(struct usart_config const *config) { configs[config->hw->index] = config; /* * All three USARTS are clocked from the HSI(8MHz) source. This is * done because the clock sources elsewhere are setup so that the result * of clock_get_freq() is not the input clock frequency to the USARTs * baud rate divisors. */ STM32_RCC_CFGR3 |= 0x000f0003; usart_set_baud_f0_l(config, 8000000); task_enable_irq(config->hw->irq); }
void lpc_keyboard_resume_irq(void) { if (lpc_keyboard_has_char()) { /* The IRQ1 is controlled by the IRQ1B bit in KBIRQR. */ IT83XX_KBC_KBHICR &= ~0x01; /* * When the OBFKIE bit in KBC Host Interface Control Register * (KBHICR) is 0, the bit directly controls the IRQ1 signal. */ IT83XX_KBC_KBIRQR |= 0x01; task_clear_pending_irq(IT83XX_IRQ_KBC_OUT); task_enable_irq(IT83XX_IRQ_KBC_OUT); } }
static void usart_variant_enable(struct usart_config const *config) { /* Use single-bit sampling */ STM32_USART_CR3(config->hw->base) |= STM32_USART_CR3_ONEBIT; /* * Make sure we register this config before enabling the HW. * If we did it the other way around the FREQ_CHANGE hook could be * called before we update the configs array and we would miss the * clock frequency change event, leaving our baud rate divisor wrong. */ configs[config->hw->index] = config; usart_set_baud_f0_l(config, clock_get_freq()); task_enable_irq(config->hw->irq); }