/*! \brief configure usart baud rate value \param[in] usart_periph: USARTx(x=0,1) \param[in] baudval: baud rate value \param[out] none \retval none */ void usart_baudrate_set(uint32_t usart_periph,uint32_t baudval) { uint32_t uclk=0,intdiv=0,fradiv=0,udiv=0; switch(usart_periph){ case USART0: uclk=rcu_clock_freq_get(CK_USART); break; case USART1: uclk=rcu_clock_freq_get(CK_APB1); break; default: break; } if(USART_CTL0(usart_periph)&USART_CTL0_OVSMOD){ /* when oversampling by 8,configure the value of USART_BAUD */ udiv=((2*uclk)+baudval/2)/baudval; intdiv=udiv&0xfff0; fradiv=udiv&0x7; USART_BAUD(usart_periph) |=((USART_BAUD_FRADIV|USART_BAUD_INTDIV)&( intdiv|fradiv)); }else{ /* when oversampling by 16,configure the value of USART_BAUD */ udiv=(uclk+baudval/2)/baudval; intdiv=udiv&0xfff0; fradiv=udiv&0xf; USART_BAUD(usart_periph) |=((USART_BAUD_FRADIV|USART_BAUD_INTDIV) &( intdiv|fradiv)); } }
/*! \brief configure I2C clock \param[in] i2c_periph: I2Cx(x=0,1) \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz) \param[in] dutycyc: duty cycle in fast mode only one parameter can be selected which is shown as below: \arg I2C_DTCY_2: T_low/T_high=2 \arg I2C_DTCY_16_9: T_low/T_high=16/9 \param[out] none \retval none */ void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) { uint32_t pclk1, clkc, freq, risetime; uint32_t temp; pclk1 = rcu_clock_freq_get(CK_APB1); /* I2C peripheral clock frequency */ freq = (uint32_t)(pclk1 / 1000000U); if (freq >= I2CCLK_MAX) { freq = I2CCLK_MAX; } temp = I2C_CTL1(i2c_periph); temp &= ~I2C_CTL1_I2CCLK; temp |= freq; I2C_CTL1(i2c_periph) = temp; if (100000U >= clkspeed) { /* the maximum SCL rise time is 1000ns in standard mode */ risetime = (uint32_t)((pclk1 / 1000000U) + 1U); if (risetime >= I2CCLK_MAX) { I2C_RT(i2c_periph) = I2CCLK_MAX; } else { I2C_RT(i2c_periph) = risetime; } clkc = (uint32_t)(pclk1 / (clkspeed * 2U)); if (clkc < 0x04U) { /* the CLKC in standard mode minmum value is 4 */ clkc = 0x04U; } I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc); } else if (400000U >= clkspeed) { /* the maximum SCL rise time is 300ns in fast mode */ I2C_RT(i2c_periph) = (uint32_t)(((freq * (uint32_t)300U) / (uint32_t)1000U) + (uint32_t)1U); if (I2C_DTCY_2 == dutycyc) { /* I2C duty cycle is 2 */ clkc = (uint32_t)(pclk1 / (clkspeed * 3U)); I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; } else { /* I2C duty cycle is 16/9 */ clkc = (uint32_t)(pclk1 / (clkspeed * 25U)); I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; } if (0U == (clkc & I2C_CKCFG_CLKC)) { /* the CLKC in fast mode minmum value is 1 */ clkc |= 0x0001U; } I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; I2C_CKCFG(i2c_periph) |= clkc; } else { } }
/** Get the frequency of SPI clock source * * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral * @param[out] spi_freq The SPI clock source freguency * @param[in] obj The SPI object */ static int dev_spi_clock_source_frequency_get(spi_t *obj) { int spi_freq = 0; struct spi_s *spiobj = SPI_S(obj); switch ((int)spiobj->spi) { case SPI0: /* clock source is APB2 */ spi_freq = rcu_clock_freq_get(CK_APB2); break; case SPI1: /* clock source is APB1 */ spi_freq = rcu_clock_freq_get(CK_APB1); break; case SPI2: /* clock source is APB1 */ spi_freq = rcu_clock_freq_get(CK_APB1); break; default: error("SPI clock source frequency get error"); break; } return spi_freq; }
/** Set the baudrate. * * @param freq The frequency value to be set. * * @returns * CAN_BT register value */ static unsigned int dev_can_baudrate_set(int freq) { uint32_t reval; uint16_t baud_psc; uint16_t baud_psc_max; uint32_t temp; uint32_t bt_reg_config; uint8_t flag; int bits; flag = 0; /* computes the value that the CAN_BT register needs to be configured */ /* (BAUDPSC[9:0] + 1) * ((BS1[3:0] + 1) + (BS2[2:0] + 1) + SJW(always 1)) */ bt_reg_config = (rcu_clock_freq_get(CK_APB1) / freq); /* BAUDPSC[9:0] minimum value */ baud_psc = bt_reg_config / DEV_CAN_BT_SEG_MAX; /* BAUDPSC[9:0] maximum value */ baud_psc_max = bt_reg_config / DEV_CAN_BT_SEG_MIN; while ((!flag) && (baud_psc < baud_psc_max)) { baud_psc++; for (bits = 22; bits > 0; bits--) { temp = (bits + 3) * (baud_psc + 1); if (temp == bt_reg_config) { flag = 1; break; } } } if (flag) { reval = ((sampling_points[bits][1] << 20) & DEV_CAN_BS2_MASK) | ((sampling_points[bits][0] << 16) & DEV_CAN_BS1_MASK) | ((1 << 24) & DEV_CAN_SJW_MASK) | ((baud_psc << 0) & DEV_CAN_BAUDPSC_MASK); } else { /* CAN_BT register reset value */ reval = 0x01230000; } return reval; }
static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration) { struct rt_spi_bus * spi_bus = (struct rt_spi_bus *)device->bus; struct gd32f4_spi *f4_spi = (struct gd32f4_spi *)spi_bus->parent.user_data; spi_parameter_struct spi_init_struct; uint32_t spi_periph = f4_spi->spi_periph; RT_ASSERT(device != RT_NULL); RT_ASSERT(configuration != RT_NULL); /* data_width */ if(configuration->data_width <= 8) { spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; } else if(configuration->data_width <= 16) { spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT; } else { return RT_EIO; } /* baudrate */ { rcu_clock_freq_enum spi_src; uint32_t spi_apb_clock; uint32_t max_hz; max_hz = configuration->max_hz; DEBUG_PRINTF("sys freq: %d\n", HAL_RCC_GetSysClockFreq()); DEBUG_PRINTF("pclk2 freq: %d\n", HAL_RCC_GetPCLK2Freq()); DEBUG_PRINTF("max freq: %d\n", max_hz); if (spi_periph == SPI1 || spi_periph == SPI2) { spi_src = CK_APB1; } else { spi_src = CK_APB2; } spi_apb_clock = rcu_clock_freq_get(spi_src); if(max_hz >= spi_apb_clock/2) { spi_init_struct.prescale = SPI_PSC_2; } else if (max_hz >= spi_apb_clock/4) { spi_init_struct.prescale = SPI_PSC_4; } else if (max_hz >= spi_apb_clock/8) { spi_init_struct.prescale = SPI_PSC_8; } else if (max_hz >= spi_apb_clock/16) { spi_init_struct.prescale = SPI_PSC_16; } else if (max_hz >= spi_apb_clock/32) { spi_init_struct.prescale = SPI_PSC_32; } else if (max_hz >= spi_apb_clock/64) { spi_init_struct.prescale = SPI_PSC_64; } else if (max_hz >= spi_apb_clock/128) { spi_init_struct.prescale = SPI_PSC_128; } else { /* min prescaler 256 */ spi_init_struct.prescale = SPI_PSC_256; } } /* baudrate */ switch(configuration->mode) { case RT_SPI_MODE_0: spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; break; case RT_SPI_MODE_1: spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE; break; case RT_SPI_MODE_2: spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE; break; case RT_SPI_MODE_3: spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; break; } /* MSB or LSB */ if(configuration->mode & RT_SPI_MSB) { spi_init_struct.endian = SPI_ENDIAN_MSB; } else { spi_init_struct.endian = SPI_ENDIAN_LSB; } spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; spi_init_struct.device_mode = SPI_MASTER; spi_init_struct.nss = SPI_NSS_SOFT; spi_crc_off(spi_periph); /* init SPI */ spi_init(spi_periph, &spi_init_struct); /* Enable SPI_MASTER */ spi_enable(spi_periph); return RT_EOK; };