void serial_init(SerialInstance* instance, bool isGlobal) { if (instance->_Mapping != 0 || Instances[instance->_Mapping] != NULL) throw(AlreadyInitException, "Serial Instance already initialised"); if (MapIndex > SUPPORTED_INSTANCES) throw(InitialisationException, "Maximum number of serial instances established"); Instances[MapIndex] = instance; instance->_Mapping = MapIndex; if (isGlobal || GlobalInstance == NULL) serial_set_global(instance); // Configure GPIO gpio_init_af(instance->GPIOX, GPIOMode_AltFunction, GPIOOutputType_PushPull, GPIOSpeed_80MHz_100MHz, GPIOResistor_PullUp, instance->TxPin, GPIOAFMapping_USART1_3); gpio_init_af(instance->GPIOX, GPIOMode_AltFunction, GPIOOutputType_PushPull, GPIOSpeed_80MHz_100MHz, GPIOResistor_PullUp, instance->RxPin, GPIOAFMapping_USART1_3); USARTInstance Usart = {0}; Usart.PeripheralMapping = MapIndex; Usart.Control1.UsartEnable = true; Usart.Control1.TransmitEnable = true; Usart.Control1.ReceiveEnable = true; Usart.Control1.ReceiveNotEmptyInterruptEnable = true; Usart.Control1.WordLength = USARTWordLength_8bit; Usart.Control2.StopBits = USARTStopBits_1; Usart.BaudRate = instance->Baudrate; Usart.USARTX = instance->USARTX; Usart.InterruptPriority = instance->Priority; Usart.OnReceiveNotEmpty = &serial_readbyte_isr; instance->_Usart = Usart; usart_init(&instance->_Usart); MapIndex++; }
static void _pin_config(gpio_t scl, gpio_t sda) { /* toggle pins to reset analog filter -> see datasheet */ /* set as output */ gpio_init(scl, GPIO_DIR_OUT, GPIO_NOPULL); gpio_init(sda, GPIO_DIR_OUT, GPIO_NOPULL); /* run through toggling sequence */ gpio_set(scl); gpio_set(sda); gpio_clear(sda); gpio_clear(scl); gpio_set(scl); gpio_set(sda); /* configure the pins alternate function */ gpio_init_af(scl, GPIO_AF_OUT_OD); gpio_init_af(sda, GPIO_AF_OUT_OD); }
uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res) { uint32_t bus_clk = periph_apb_clk(pwm_config[pwm].bus); /* verify parameters */ assert((pwm < PWM_NUMOF) && ((freq * res) < bus_clk)); /* power on the used timer */ pwm_poweron(pwm); /* reset configuration and CC channels */ dev(pwm)->CR1 = 0; dev(pwm)->CR2 = 0; for (int i = 0; i < TIMER_CHAN; i++) { dev(pwm)->CCR[i] = 0; } /* configure the used pins */ unsigned i = 0; while ((i < TIMER_CHAN) && (pwm_config[pwm].chan[i].pin != GPIO_UNDEF)) { gpio_init(pwm_config[pwm].chan[i].pin, GPIO_OUT); gpio_init_af(pwm_config[pwm].chan[i].pin, pwm_config[pwm].af); i++; } /* configure the PWM frequency and resolution by setting the auto-reload * and prescaler registers */ dev(pwm)->PSC = (bus_clk / (res * freq)) - 1; dev(pwm)->ARR = res - 1; /* set PWM mode */ switch (mode) { case PWM_LEFT: dev(pwm)->CCMR1 = CCMR_LEFT; dev(pwm)->CCMR2 = CCMR_LEFT; break; case PWM_RIGHT: dev(pwm)->CCMR1 = CCMR_RIGHT; dev(pwm)->CCMR2 = CCMR_RIGHT; break; case PWM_CENTER: dev(pwm)->CCMR1 = 0; dev(pwm)->CCMR2 = 0; dev(pwm)->CR1 |= (TIM_CR1_CMS_0 | TIM_CR1_CMS_1); break; } /* enable PWM outputs and start PWM generation */ #ifdef TIM_BDTR_MOE dev(pwm)->BDTR = TIM_BDTR_MOE; #endif dev(pwm)->CCER = (TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E); dev(pwm)->CR1 |= TIM_CR1_CEN; /* return the actual used PWM frequency */ return (bus_clk / (res * (dev(pwm)->PSC + 1))); }
int i2c_init_master(i2c_t dev, i2c_speed_t speed) { int ccr; if ((unsigned int)dev >= I2C_NUMOF) { return -1; } /* read speed configuration */ switch (speed) { case I2C_SPEED_NORMAL: ccr = I2C_APBCLK / 200000; break; case I2C_SPEED_FAST: ccr = I2C_APBCLK / 800000; break; default: return -2; } I2C_TypeDef *i2c = i2c_config[dev].dev; /* enable I2C clock */ i2c_poweron(dev); /* set IRQn priority */ NVIC_SetPriority(i2c_config[dev].er_irqn, I2C_IRQ_PRIO); /* enable IRQn */ NVIC_EnableIRQ(i2c_config[dev].er_irqn); /* configure pins */ gpio_init(i2c_config[dev].scl, GPIO_DIR_OUT, GPIO_PULLUP); gpio_init_af(i2c_config[dev].scl, i2c_config[dev].af); gpio_init(i2c_config[dev].sda, GPIO_DIR_OUT, GPIO_PULLUP); gpio_init_af(i2c_config[dev].sda, i2c_config[dev].af); /* configure device */ _i2c_init(i2c, ccr); return 0; }
static inline void uart_init_pins(uart_t uart, uart_rx_cb_t rx_cb) { /* configure TX pin */ gpio_init(uart_config[uart].tx_pin, GPIO_OUT); /* set TX pin high to avoid garbage during further initialization */ gpio_set(uart_config[uart].tx_pin); #ifdef CPU_FAM_STM32F1 gpio_init_af(uart_config[uart].tx_pin, GPIO_AF_OUT_PP); #else gpio_init_af(uart_config[uart].tx_pin, uart_config[uart].tx_af); #endif /* configure RX pin */ if (rx_cb) { gpio_init(uart_config[uart].rx_pin, GPIO_IN); #ifndef CPU_FAM_STM32F1 gpio_init_af(uart_config[uart].rx_pin, uart_config[uart].rx_af); #endif } #ifdef MODULE_STM32_PERIPH_UART_HW_FC if (uart_config[uart].cts_pin != GPIO_UNDEF) { gpio_init(uart_config[uart].cts_pin, GPIO_IN); gpio_init(uart_config[uart].rts_pin, GPIO_OUT); #ifdef CPU_FAM_STM32F1 gpio_init_af(uart_config[uart].rts_pin, GPIO_AF_OUT_PP); #else gpio_init_af(uart_config[uart].cts_pin, uart_config[uart].cts_af); gpio_init_af(uart_config[uart].rts_pin, uart_config[uart].rts_af); #endif } #endif }
int spi_conf_pins(spi_t dev) { gpio_t mosi, miso, clk; switch(dev) { #ifdef SPI_0_EN case SPI_0: clk = SPI_0_CLK_PIN; mosi = SPI_0_MOSI_PIN; miso = SPI_0_MISO_PIN; break; #endif default: return -1; } /* configure pins for alternate function input (MISO) or output (MOSI, CLK) */ gpio_init_af(clk, GPIO_AF_OUT_PP); gpio_init_af(mosi, GPIO_AF_OUT_PP); gpio_init(miso, GPIO_DIR_IN, GPIO_NOPULL); return 0; }
int uart_init_blocking(uart_t uart, uint32_t baudrate) { USART_TypeDef *dev; uint32_t bus_freq; gpio_t rx_pin, tx_pin; float divider; uint16_t mantissa; uint8_t fraction; /* enable UART and port clocks and select devices */ switch (uart) { #if UART_0_EN case UART_0: dev = UART_0_DEV; rx_pin = UART_0_RX_PIN; tx_pin = UART_0_TX_PIN; bus_freq = UART_0_BUS_FREQ; /* enable clocks */ UART_0_CLKEN(); break; #endif #if UART_1_EN case UART_1: dev = UART_1_DEV; tx_pin = UART_1_TX_PIN; rx_pin = UART_1_RX_PIN; bus_freq = UART_1_BUS_FREQ; /* enable clocks */ UART_1_CLKEN(); break; #endif default: return -2; } /* configure RX and TX pin */ gpio_init_af(tx_pin, GPIO_AF_OUT_PP); gpio_init(rx_pin, GPIO_DIR_IN, GPIO_NOPULL); /* configure UART to mode 8N1 with given baudrate */ divider = ((float)bus_freq) / (16 * baudrate); mantissa = (uint16_t)floorf(divider); fraction = (uint8_t)floorf((divider - mantissa) * 16); dev->BRR = 0; dev->BRR |= ((mantissa & 0x0fff) << 4) | (0x0f & fraction); /* enable receive and transmit mode */ dev->CR1 |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; return 0; }
void i2c_init(i2c_t dev) { assert(dev < I2C_NUMOF); DEBUG("[i2c] init: initializing device\n"); mutex_init(&locks[dev]); I2C_TypeDef *i2c = i2c_config[dev].dev; periph_clk_en(i2c_config[dev].bus, i2c_config[dev].rcc_mask); NVIC_SetPriority(i2c_config[dev].irqn, I2C_IRQ_PRIO); NVIC_EnableIRQ(i2c_config[dev].irqn); #if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3) /* Set I2CSW bits to enable I2C clock source */ RCC->CFGR3 |= i2c_config[dev].rcc_sw_mask; #endif DEBUG("[i2c] init: configuring pins\n"); /* configure pins */ gpio_init(i2c_config[dev].scl_pin, GPIO_OD_PU); gpio_init_af(i2c_config[dev].scl_pin, i2c_config[dev].scl_af); gpio_init(i2c_config[dev].sda_pin, GPIO_OD_PU); gpio_init_af(i2c_config[dev].sda_pin, i2c_config[dev].sda_af); DEBUG("[i2c] init: configuring device\n"); /* set the timing register value from predefined values */ i2c_timing_param_t tp = timing_params[i2c_config[dev].speed]; uint32_t timing = (( (uint32_t)tp.presc << I2C_TIMINGR_PRESC_Pos) | ( (uint32_t)tp.scldel << I2C_TIMINGR_SCLDEL_Pos) | ( (uint32_t)tp.sdadel << I2C_TIMINGR_SDADEL_Pos) | ( (uint16_t)tp.sclh << I2C_TIMINGR_SCLH_Pos) | tp.scll); _i2c_init(i2c, timing); }
static int init_base(uart_t uart, uint32_t baudrate) { USART_TypeDef *dev = 0; gpio_t tx_pin = 0; gpio_t rx_pin = 0; gpio_af_t af = 0; float clk = 0; uint16_t mantissa; uint8_t fraction; switch (uart) { #if UART_0_EN case UART_0: dev = UART_0_DEV; clk = UART_0_CLK; tx_pin = UART_0_TX_PIN; rx_pin = UART_0_RX_PIN; af = UART_0_AF; UART_0_CLKEN(); break; #endif #if UART_1_EN case UART_1: dev = UART_1_DEV; clk = UART_1_CLK; tx_pin = UART_1_TX_PIN; rx_pin = UART_1_RX_PIN; af = UART_1_AF; UART_1_CLKEN(); break; #endif #if UART_2_EN case UART_2: dev = UART_2_DEV; clk = UART_2_CLK; tx_pin = UART_2_TX_PIN; rx_pin = UART_2_RX_PIN; af = UART_2_AF; UART_2_CLKEN(); break; #endif default: return -1; } /* uart_configure RX and TX pins, set pin to use alternative function mode */ gpio_init(tx_pin, GPIO_DIR_OUT, GPIO_NOPULL); gpio_init_af(tx_pin, af); gpio_init(rx_pin, GPIO_DIR_IN, GPIO_NOPULL); gpio_init_af(rx_pin, af); /* uart_configure UART to mode 8N1 with given baudrate */ clk /= baudrate; mantissa = (uint16_t)(clk / 16); fraction = (uint8_t)(clk - (mantissa * 16)); dev->BRR = ((mantissa & 0x0fff) << 4) | (0x0f & fraction); /* enable receive and transmit mode */ dev->CR3 = 0; dev->CR2 = 0; dev->CR1 |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; return 0; }
static int init_base(uart_t uart, uint32_t baudrate) { cc2538_uart_t *u = NULL; switch (uart) { #if UART_0_EN case UART_0: u = UART_0_DEV; gpio_init_af(UART_0_RX_PIN, UART0_RXD, GPIO_IN); gpio_init_af(UART_0_TX_PIN, UART0_TXD, GPIO_OUT); break; #endif #if UART_1_EN case UART_1: u = UART_1_DEV; gpio_init_af(UART_1_RX_PIN, UART1_RXD, GPIO_IN); gpio_init_af(UART_1_TX_PIN, UART1_TXD, GPIO_OUT); break; #endif default: (void)u; return UART_NODEV; } #if UART_0_EN || UART_1_EN /* Enable clock for the UART while Running, in Sleep and Deep Sleep */ unsigned int uart_num = ( (uintptr_t)u - (uintptr_t)UART0 ) / 0x1000; SYS_CTRL_RCGCUART |= (1 << uart_num); SYS_CTRL_SCGCUART |= (1 << uart_num); SYS_CTRL_DCGCUART |= (1 << uart_num); /* Make sure the UART is disabled before trying to configure it */ u->cc2538_uart_ctl.CTL = 0; /* Run on SYS_DIV */ u->CC = 0; /* On the CC2538, hardware flow control is supported only on UART1 */ if (u == UART1) { #ifdef UART_1_RTS_PIN gpio_init_af(UART_1_RTS_PIN, UART1_RTS, GPIO_OUT); u->cc2538_uart_ctl.CTLbits.RTSEN = 1; #endif #ifdef UART_1_CTS_PIN gpio_init_af(UART_1_CTS_PIN, UART1_CTS, GPIO_IN); u->cc2538_uart_ctl.CTLbits.CTSEN = 1; #endif } /* Enable clock for the UART while Running, in Sleep and Deep Sleep */ uart_num = ( (uintptr_t)u - (uintptr_t)UART0 ) / 0x1000; SYS_CTRL_RCGCUART |= (1 << uart_num); SYS_CTRL_SCGCUART |= (1 << uart_num); SYS_CTRL_DCGCUART |= (1 << uart_num); /* * UART Interrupt Masks: * Acknowledge RX and RX Timeout * Acknowledge Framing, Overrun and Break Errors */ u->cc2538_uart_im.IM = 0; u->cc2538_uart_im.IMbits.RXIM = 1; /**< UART receive interrupt mask */ u->cc2538_uart_im.IMbits.RTIM = 1; /**< UART receive time-out interrupt mask */ u->cc2538_uart_im.IMbits.OEIM = 1; /**< UART overrun error interrupt mask */ u->cc2538_uart_im.IMbits.BEIM = 1; /**< UART break error interrupt mask */ u->cc2538_uart_im.IMbits.FEIM = 1; /**< UART framing error interrupt mask */ /* Set FIFO interrupt levels: */ u->cc2538_uart_ifls.IFLSbits.RXIFLSEL = FIFO_LEVEL_4_8TH; /**< MCU default */ u->cc2538_uart_ifls.IFLSbits.TXIFLSEL = FIFO_LEVEL_4_8TH; /**< MCU default */ u->cc2538_uart_ctl.CTLbits.RXE = 1; u->cc2538_uart_ctl.CTLbits.TXE = 1; u->cc2538_uart_ctl.CTLbits.HSE = UART_CTL_HSE_VALUE; /* Set the divisor for the baud rate generator */ uint32_t divisor = sys_clock_freq(); divisor <<= UART_CTL_HSE_VALUE + 2; divisor += baudrate / 2; /**< Avoid a rounding error */ divisor /= baudrate; u->IBRD = divisor >> DIVFRAC_NUM_BITS; u->FBRD = divisor & DIVFRAC_MASK; /* Configure line control for 8-bit, no parity, 1 stop bit and enable */ u->cc2538_uart_lcrh.LCRH = (WLEN_8_BITS << 5) | FEN; /* UART Enable */ u->cc2538_uart_ctl.CTLbits.UARTEN = 1; return UART_OK; #endif /* UART_0_EN || UART_1_EN */ }
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) { USART_TypeDef *dev; DMA_Stream_TypeDef *stream; float divider; uint16_t mantissa; uint8_t fraction; /* check if given UART device does exist */ if ((unsigned int)uart >= UART_NUMOF) { return -1; } /* get UART base address */ dev = _dev(uart); /* remember callback addresses and argument */ uart_ctx[uart].rx_cb = rx_cb; uart_ctx[uart].arg = arg; /* init TX lock and DMA synchronization mutex */ mutex_init(&_tx_lock[uart]); mutex_init(&_tx_dma_sync[uart]); mutex_lock(&_tx_dma_sync[uart]); /* configure pins */ gpio_init(uart_config[uart].rx_pin, GPIO_IN); gpio_init(uart_config[uart].tx_pin, GPIO_OUT); gpio_init_af(uart_config[uart].rx_pin, uart_config[uart].af); gpio_init_af(uart_config[uart].tx_pin, uart_config[uart].af); /* enable UART clock */ uart_poweron(uart); /* calculate and set baudrate */ if (uart_config[uart].bus == APB1) { divider = CLOCK_APB1 / (16 * baudrate); } else { divider = CLOCK_APB2 / (16 * baudrate); } mantissa = (uint16_t)divider; fraction = (uint8_t)((divider - mantissa) * 16); dev->BRR = ((mantissa & 0x0fff) << 4) | (0x0f & fraction); /* configure UART to 8N1 and enable receive and transmit mode */ dev->CR3 = USART_CR3_DMAT; dev->CR2 = 0; dev->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; /* configure the DMA stream for transmission */ dma_poweron(uart_config[uart].dma_stream); stream = dma_stream(uart_config[uart].dma_stream); stream->CR = ((uart_config[uart].dma_chan << 25) | DMA_SxCR_PL_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_TCIE); stream->PAR = (uint32_t)&(dev->DR); stream->FCR = 0; /* enable global and receive interrupts */ NVIC_EnableIRQ(uart_config[uart].irqn); dma_isr_enable(uart_config[uart].dma_stream); dev->CR1 |= USART_CR1_RXNEIE; return 0; }
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) { uint16_t mantissa; uint8_t fraction; uint32_t clk; assert(uart < UART_NUMOF); /* save ISR context */ isr_ctx[uart].rx_cb = rx_cb; isr_ctx[uart].arg = arg; /* configure TX pin */ gpio_init(uart_config[uart].tx_pin, GPIO_OUT); /* set TX pin high to avoid garbage during further initialization */ gpio_set(uart_config[uart].tx_pin); #ifdef CPU_FAM_STM32F1 gpio_init_af(uart_config[uart].tx_pin, GPIO_AF_OUT_PP); #else gpio_init_af(uart_config[uart].tx_pin, uart_config[uart].tx_af); #endif /* configure RX pin */ if (rx_cb) { gpio_init(uart_config[uart].rx_pin, GPIO_IN); #ifndef CPU_FAM_STM32F1 gpio_init_af(uart_config[uart].rx_pin, uart_config[uart].rx_af); #endif } #ifdef UART_USE_HW_FC if (uart_config[uart].cts_pin != GPIO_UNDEF) { gpio_init(uart_config[uart].cts_pin, GPIO_IN); gpio_init(uart_config[uart].rts_pin, GPIO_OUT); #ifdef CPU_FAM_STM32F1 gpio_init_af(uart_config[uart].rts_pin, GPIO_AF_OUT_PP); #else gpio_init_af(uart_config[uart].cts_pin, uart_config[uart].cts_af); gpio_init_af(uart_config[uart].rts_pin, uart_config[uart].rts_af); #endif } #endif /* enable the clock */ periph_clk_en(uart_config[uart].bus, uart_config[uart].rcc_mask); /* reset UART configuration -> defaults to 8N1 mode */ dev(uart)->CR1 = 0; dev(uart)->CR2 = 0; dev(uart)->CR3 = 0; /* calculate and apply baudrate */ clk = periph_apb_clk(uart_config[uart].bus) / baudrate; mantissa = (uint16_t)(clk / 16); fraction = (uint8_t)(clk - (mantissa * 16)); dev(uart)->BRR = ((mantissa & 0x0fff) << 4) | (fraction & 0x0f); /* enable RX interrupt if applicable */ if (rx_cb) { NVIC_EnableIRQ(uart_config[uart].irqn); dev(uart)->CR1 = (USART_CR1_UE | USART_CR1_TE | RXENABLE); } else { dev(uart)->CR1 = (USART_CR1_UE | USART_CR1_TE); } #ifdef UART_USE_HW_FC if (uart_config[uart].cts_pin != GPIO_UNDEF) { /* configure hardware flow control */ dev(uart)->CR3 = (USART_CR3_RTSE | USART_CR3_CTSE); } #endif return UART_OK; }
void i2c_init(i2c_t dev) { assert(dev < I2C_NUMOF); mutex_init(&locks[dev]); I2C_TypeDef *i2c = i2c_config[dev].dev; assert(i2c != NULL); uint32_t ccr; /* read speed configuration */ switch (i2c_config[dev].speed) { case I2C_SPEED_LOW: /* 10Kbit/s */ ccr = i2c_config[dev].clk / 20000; break; case I2C_SPEED_NORMAL: /* 100Kbit/s */ ccr = i2c_config[dev].clk / 200000; break; case I2C_SPEED_FAST: ccr = i2c_config[dev].clk / 800000; break; default: return; } periph_clk_en(i2c_config[dev].bus, i2c_config[dev].rcc_mask); NVIC_SetPriority(i2c_config[dev].irqn, I2C_IRQ_PRIO); NVIC_EnableIRQ(i2c_config[dev].irqn); /* configure pins */ gpio_init(i2c_config[dev].scl_pin, GPIO_OD_PU); gpio_init(i2c_config[dev].sda_pin, GPIO_OD_PU); #ifdef CPU_FAM_STM32F1 /* This is needed in case the remapped pins are used */ if (i2c_config[dev].scl_pin == GPIO_PIN(PORT_B, 8) || i2c_config[dev].sda_pin == GPIO_PIN(PORT_B, 9)) { /* The remapping periph clock must first be enabled */ RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; /* Then the remap can occur */ AFIO->MAPR |= AFIO_MAPR_I2C1_REMAP; } gpio_init_af(i2c_config[dev].scl_pin, GPIO_AF_OUT_OD); gpio_init_af(i2c_config[dev].sda_pin, GPIO_AF_OUT_OD); #else gpio_init_af(i2c_config[dev].scl_pin, i2c_config[dev].scl_af); gpio_init_af(i2c_config[dev].sda_pin, i2c_config[dev].sda_af); #endif /* configure device */ _i2c_init(i2c, i2c_config[dev].clk, ccr); #if defined(CPU_FAM_STM32F4) /* make sure the analog filters don't hang -> see errata sheet 2.14.7 */ if (i2c->SR2 & I2C_SR2_BUSY) { /* disable peripheral */ i2c->CR1 &= ~I2C_CR1_PE; /* toggle both pins to reset analog filter */ gpio_init(i2c_config[dev].scl_pin, GPIO_OD); gpio_init(i2c_config[dev].sda_pin, GPIO_OD); gpio_set(i2c_config[dev].sda_pin); gpio_set(i2c_config[dev].scl_pin); gpio_clear(i2c_config[dev].sda_pin); gpio_clear(i2c_config[dev].scl_pin); gpio_set(i2c_config[dev].sda_pin); gpio_set(i2c_config[dev].scl_pin); /* reset pins for alternate function */ gpio_init(i2c_config[dev].scl_pin, GPIO_OD_PU); gpio_init(i2c_config[dev].sda_pin, GPIO_OD_PU); gpio_init_af(i2c_config[dev].scl_pin, i2c_config[dev].scl_af); gpio_init_af(i2c_config[dev].sda_pin, i2c_config[dev].sda_af); /* make peripheral soft reset */ i2c->CR1 |= I2C_CR1_SWRST; i2c->CR1 &= ~I2C_CR1_SWRST; /* enable device */ _i2c_init(i2c, i2c_config[dev].clk, ccr); } #endif }