void cc2538_i2c_init_master(uint32_t speed_hz) { SYS_CTRL_RCGCI2C |= 1; /**< Enable the I2C0 clock. */ SYS_CTRL_SCGCI2C |= 1; /**< Enable the I2C0 clock. */ SYS_CTRL_DCGCI2C |= 1; /**< Enable the I2C0 clock. */ /* Reset I2C peripheral */ SYS_CTRL_SRI2C |= 1; #ifdef MODULE_XTIMER xtimer_usleep(50); #else thread_yield(); #endif SYS_CTRL_SRI2C &= ~1; /* Clear all pin override flags except PUE (Pull-Up Enable) */ IOC_PXX_OVER[I2C_0_SCL_PIN] &= IOC_OVERRIDE_PUE; IOC_PXX_OVER[I2C_0_SDA_PIN] &= IOC_OVERRIDE_PUE; IOC_PXX_SEL[I2C_0_SCL_PIN] = I2C_SCL_OUT; IOC_PXX_SEL[I2C_0_SDA_PIN] = I2C_SDA_OUT; IOC_I2CMSSCL = I2C_0_SCL_PIN; IOC_I2CMSSDA = I2C_0_SDA_PIN; gpio_hardware_control(I2C_0_SCL_PIN); gpio_hardware_control(I2C_0_SDA_PIN); /* Initialize the I2C master by setting the Master Function Enable bit */ I2CM_CR |= MFE; /* Set the SCL clock speed */ uint32_t ps = sys_clock_freq(); uint32_t denom = 2 * (SCL_LP + SCL_HP) * speed_hz; ps += denom / 2; ps /= denom; I2CM_TPR = ps - 1; /* Enable I2C master interrupts */ NVIC_SetPriority(I2C_IRQn, I2C_IRQ_PRIO); NVIC_EnableIRQ(I2C_IRQn); i2cm_ctrl_write(STOP); /* Enable I2C master interrupts */ I2CM_IMR = 1; }
/** * @brief Setup the given timer * */ int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg) { cc2538_gptimer_t *gptimer = timer_config[dev].dev; unsigned int gptimer_num; uint32_t chan_mode; DEBUG("%s(%u, %lu, %p, %p)\n", __FUNCTION__, dev, freq, cb, arg); if (dev >= TIMER_NUMOF) { return -1; } gptimer_num = GPTIMER_GET_NUM(gptimer); /* Save the callback function: */ assert(gptimer_num < GPTIMER_NUMOF); config[gptimer_num].cb = cb; config[gptimer_num].arg = arg; /* Enable the clock for this timer: */ SYS_CTRL_RCGCGPT |= (1 << gptimer_num); /* Disable this timer before configuring it: */ gptimer->cc2538_gptimer_ctl.CTL = 0; if (timer_config[dev].cfg == GPTMCFG_32_BIT_TIMER) { /* Count up in periodic mode */ chan_mode = TnCMIE | TnCDIR | GPTIMER_PERIODIC_MODE; if (timer_config[dev].channels > 1) { DEBUG("Invalid timer_config. Multiple channels are available only in 16-bit mode."); return -1; } if (freq != sys_clock_freq()) { DEBUG("In 32-bit mode, the GPTimer frequency must equal the system clock frequency (%u).", sys_clock_freq()); return -1; } } else { /* Count down in periodic mode */ chan_mode = TnCMIE | GPTIMER_PERIODIC_MODE; } gptimer->CFG = timer_config[dev].cfg; gptimer->cc2538_gptimer_tamr.TAMR = chan_mode; switch (timer_config[dev].channels) { case 1: /* Enable the timer: */ gptimer->cc2538_gptimer_ctl.CTL = TAEN; break; case 2: gptimer->cc2538_gptimer_tbmr.TBMR = chan_mode; gptimer->TAILR = LOAD_VALUE; gptimer->TBILR = LOAD_VALUE; uint32_t prescaler = sys_clock_freq(); prescaler += freq / 2; prescaler /= freq; if (prescaler > 0) prescaler--; if (prescaler > 255) prescaler = 255; gptimer->TAPR = prescaler; gptimer->TBPR = prescaler; /* Enable the timer: */ gptimer->cc2538_gptimer_ctl.CTL = TBEN | TAEN; break; } /* Enable interrupts for given timer: */ _irq_enable(dev); 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; /* * Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register */ IOC_UARTRXD_UART0 = UART_0_RX_PIN; /* * Pad Control for the TX pin: * - Set function to UARTn TX * - Output Enable */ IOC_PXX_SEL[UART_0_TX_PIN] = UART0_TXD; IOC_PXX_OVER[UART_0_TX_PIN] = IOC_OVERRIDE_OE; /* Set RX and TX pins to peripheral mode */ gpio_hardware_control(UART_0_TX_PIN); gpio_hardware_control(UART_0_RX_PIN); break; #endif #if UART_1_EN case UART_1: u = UART_1_DEV; /* * Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register */ IOC_UARTRXD_UART1 = UART_1_RX_PIN; /* * Pad Control for the TX pin: * - Set function to UARTn TX * - Output Enable */ IOC_PXX_SEL[UART_1_TX_PIN] = UART1_TXD; IOC_PXX_OVER[UART_1_TX_PIN] = IOC_OVERRIDE_OE; /* Set RX and TX pins to peripheral mode */ gpio_hardware_control(UART_1_TX_PIN); gpio_hardware_control(UART_1_RX_PIN); 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 IOC_PXX_SEL[UART_1_RTS_PIN] = UART1_RTS; gpio_hardware_control(UART_1_RTS_PIN); IOC_PXX_OVER[UART_1_RTS_PIN] = IOC_OVERRIDE_OE; u->cc2538_uart_ctl.CTLbits.RTSEN = 1; #endif #ifdef UART_1_CTS_PIN IOC_UARTCTS_UART1 = UART_1_CTS_PIN; gpio_hardware_control(UART_1_CTS_PIN); IOC_PXX_OVER[UART_1_CTS_PIN] = IOC_OVERRIDE_DIS; 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_blocking(uart_t uart, uint32_t baudrate) { cc2538_uart_t *u; unsigned int uart_num; uint32_t divisor; switch (uart) { #if UART_0_EN case UART_0: u = UART_0_DEV; /* Run on SYS_DIV */ u->CC = 0; /* * Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register */ IOC_UARTRXD_UART0 = UART_0_RX_PIN; /* * Pad Control for the TX pin: * - Set function to UARTn TX * - Output Enable */ IOC_PXX_SEL[UART_0_TX_PIN] = UART0_TXD; IOC_PXX_OVER[UART_0_TX_PIN] = IOC_OVERRIDE_OE; /* Set RX and TX pins to peripheral mode */ gpio_hardware_control(UART_0_TX_PIN); gpio_hardware_control(UART_0_RX_PIN); break; #endif #if UART_1_EN case UART_1: u = UART_1_DEV; /* Run on SYS_DIV */ u->CC = 0; /* * Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register */ IOC_UARTRXD_UART1 = UART_1_RX_PIN; /* * Pad Control for the TX pin: * - Set function to UARTn TX * - Output Enable */ IOC_PXX_SEL[UART_1_TX_PIN] = UART1_TXD; IOC_PXX_OVER[UART_1_TX_PIN] = IOC_OVERRIDE_OE; /* Set RX and TX pins to peripheral mode */ gpio_hardware_control(UART_1_TX_PIN); gpio_hardware_control(UART_1_RX_PIN); #if ( defined(UART_1_RTS_PORT) && defined(UART_1_RTS_PIN) ) IOC_PXX_SEL[UART_1_RTS_PIN] = UART1_RTS; gpio_hardware_control(UART_1_RTS_PIN); IOC_PXX_OVER[UART_1_RTS_PIN] = IOC_OVERRIDE_OE; u->CTLbits.RTSEN = 1; #endif #if ( defined(UART_1_CTS_PORT) && defined(UART_1_CTS_PIN) ) IOC_UARTCTS_UART1 = UART_1_CTS_PIN; gpio_hardware_control(UART_1_CTS_PIN); IOC_PXX_OVER[UART_1_CTS_PIN] = IOC_OVERRIDE_DIS; u->CTLbits.CTSEN = 1; #endif break; #endif default: return -1; } /* 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->IM = 0; u->IMbits.RXIM = 1; /**< UART receive interrupt mask */ u->IMbits.RTIM = 1; /**< UART receive time-out interrupt mask */ u->IMbits.OEIM = 1; /**< UART overrun error interrupt mask */ u->IMbits.BEIM = 1; /**< UART break error interrupt mask */ u->IMbits.FEIM = 1; /**< UART framing error interrupt mask */ /* Set FIFO interrupt levels: */ u->IFLSbits.RXIFLSEL = FIFO_LEVEL_1_8TH; u->IFLSbits.TXIFLSEL = FIFO_LEVEL_4_8TH; /* Make sure the UART is disabled before trying to configure it */ u->CTL = 0; u->CTLbits.RXE = 1; u->CTLbits.TXE = 1; u->CTLbits.HSE = UART_CTL_HSE_VALUE; /* Set the divisor for the baud rate generator */ divisor = sys_clock_freq(); divisor <<= UART_CTL_HSE_VALUE + 2; 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->LCRH = 0; u->LCRHbits.WLEN = UART_WORD_LENGTH - 5; u->LCRHbits.FEN = 1; /**< Enable FIFOs */ u->LCRHbits.PEN = 0; /**< No parity */ /* UART Enable */ u->CTLbits.UARTEN = 1; return 0; }
/** * @brief Setup the given timer * */ int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg) { DEBUG("%s(%u, %lu, %p, %p)\n", __FUNCTION__, tim, freq, cb, arg); if (tim >= TIMER_NUMOF) { return -1; } /* Save the callback function: */ isr_ctx[tim].cb = cb; isr_ctx[tim].arg = arg; /* Enable the clock for this timer: */ SYS_CTRL->RCGCGPT |= (1 << tim); /* Disable this timer before configuring it: */ dev(tim)->CTL = 0; uint32_t prescaler = 0; uint32_t chan_mode = TNMIE | GPTIMER_PERIODIC_MODE; if (timer_config[tim].cfg == GPTMCFG_32_BIT_TIMER) { /* Count up in periodic mode */ chan_mode |= TNCDIR ; if (timer_config[tim].chn > 1) { DEBUG("Invalid timer_config. Multiple channels are available only in 16-bit mode."); return -1; } if (freq != sys_clock_freq()) { DEBUG("In 32-bit mode, the GPTimer frequency must equal the system clock frequency (%u).\n", (unsigned)sys_clock_freq()); return -1; } } else if (timer_config[tim].cfg == GPTMCFG_16_BIT_TIMER) { prescaler = sys_clock_freq(); prescaler += freq / 2; prescaler /= freq; if (prescaler > 0) prescaler--; if (prescaler > 255) prescaler = 255; dev(tim)->TAPR = prescaler; dev(tim)->TAILR = LOAD_VALUE; } else { DEBUG("timer_init: invalid timer config must be 16 or 32Bit mode!\n"); return -1; } dev(tim)->CFG = timer_config[tim].cfg; dev(tim)->CTL = TAEN; dev(tim)->TAMR = chan_mode; if (timer_config[tim].chn > 1) { dev(tim)->TBMR = chan_mode; dev(tim)->TBPR = prescaler; dev(tim)->TBILR = LOAD_VALUE; /* Enable the timer: */ dev(tim)->CTL = TBEN | TAEN; } /* Enable interrupts for given timer: */ _irq_enable(tim); return 0; }