예제 #1
0
파일: i2c.c 프로젝트: phectori/RIOT
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_CMSSCL;
    IOC_PXX_SEL[I2C_0_SDA_PIN] = I2C_CMSSDA;

    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;
}
예제 #2
0
static void recover_i2c_bus(void) {
    /* Switch to software GPIO mode for bus recovery */
    release_sda();
    release_scl();

    if (!bus_quiet()) {
        const uint_fast8_t try_limit = 200;
        uint_fast8_t n;
        for (n = 0; n < try_limit; n++) {
            if (bus_quiet()) {
                DEBUG("%s(): SDA released after%4u SCL pulses.\n", __FUNCTION__, n);
                break;
            }

            assert_scl();

#ifdef MODULE_XTIMER
            xtimer_usleep(scl_delay);
#else
            thread_yield();
#endif

            release_scl();

#ifdef MODULE_XTIMER
            xtimer_usleep(scl_delay);
#else
            thread_yield();
#endif
        }

        if (n >= try_limit) {
            DEBUG("%s(): Failed to release SDA after%4u SCL pulses.\n", __FUNCTION__, n);
        }
    }

    /* Return to hardware mode for the I2C pins */
    gpio_hardware_control(I2C_0_SCL_PIN);
    gpio_hardware_control(I2C_0_SDA_PIN);
}
예제 #3
0
파일: uart.c 프로젝트: 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 */
}
예제 #4
0
파일: uart.c 프로젝트: 4dahalibut/RIOT
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;
}