/** * Preset PWM operation clock. * * @param none * @return none * @notes changed when initial or HOOK_FREQ_CHANGE command */ void pwm_freq_changed(void) { uint32_t prescaler_divider = 0; if (pwm_init_ch == PWM_CH_FAN) { /* * Using PWM Frequency and Resolution we calculate * prescaler for input clock */ /* (Benson_TBD_9) pwm_clock/freq/resolution not confirm */ #ifdef CONFIG_PWM_INPUT_LFCLK prescaler_divider = (uint32_t)(32768 / pwm_channels[pwm_init_ch].freq); #else prescaler_divider = (uint32_t)(clock_get_apb2_freq() / pwm_channels[pwm_init_ch].freq); #endif } else { prescaler_divider = (uint32_t)(clock_get_apb2_freq() / pwm_channels[pwm_init_ch].freq); } /* Set clock prescalre divider to ADC module*/ if (prescaler_divider >= 1) prescaler_divider = prescaler_divider - 1; if (prescaler_divider > 0xFFFF) prescaler_divider = 0xFFFF; /* Configure computed prescaler and resolution */ NPCX_PRSC(pwm_channels[pwm_init_ch].channel) = (uint16_t)prescaler_divider; }
/* Hooks */ static void i2c_freq_changed(void) { int freq, i; for (i = 0; i < i2c_ports_used; i++) { int bus_freq = i2c_ports[i].kbps; int ctrl = i2c_port_to_controller(i2c_ports[i].port); int scl_time; /* SMB0/1 use core clock & SMB2/3 use apb2 clock */ if (ctrl < 2) freq = clock_get_freq(); else freq = clock_get_apb2_freq(); /* use Fast Mode */ SET_BIT(NPCX_SMBCTL3(ctrl) , NPCX_SMBCTL3_400K); /* * Set SCLLT/SCLHT: * tSCLL = 2 * SCLLT7-0 * tCLK * tSCLH = 2 * SCLHT7-0 * tCLK * (tSCLL+tSCLH) = 4 * SCLH(L)T * tCLK if tSCLL == tSCLH * SCLH(L)T = T(SCL)/4/T(CLK) = FREQ(CLK)/4/FREQ(SCL) */ scl_time = (freq/1000) / (bus_freq * 4); /* bus_freq is KHz */ /* set SCL High/Low time */ NPCX_SMBSCLLT(ctrl) = scl_time; NPCX_SMBSCLHT(ctrl) = scl_time; } }
static void update_prescaler(void) { /* * prescaler to time tick * Ttick_unit = (PRE_8+1) * Tapb2_clk * PRE_8 = (Ttick_unit/Tapb2_clk) -1 */ NPCX_ITPRE(ITIM32) = (clock_get_apb2_freq() / SECOND) - 1; /* Set event tick unit = 1/32768 sec */ NPCX_ITPRE(ITIM_EVENT_NO) = 0; }
/** * Preset SPI operation clock. * * @param none * @return none * @notes changed when initial or HOOK_FREQ_CHANGE command */ void spi_freq_changed(void) { uint8_t prescaler_divider = 0; /* Set clock prescaler divider to SPI module*/ prescaler_divider = (uint8_t)((uint32_t)clock_get_apb2_freq() / 2 / SPI_CLK); if (prescaler_divider >= 1) prescaler_divider = prescaler_divider - 1; if (prescaler_divider > 0x7F) prescaler_divider = 0x7F; /* Set core clock division factor in order to obtain the SPI clock */ NPCX_SPI_CTL1 = (NPCX_SPI_CTL1&(~(((1<<7)-1)<<NPCX_SPI_CTL1_SCDV))) |(prescaler_divider<<NPCX_SPI_CTL1_SCDV); }
/** * Set PWM operation clock. * * @param ch operation channel * @param freq desired PWM frequency * @param res resolution for duty cycle * @notes changed when initialization */ void pwm_set_freq(enum pwm_channel ch, uint32_t freq, uint32_t res) { int mdl = pwm_channels[ch].channel; uint32_t prescaler_divider = 0; uint32_t clock; /* Disable PWM for module configuration */ pwm_enable(ch, 0); /* Get PWM clock frequency */ if (pwm_channels[ch].flags & PWM_CONFIG_DSLEEP_CLK) clock = INT_32K_CLOCK; else clock = clock_get_apb2_freq(); /* * Using PWM Frequency and Resolution we calculate * prescaler for input clock */ prescaler_divider = ((clock / freq)/res); /* Set clock prescaler divider to PWM module*/ if (prescaler_divider >= 1) prescaler_divider = prescaler_divider - 1; if (prescaler_divider > 0xFFFF) prescaler_divider = 0xFFFF; /* Configure computed prescaler and resolution */ NPCX_PRSC(mdl) = (uint16_t)prescaler_divider - 1; /* Set PWM cycle time */ NPCX_CTR(mdl) = res - 1; /* Set the duty cycle to 0% since DCR > CTR */ NPCX_DCR(mdl) = res; }