Пример #1
0
void at86rf231_gpio_spi_interrupts_init(void)
{
    /* set up GPIO pins */
    /* SCLK and MOSI*/
    GPIOA->CRL &= ~(0xf << (5 * 4));
    GPIOA->CRL |= (0xb << (5 * 4));
    GPIOA->CRL &= ~(0xf << (7 * 4));
    GPIOA->CRL |= (0xb << (7 * 4));
    /* MISO */
    gpio_init_in(SPI_0_MISO_GPIO, GPIO_NOPULL);

    /* SPI init */
    spi_init_master(SPI_0, SPI_CONF_FIRST_RISING, SPI_SPEED_5MHZ);

    spi_poweron(SPI_0);

    /* IRQ0 */
    gpio_init_in(SPI_0_IRQ0_GPIO, GPIO_NOPULL);
    gpio_init_int(SPI_0_IRQ0_GPIO, GPIO_NOPULL, GPIO_RISING, (gpio_cb_t)at86rf231_rx_irq, NULL);

    /* Connect EXTI4 Line to PC4 pin */
    at86rf231_enable_interrupts();

    /* CS */
    gpio_init_out(SPI_0_CS_GPIO, GPIO_NOPULL);
    /* SLEEP */
    gpio_init_out(SPI_0_SLEEP_GPIO, GPIO_NOPULL);
    /* RESET */
    gpio_init_out(SPI_0_RESET_GPIO, GPIO_NOPULL);

}
Пример #2
0
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
{
    LPC_SSPx_Type *spi;
    /* power on the SPI device */
    spi_poweron(dev);

    /* configure SCK, MISO and MOSI pin */
    spi_conf_pins(dev);

    switch(dev) {
#if SPI_0_EN
        case SPI_0:
            spi = LPC_SSP0;
            break;
#endif
#if SPI_1_EN
        case SPI_1:
            spi = LPC_SSP1;
            break;
#endif
        default:
            return -1;
    }

    /* Master mode, SPI disabled */
    spi->CR1 = 0;
    /* Base clock frequency : 12MHz */
    spi->CPSR = 4;
    /* configure bus clock speed */
    switch (speed) {
        case SPI_SPEED_100KHZ:
            spi->CR0 |= (119 << 8);
            break;
        case SPI_SPEED_400KHZ:
            spi->CR0 |= (29 << 8);
            break;
        case SPI_SPEED_1MHZ:
            spi->CR0 |= (11 << 8);
            break;
        case SPI_SPEED_5MHZ:
            spi->CR0 |= (2 << 8); /* Actual : 4MHz */
            break;
        case SPI_SPEED_10MHZ:
            spi->CR0 |= (0 << 8); /* Actual : 12MHz */
            break;
    }
    /* Set mode and 8-bit transfer */
    spi->CR0 |= 0x07 | (conf << 6);
    /* Enable SPI */
    spi->CR1 |= (1 << 1);

    /* Wait while the BUSY flag is set */
    while(spi->SR & (1 << 4)) {}
    /* Clear the RX FIFO */
    while(spi->SR & (1 << 2)) {
        spi->DR;
    }

    return 0;
}
Пример #3
0
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
{
    SPI_TypeDef *spi;

    /* power on the SPI device */
    spi_poweron(dev);

    switch (dev) {
#if SPI_0_EN
        case SPI_0:
            spi = SPI_0_DEV;
            SPI_0_PORT_CLKEN();
            break;
#endif
#if SPI_1_EN
        case SPI_1:
            spi = SPI_1_DEV;
            SPI_1_PORT_CLKEN();
            break;
#endif
        default:
            return -1;
    }

    /* configure SCK, MISO and MOSI pin */
    spi_conf_pins(dev);

    /* reset SPI configuration registers */
    spi->CR1 = 0;
    spi->CR2 = 0;
    spi->I2SCFGR = 0;       /* this makes sure SPI mode is selected */

    /* configure bus clock speed */
    switch (speed) {
        case SPI_SPEED_100KHZ:
            spi->CR1 |= (7 << 3);       /* actual clock: 125KHz (lowest possible) */
            break;
        case SPI_SPEED_400KHZ:
            spi->CR1 |= (5 << 3);       /* actual clock: 500KHz */
            break;
        case SPI_SPEED_1MHZ:
            spi->CR1 |= (4 << 3);       /* actual clock: 1MHz */
            break;
        case SPI_SPEED_5MHZ:
            spi->CR1 |= (2 << 3);       /* actual clock: 4MHz */
            break;
        case SPI_SPEED_10MHZ:
            spi->CR1 |= (1 << 3);       /* actual clock 8MHz */
    }

    /* select clock polarity and clock phase */
    spi->CR1 |= conf;
    /* select master mode */
    spi->CR1 |= SPI_CR1_MSTR;
    /* the NSS (chip select) is managed purely by software */
    spi->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI;
    /* enable the SPI device */
    spi->CR1 |= SPI_CR1_SPE;
    return 0;
}
Пример #4
0
int ws2812_init(ws2812_t *dev, spi_t spi){
  
  dev->spi = spi;
  log;
  /* Init SPI */
  spi_poweron(dev->spi);
  log;
  spi_acquire(dev->spi);
  log;
  int status = spi_init_master(dev->spi, SPI_CONF_FIRST_RISING, SPI_SPEED_4MHZ);
  log;
  spi_release(dev->spi);
  log;
  return status;
}
Пример #5
0
SOL_API struct sol_spi *
sol_spi_open(unsigned int bus, const struct sol_spi_config *config)
{
    struct sol_spi *spi;

    SOL_LOG_INTERNAL_INIT_ONCE;

    if (unlikely(config->api_version != SOL_SPI_CONFIG_API_VERSION)) {
        SOL_WRN("Couldn't open SPI that has unsupported version '%u', "
            "expected version is '%u'",
            config->api_version, SOL_SPI_CONFIG_API_VERSION);
        return NULL;
    }

    SOL_EXP_CHECK(config->bits_per_word != 8, NULL);

    spi = malloc(sizeof(struct sol_spi));
    SOL_NULL_CHECK(spi, NULL);

    spi_poweron(bus);
    spi_acquire(bus);
    spi_conf_pins(bus);
    if (spi_init_master(bus, config->mode, uint32_to_spi_speed_enum(config->frequency)) != 0) {
        SOL_WRN("%u,%u: Unable to setup SPI", bus, config->chip_select);
        spi_release(bus);
        free(spi);
        return NULL;
    }
    spi_release(spi->bus);

    spi->bus = bus;
    spi->cs_pin = config->chip_select;
    spi->transfer.timeout = NULL;

    gpio_init(spi->cs_pin, GPIO_DIR_OUT, GPIO_NOPULL);
    gpio_set(spi->cs_pin);
    return spi;
}
Пример #6
0
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
{
    SercomSpi* spi_dev = spi[dev].dev;

    uint8_t   dopo = 0;
    uint8_t   dipo = 0;
    uint8_t   cpha = 0;
    uint8_t   cpol = 0;
    uint32_t  f_baud = 0;

    switch(speed)
    {
        case SPI_SPEED_100KHZ:
            f_baud = 100000;
            break;
        case SPI_SPEED_400KHZ:
            f_baud = 400000;
            break;
        case SPI_SPEED_1MHZ:
            f_baud = 1000000;
            break;
        case SPI_SPEED_5MHZ:
            return -1;
        case SPI_SPEED_10MHZ:
            return -1;
    }

    switch(conf)
    {
        case SPI_CONF_FIRST_RISING: /**< first data bit is transacted on the first rising SCK edge */
            cpha = 0;
            cpol = 0;
            break;
        case SPI_CONF_SECOND_RISING:/**< first data bit is transacted on the second rising SCK edge */
            cpha = 1;
            cpol = 0;
            break;
        case SPI_CONF_FIRST_FALLING:/**< first data bit is transacted on the first falling SCK edge */
            cpha = 0;
            cpol = 1;
            break;
        case SPI_CONF_SECOND_FALLING:/**< first data bit is transacted on the second falling SCK edge */
            cpha = 1;
            cpol = 1;
            break;
    }

    /* Enable sercom4 in power manager */
    MCLK->APBCMASK.reg |= spi[dev].mclk;

    /* Setup clock */
    GCLK->PCHCTRL[ spi[dev].gclk_id ].reg =
        GCLK_PCHCTRL_CHEN |
        GCLK_PCHCTRL_GEN_GCLK0;

    while (!(GCLK->PCHCTRL[spi[dev].gclk_id].reg & GCLK_PCHCTRL_CHEN));

    /* SCLK+MOSI = output */
    gpio_init(spi[dev].sclk.pin, GPIO_DIR_OUT, GPIO_NOPULL);
    gpio_init(spi[dev].mosi.pin, GPIO_DIR_OUT, GPIO_NOPULL);
    /* MISO = input */
    gpio_init(spi[dev].miso.pin, GPIO_DIR_IN, GPIO_PULLUP);

    /*
     * Set alternate funcion (PMUX) for our ports.
     */
    gpio_init_mux(spi[dev].sclk.pin, spi[dev].sclk.pmux);
    gpio_init_mux(spi[dev].miso.pin, spi[dev].miso.pmux);
    gpio_init_mux(spi[dev].mosi.pin, spi[dev].mosi.pmux);

    /* pin pad mapping */
    dipo = spi[dev].dipo;
    dopo = spi[dev].dopo;

    /* Disable spi to write config */
    spi_dev->CTRLA.bit.ENABLE = 0;
    while (spi_dev->SYNCBUSY.reg);

    /* setup baud */
    spi_dev->BAUD.bit.BAUD = (uint8_t) (((uint32_t) GCLK_REF) / (2 * f_baud) - 1); /* Syncronous mode*/

    spi_dev->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE(0x3) /* 0x2 = slave 0x3 = master */
                          |  (SERCOM_SPI_CTRLA_DOPO(dopo))
                          |  (SERCOM_SPI_CTRLA_DIPO(dipo))
                          |  (cpha << SERCOM_SPI_CTRLA_CPHA_Pos)
                          |  (cpol << SERCOM_SPI_CTRLA_CPOL_Pos);

    while (spi_dev->SYNCBUSY.reg);
    spi_dev->CTRLB.reg = (SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN);
    while(spi_dev->SYNCBUSY.reg);
    spi_poweron(dev);
    return 0;
}
Пример #7
0
Файл: spi.c Проект: Cr0s/RIOT
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
{
    SercomSpi* spi_dev = 0;
    uint8_t   dopo = 0;
    uint8_t   dipo = 0;
    uint8_t   cpha = 0;
    uint8_t   cpol = 0;
    uint32_t   f_baud = 0;
    switch(speed)
    {
    case SPI_SPEED_100KHZ:
        f_baud = 100000;
        break;
    case SPI_SPEED_400KHZ:
        f_baud = 400000;
        break;
    case SPI_SPEED_1MHZ:
        f_baud = 1000000;
        break;
    case SPI_SPEED_5MHZ:
#if CLOCK_CORECLOCK >= 5000000
        f_baud = 5000000;
        break;
#else
        return -1;
#endif
    case SPI_SPEED_10MHZ:
#if CLOCK_CORECLOCK >= 10000000
        f_baud = 10000000;
        break;
#else
        return -1;
#endif
    }
    switch(conf)
    {
    case SPI_CONF_FIRST_RISING: /**< first data bit is transacted on the first rising SCK edge */
        cpha = 0;
        cpol = 0;
        break;
    case SPI_CONF_SECOND_RISING:/**< first data bit is transacted on the second rising SCK edge */
        cpha = 1;
        cpol = 0;
        break;
    case SPI_CONF_FIRST_FALLING:/**< first data bit is transacted on the first falling SCK edge */
        cpha = 0;
        cpol = 1;
        break;
    case SPI_CONF_SECOND_FALLING:/**< first data bit is transacted on the second falling SCK edge */
        cpha = 1;
        cpol = 1;
        break;
    }
    switch(dev)
    {
#ifdef SPI_0_EN
    case SPI_0:
        spi_dev = &SPI_0_DEV;

        /* Enable sercom4 in power manager */
        PM->APBCMASK.reg |= PM_APBCMASK_SERCOM4;
        GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN
                                        | GCLK_CLKCTRL_GEN_GCLK0
                                        | (SERCOM4_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos)));

        /* Setup clock */
        while (GCLK->STATUS.bit.SYNCBUSY) {}
        /* Mux enable*/
        SPI_0_SCLK_DEV.PINCFG[ SPI_0_SCLK_PIN ].bit.PMUXEN = 1;
        SPI_0_MISO_DEV.PINCFG[ SPI_0_MISO_PIN ].bit.PMUXEN = 1;
        SPI_0_MOSI_DEV.PINCFG[ SPI_0_MOSI_PIN ].bit.PMUXEN = 1;

        /*Set mux function to spi. seperate registers, for even or odd pins */
        SPI_0_SCLK_DEV.PMUX[ SPI_0_SCLK_PIN / 2].bit.PMUXE = 5;
        SPI_0_MISO_DEV.PMUX[ SPI_0_MISO_PIN / 2].bit.PMUXO = 5;
        SPI_0_MOSI_DEV.PMUX[ SPI_0_MOSI_PIN / 2].bit.PMUXE = 5;

        /* SCLK+MOSI */
        SPI_0_SCLK_DEV.DIRSET.reg = 1 << SPI_0_SCLK_PIN;
        SPI_0_MOSI_DEV.DIRSET.reg = 1 << SPI_0_MOSI_PIN;

        /* MISO = input */
        /* configure as input */
        SPI_0_MISO_DEV.DIRCLR.reg = 1 << SPI_0_MISO_PIN;
        SPI_0_MISO_DEV.PINCFG[ SPI_0_MISO_PIN ].bit.INEN = true;

        SPI_0_MISO_DEV.OUTCLR.reg = 1 << SPI_0_MISO_PIN;
        SPI_0_MISO_DEV.PINCFG[ SPI_0_MISO_PIN ].bit.PULLEN = true;

        dopo = SPI_0_DOPO;
        dipo  = SPI_0_DIPO;
        break;
#endif
#ifdef SPI_1_EN
    case SPI_1:
        spi_dev = &SPI_1_DEV;

        /* Enable sercom5 in power manager */
        PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5;
        /* Setup clock */            /* configure GCLK0 to feed sercom5 */;
        GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN
                                        | GCLK_CLKCTRL_GEN_GCLK0
                                        | (SERCOM5_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos)));

        /* Mux enable*/
        SPI_1_SCLK_DEV.PINCFG[ SPI_1_SCLK_PIN ].bit.PMUXEN = 1;
        SPI_1_MISO_DEV.PINCFG[ SPI_1_MISO_PIN ].bit.PMUXEN = 1;
        SPI_1_MOSI_DEV.PINCFG[ SPI_1_MOSI_PIN ].bit.PMUXEN = 1;
        /*Set mux function to spi. seperate registers, for even or odd pins */
        SPI_1_SCLK_DEV.PMUX[ SPI_1_SCLK_PIN / 2].bit.PMUXO = 3;
        SPI_1_MISO_DEV.PMUX[ SPI_1_MISO_PIN / 2].bit.PMUXE = 3;
        SPI_1_MOSI_DEV.PMUX[ SPI_1_MOSI_PIN / 2].bit.PMUXE = 3;
        /* SCLK+MOSI */
        SPI_1_SCLK_DEV.DIRSET.reg = 1 << SPI_1_SCLK_PIN;
        SPI_1_MOSI_DEV.DIRSET.reg = 1 << SPI_1_MOSI_PIN;

        /* MISO = input */
        /* configure as input */
        SPI_1_MISO_DEV.DIRCLR.reg = 1 << SPI_1_MISO_PIN;
        SPI_1_MISO_DEV.PINCFG[ SPI_1_MISO_PIN ].bit.INEN = true;

        SPI_1_MISO_DEV.OUTCLR.reg = 1 << SPI_1_MISO_PIN;
        SPI_1_MISO_DEV.PINCFG[SPI_1_MISO_PIN].bit.PULLEN = true;

        dopo = SPI_1_DOPO;
        dipo  = SPI_1_DIPO;
        break;
#endif
    default:
        return -1;
    }
    spi_dev->CTRLA.bit.ENABLE = 0;  /* Disable spi to write confs */
    while (spi_dev->SYNCBUSY.reg) {}
    spi_dev->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE_SPI_MASTER;
    while (spi_dev->SYNCBUSY.reg) {}

    spi_dev->BAUD.bit.BAUD = (uint8_t) (((uint32_t)CLOCK_CORECLOCK) / (2 * f_baud) - 1); /* Syncronous mode*/


    spi_dev->CTRLA.reg |= (SERCOM_SPI_CTRLA_DOPO(dopo))
                          |  (SERCOM_SPI_CTRLA_DIPO(dipo))
                          |  (cpha << SERCOM_SPI_CTRLA_CPHA_Pos)
                          |  (cpol << SERCOM_SPI_CTRLA_CPOL_Pos);

    while (spi_dev->SYNCBUSY.reg) {}
    spi_dev->CTRLB.reg = (SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN);
    while(spi_dev->SYNCBUSY.reg) {}
    spi_poweron(dev);
    return 0;
}
Пример #8
0
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
{
    SercomSpi* spi_dev = 0;
    uint8_t   dopo = 0;
    uint8_t   dipo = 0;
    uint8_t   cpha = 0;
    uint8_t   cpol = 0;
    uint32_t   f_baud = 0;
    /* Speed < ½ f_ref, current f_ref = 8`000`000 
    *  baud = f_ref/(2 f_baud) - 1 
    */
    switch(speed)
    {
        case SPI_SPEED_100KHZ:       /**< drive the SPI bus with 100KHz */
            f_baud = 100000;
            break;
        case SPI_SPEED_400KHZ:           /**< drive the SPI bus with 400KHz */
            f_baud = 400000;
            break;
        case SPI_SPEED_1MHZ:             /**< drive the SPI bus with 1MHz */
            f_baud = 1000000;
            break;
        case SPI_SPEED_5MHZ:             /**< drive the SPI bus with 5MHz */
            return -1;
        case SPI_SPEED_10MHZ:             /**< drive the SPI bus with 10MHz */
            return -1;
    }
    switch(conf)
    {
        case SPI_CONF_FIRST_RISING: /**< first data bit is transacted on the first rising SCK edge */
            cpha = 0;
            cpol = 0;
            break;
        case SPI_CONF_SECOND_RISING:/**< first data bit is transacted on the second rising SCK edge */
            cpha = 1;
            cpol = 0;
            break;
        case SPI_CONF_FIRST_FALLING:/**< first data bit is transacted on the first falling SCK edge */
            cpha = 0;
            cpol = 1;
            break;
        case SPI_CONF_SECOND_FALLING:/**< first data bit is transacted on the second falling SCK edge */
            cpha = 1;
            cpol = 1;
            break;
    }
    switch(dev)
    {
#ifdef SPI_0_EN
        case SPI_0:
            spi_dev = &SPI_0_DEV;  
            
            /* Enable sercom4 in power manager */
            PM->APBCMASK.reg |= PM_APBCMASK_SERCOM4;
            GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (SERCOM4_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos)));

            /* Setup clock */            
            while (GCLK->STATUS.bit.SYNCBUSY);
            pmux_set(SPI_0_SCLK_PIN, F);
            pmux_set(SPI_0_MISO_PIN, F);
            pmux_set(SPI_0_MOSI_PIN, F);

            // uint32_t pinmask = (((1UL << (SPI_0_SCLK_PIN % 32)) | (1UL << (SPI_0_MISO_PIN % 32)))  >> 16);
            // /* PMUX */
            // SPI_0_PORT0.WRCONFIG.reg |= 
            //                  PORT_WRCONFIG_HWSEL
            //                 | PORT_WRCONFIG_WRPMUX
            //                 | (0x5 << PORT_WRCONFIG_PMUX_Pos)
            //                 | PORT_WRCONFIG_PMUXEN
            //                 | (pinmask << PORT_WRCONFIG_PINMASK_Pos);

            // pinmask = (1UL << (SPI_0_MOSI_PIN % 32)) >> 16;
            // SPI_0_PORT1.WRCONFIG.reg |= 
            //                  PORT_WRCONFIG_HWSEL
            //                 | PORT_WRCONFIG_WRPMUX
            //                 | (0x5 << PORT_WRCONFIG_PMUX_Pos)
            //                 | PORT_WRCONFIG_PMUXEN
            //                 | (pinmask << PORT_WRCONFIG_PINMASK_Pos);
            //SCLK+MOSI
            SPI_0_SCLK_DEV.DIRSET.reg = (1 << (SPI_0_SCLK_PIN % 32));
            SPI_0_MOSI_DEV.DIRSET.reg = (1 << (SPI_0_MOSI_PIN % 32));

            //MISO = input
            /* configure as input */
            SPI_0_MISO_DEV.DIRCLR.reg = (1<<(SPI_0_MISO_PIN % 32));
            SPI_0_MISO_DEV.PINCFG[SPI_0_MISO_PIN % 32].bit.INEN = true;

            SPI_0_MISO_DEV.OUTCLR.reg = (1 << (SPI_0_MISO_PIN % 32));
            SPI_0_MISO_DEV.PINCFG[SPI_0_MISO_PIN % 32].bit.PULLEN = true;

            dopo = SPI_0_DOPO;
            dipo  = SPI_0_DIPO;
            break;
#endif
#ifdef SPI_1_EN
        case SPI_1:
            spi_dev = &SPI_1_DEV;

            /* Enable sercom5 in power manager */
            PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5;
            /* Setup clock */            /* configure GCLK0 to feed sercom5 */;
            GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (SERCOM5_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos)));
            while (GCLK->STATUS.reg);

            pmux_set(SPI_1_SCLK_PIN, D);
            pmux_set(SPI_1_MISO_PIN, D);
            pmux_set(SPI_1_MOSI_PIN, D);
            //SCLK+MOSI
            SPI_1_SCLK_DEV.DIRSET.reg = (1 << (SPI_1_SCLK_PIN % 32));
            SPI_1_MOSI_DEV.DIRSET.reg = (1 << (SPI_1_MOSI_PIN % 32));

            //MISO = input
            /* configure as input */
            SPI_1_MISO_DEV.DIRCLR.reg = (1<<(SPI_1_MISO_PIN % 32));
            SPI_1_MISO_DEV.PINCFG[SPI_1_MISO_PIN % 32].bit.INEN = true;

            SPI_1_MISO_DEV.OUTCLR.reg = (1 << (SPI_1_MISO_PIN % 32));
            SPI_1_MISO_DEV.PINCFG[SPI_1_MISO_PIN % 32].bit.PULLEN = true;

            dopo = SPI_1_DOPO;
            dipo  = SPI_1_DIPO;
            break;
#endif
    }
    spi_dev->CTRLA.bit.ENABLE = 0;  // Disable spi to write confs
    while (spi_dev->SYNCBUSY.reg);
    spi_dev->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE_SPI_MASTER;
    while (spi_dev->SYNCBUSY.reg);
    
    spi_dev->BAUD.bit.BAUD = (uint8_t) (((uint32_t) SPI_0_F_REF) / (2 * f_baud) - 1); // Synchronous mode
    spi_dev->CTRLA.reg |= (SERCOM_SPI_CTRLA_DOPO(dopo))
                       |  (SERCOM_SPI_CTRLA_DIPO(dipo))
                       |  (cpha << SERCOM_SPI_CTRLA_CPHA_Pos)
                       |  (cpol << SERCOM_SPI_CTRLA_CPOL_Pos);

    while (spi_dev->SYNCBUSY.reg);
    spi_dev->CTRLB.reg = (SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN);
    while(spi_dev->SYNCBUSY.reg);
    spi_poweron(dev);
    return 0;
}
Пример #9
0
Файл: spi.c Проект: JMR-b/RIOT
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
{
    uint8_t speed_divider;
    Spi *spi_port;

    spi_poweron(dev);

    switch (speed) {
        case SPI_SPEED_400KHZ:
            speed_divider = 210;
            break;

        case SPI_SPEED_1MHZ:
            speed_divider = 84;
            break;

        case SPI_SPEED_5MHZ:
            speed_divider = 17;
            break;

        case SPI_SPEED_10MHZ: /* this might be too fast */
            speed_divider = 8;
            break;

        default:
            return -1;
    }

    switch (dev) {
#if SPI_0_EN
        case SPI_0:
            spi_port = SPI_0_DEV;
            break;
#endif /* SPI_0_EN */
        default:
            return -2;
    }

    /* Configure SCK, MISO and MOSI pin */
    spi_conf_pins(dev);

    /***************** SPI-Init *****************/

    /* Chip Select Register */
    spi_port->SPI_CSR[0] = 0; /* This is index 0 since we don't use internal CS-Signals */

    switch (conf) {
        case SPI_CONF_FIRST_RISING:
            spi_port->SPI_CSR[0] &= ~SPI_CSR_CPOL;
            spi_port->SPI_CSR[0] |= SPI_CSR_NCPHA;
            break;

        case SPI_CONF_SECOND_RISING:
            spi_port->SPI_CSR[0] &= ~SPI_CSR_CPOL;
            spi_port->SPI_CSR[0] &= ~SPI_CSR_NCPHA;
            break;

        case SPI_CONF_FIRST_FALLING:
            spi_port->SPI_CSR[0] |= SPI_CSR_CPOL;
            spi_port->SPI_CSR[0] |= SPI_CSR_NCPHA;
            break;

        case SPI_CONF_SECOND_FALLING:
            spi_port->SPI_CSR[0] |= SPI_CSR_CPOL;
            spi_port->SPI_CSR[0] &= ~ SPI_CSR_NCPHA;
            break;

        default:
            return -2;
    }

    spi_port->SPI_CSR[0] |= SPI_CSR_SCBR(speed_divider);
    spi_port->SPI_CSR[0] |= SPI_CSR_BITS_8_BIT;

    /* Control Register */
    spi_port->SPI_CR |= SPI_CR_SPIEN;
    /* Mode Register */
    spi_port->SPI_MR = 0;
    spi_port->SPI_MR |= SPI_MR_MSTR;
    spi_port->SPI_MR |= SPI_MR_MODFDIS;
    spi_port->SPI_MR &= ~SPI_MR_PS;
    spi_port->SPI_MR &= ~SPI_MR_PCS(0);

    return 0;
}
Пример #10
0
Файл: spi.c Проект: JMR-b/RIOT
int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data))
{
    Spi *spi_port;

    spi_poweron(dev);

    switch (dev) {
#if SPI_0_EN
        case SPI_0:
            spi_port = SPI_0_DEV;
            NVIC_SetPriority(SPI_0_IRQ, SPI_0_IRQ_PRIO);
            NVIC_EnableIRQ(SPI_0_IRQ);
            /* Initialize predefined NSS pin as output so it is "disabled" */
            PIOA->PIO_PER |= PIO_PA28A_SPI0_NPCS0;
            PIOA->PIO_OER |= PIO_PA28A_SPI0_NPCS0;
            break;
#endif /* SPI_0_EN */
        default:
            return -1;
    }

    /* Configure SCK, MISO and MOSI pin */
    spi_conf_pins(dev);

    /***************** SPI-Init *****************/

    /* Chip Select Register */
    spi_port->SPI_CSR[0] = 0;

    switch (conf) {
        case SPI_CONF_FIRST_RISING:
            spi_port->SPI_CSR[0] &= ~SPI_CSR_CPOL;
            spi_port->SPI_CSR[0] |= SPI_CSR_NCPHA;
            break;

        case SPI_CONF_SECOND_RISING:
            spi_port->SPI_CSR[0] &= ~SPI_CSR_CPOL;
            spi_port->SPI_CSR[0] &= ~SPI_CSR_NCPHA;
            break;

        case SPI_CONF_FIRST_FALLING:
            spi_port->SPI_CSR[0] |= SPI_CSR_CPOL;
            spi_port->SPI_CSR[0] |= SPI_CSR_NCPHA;
            break;

        case SPI_CONF_SECOND_FALLING:
            spi_port->SPI_CSR[0] |= SPI_CSR_CPOL;
            spi_port->SPI_CSR[0] &= ~ SPI_CSR_NCPHA;
            break;

        default:
            return -1;
    }

    /* Control Register */
    spi_port->SPI_CR |= SPI_CR_SPIEN;
    /* Mode Register */
    spi_port->SPI_MR = 0;
    spi_port->SPI_MR |= SPI_MR_MODFDIS;
    /* Enable SPI interrupts */
    spi_port->SPI_IER = 0;
    spi_port->SPI_IDR = ~(0);
    spi_port->SPI_IER |= 1;
    spi_port->SPI_IDR &= ~SPI_IDR_RDRF;

    /* Set callback */
    spi_config[dev].cb = cb;

    return 0;
}
Пример #11
0
Файл: spi.c Проект: JMR-b/RIOT
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
{
    if (dev >= SPI_NUMOF) {
        return -1;
    }

    spi_poweron(dev);

    /* disable the device -> nRF51822 reference 3.0 26.1.1 and 27.1*/
    spi[dev]->ENABLE = 0;

    switch(dev) {
#if SPI_0_EN
        case SPI_0:
            /* disable TWI Interface */
            NRF_TWI0->ENABLE = 0;
            break;
#endif
#if SPI_1_EN
        case SPI_1:
            /* disable SPI Slave */
            NRF_SPIS1->ENABLE = 0;
            /* disable TWI Interface */
            NRF_TWI1->ENABLE = 0;
            break;
#endif
        default:
            return -1;
    }

    /* configure direction of used pins */
    spi_conf_pins(dev);
    /* configure SPI mode */
    switch (conf) {
        case SPI_CONF_FIRST_RISING:
            spi[dev]->CONFIG = (SPI_CONFIG_CPOL_ActiveHigh << 2) | (SPI_CONFIG_CPHA_Leading << 1);
            break;
        case SPI_CONF_SECOND_RISING:
            spi[dev]->CONFIG = (SPI_CONFIG_CPOL_ActiveHigh << 2) | (SPI_CONFIG_CPHA_Trailing << 1);
            break;
        case SPI_CONF_FIRST_FALLING:
            spi[dev]->CONFIG = (SPI_CONFIG_CPOL_ActiveLow << 2) | (SPI_CONFIG_CPHA_Leading << 1);
            break;
        case SPI_CONF_SECOND_FALLING:
            spi[dev]->CONFIG = (SPI_CONFIG_CPOL_ActiveLow << 2) | (SPI_CONFIG_CPHA_Trailing << 1);
            break;
    }

    /* select bus speed */
    switch (speed) {
        case SPI_SPEED_100KHZ:          /* 125 KHz for this device */
            spi[dev]->FREQUENCY = SPI_FREQUENCY_FREQUENCY_K125;
            break;
        case SPI_SPEED_400KHZ:          /* 500 KHz for this device */
            spi[dev]->FREQUENCY = SPI_FREQUENCY_FREQUENCY_K500;
            break;
        case SPI_SPEED_1MHZ:            /* 1 MHz for this device */
            spi[dev]->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M1;
            break;
        case SPI_SPEED_5MHZ:            /* 4 MHz for this device */
            spi[dev]->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M4;
            break;
        case SPI_SPEED_10MHZ:           /* 8 MHz for this device */
            spi[dev]->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M8;
            break;
    }

    /* finally enable the device */
    spi[dev]->ENABLE = 1;
    return 0;
}
Пример #12
0
int nrf24l01p_init(nrf24l01p_t *dev, spi_t spi, gpio_t ce, gpio_t cs, gpio_t irq)
{
    int status;
    char INITIAL_TX_ADDRESS[] =  {0xe7, 0xe7, 0xe7, 0xe7, 0xe7,};
    char INITIAL_RX_ADDRESS[] =  {0xe7, 0xe7, 0xe7, 0xe7, 0xe7,};

    dev->spi = spi;
    dev->ce = ce;
    dev->cs = cs;
    dev->irq = irq;
    dev->listener = KERNEL_PID_UNDEF;

    /* Init CE pin */
    gpio_init(dev->ce, GPIO_DIR_OUT, GPIO_NOPULL);

    /* Init CS pin */
    gpio_init(dev->cs, GPIO_DIR_OUT, GPIO_NOPULL);
    gpio_set(dev->cs);

    /* Init IRQ pin */
    gpio_init_int(dev->irq, GPIO_PULLUP, GPIO_FALLING, nrf24l01p_rx_cb, dev);


    /* Init SPI */
    spi_poweron(dev->spi);
    spi_acquire(dev->spi);
    status = spi_init_master(dev->spi, SPI_CONF_FIRST_RISING, SPI_SPEED_400KHZ);
    spi_release(dev->spi);

    if (status < 0) {
        return status;
    }

    xtimer_spin(DELAY_AFTER_FUNC_TICKS);

    /* Flush TX FIFIO */
    status = nrf24l01p_flush_tx_fifo(dev);

    if (status < 0) {
        return status;
    }

    /* Flush RX FIFIO */
    status = nrf24l01p_flush_rx_fifo(dev);

    if (status < 0) {
        return status;
    }

    /* Setup adress width */
    status = nrf24l01p_set_address_width(dev, NRF24L01P_AW_5BYTE);

    if (status < 0) {
        return status;
    }

    /* Setup payload width */
    status = nrf24l01p_set_payload_width(dev, NRF24L01P_PIPE0, NRF24L01P_MAX_DATA_LENGTH);

    if (status < 0) {
        return status;
    }

    /* Set RF channel */
    status = nrf24l01p_set_channel(dev, INITIAL_RF_CHANNEL);

    if (status < 0) {
        return status;
    }

    /* Set RF power */
    status = nrf24l01p_set_power(dev, INITIAL_RX_POWER_0dB);

    if (status < 0) {
        return status;
    }

    /* Set RF datarate */
    status = nrf24l01p_set_datarate(dev, NRF24L01P_DR_250KBS);

    if (status < 0) {
        return status;
    }

    /* Set TX Address */
    status = nrf24l01p_set_tx_address(dev, INITIAL_TX_ADDRESS, INITIAL_ADDRESS_WIDTH);

    if (status < 0) {
        return status;
    }

    /* Set RX Adress */
    status = nrf24l01p_set_rx_address(dev, NRF24L01P_PIPE0, INITIAL_RX_ADDRESS, INITIAL_ADDRESS_WIDTH);

    if (status < 0) {
        return status;
    }

    /* Reset auto ack for all pipes */
    status = nrf24l01p_disable_all_auto_ack(dev);

    if (status < 0) {
        return status;
    }

    /* Setup Auto ACK and retransmission */
    status = nrf24l01p_setup_auto_ack(dev, NRF24L01P_PIPE0, NRF24L01P_RETR_750US, 15);

    if (status < 0) {
        return status;
    }

    /* Setup CRC */
    status = nrf24l01p_enable_crc(dev, NRF24L01P_CRC_2BYTE);

    if (status < 0) {
        return status;
    }

    /* Reset all interrupt flags */
    status = nrf24l01p_reset_all_interrupts(dev);

    if (status < 0) {
        return status;
    }

    return nrf24l01p_on(dev);
}