Esempio n. 1
0
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;
}
Esempio n. 2
0
/**
 * @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;
}
Esempio n. 3
0
File: uart.c Progetto: kYc0o/RIOT
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 */
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
File: timer.c Progetto: A-Paul/RIOT
/**
 * @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;
}