int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { /* check if device is valid */ if (dev >= SPI_NUMOF) { return -1; } /* enable clocks */ CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(spi_config[dev].cmu, true); /* initialize and enable peripheral */ EFM32_CREATE_INIT(init, USART_InitSync_TypeDef, USART_INITSYNC_DEFAULT, .conf.baudrate = (uint32_t) speed, .conf.clockMode = (USART_ClockMode_TypeDef) conf, .conf.msbf = true ); USART_InitSync(spi_config[dev].dev, &init.conf); /* configure the pins */ spi_conf_pins(dev); return 0; }
void cc110x_cs(void) { volatile int retry_count = 0; /* Switch MISO/GDO1 to GPIO input mode */ gpio_init_in(CC110X_GDO1, GPIO_NOPULL); /* CS to low */ gpio_clear(CC110X_CS); /* Wait for SO to go low (voltage regulator * has stabilized and the crystal is running) */ while (gpio_read(CC110X_GDO1)) { /* Wait ~500us and try again */ hwtimer_wait(CS_SO_WAIT_TIME); if (gpio_read(CC110X_GDO1)) { retry_count++; if (retry_count > CC1100_GDO1_LOW_RETRY) { puts("[CC1100 SPI] fatal error\n"); break; } gpio_set(CC110X_CS); gpio_clear(CC110X_CS); } } /* Switch MISO/GDO1 to SPI mode */ spi_conf_pins(CC110X_SPI); }
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; }
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; }
void cc110x_cs(cc110x_t *dev) { volatile int retry_count = 0; /* Switch MISO/GDO1 to GPIO input mode */ #ifndef GPIO_READS_SPI_PINS gpio_init(dev->params.gdo1, GPIO_DIR_IN, GPIO_NOPULL); #endif /* CS to low */ gpio_clear(dev->params.cs); /* Wait for SO to go low (voltage regulator * has stabilized and the crystal is running) */ while (gpio_read(dev->params.gdo1)) { /* Wait ~500us and try again */ xtimer_usleep(CS_SO_WAIT_TIME); if (gpio_read(dev->params.gdo1)) { retry_count++; if (retry_count > CC110X_GDO1_LOW_RETRY) { puts("[CC110X spi] fatal error\n"); break; } gpio_set(dev->params.cs); gpio_clear(dev->params.cs); } } /* Switch MISO/GDO1 to spi mode */ #ifndef GPIO_READS_SPI_PINS spi_conf_pins(dev->params.spi); #endif }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { SPI_TypeDef *spi; uint16_t br_div; uint8_t bus_div; switch(dev) { #ifdef SPI_0_EN case SPI_0: spi = SPI_0_DEV; bus_div = SPI_0_BUS_DIV; SPI_0_CLKEN(); break; #endif default: return -1; } /* configure SCK, MISO and MOSI pin */ spi_conf_pins(dev); /* configure SPI bus speed */ switch(speed) { case SPI_SPEED_10MHZ: br_div = 0x01 + bus_div; /* actual speed: 9MHz */ break; case SPI_SPEED_5MHZ: br_div = 0x02 + bus_div; /* actual speed: 4.5MHz */ break; case SPI_SPEED_1MHZ: br_div = 0x04 + bus_div; /* actual speed: 1.1MHz */ break; case SPI_SPEED_400KHZ: br_div = 0x05 + bus_div; /* actual speed: 560kHz */ break; case SPI_SPEED_100KHZ: br_div = 0x07; /* actual speed: 280kHz on APB2, 140KHz on APB1 */ break; default: return -2; } /* set up SPI */ spi->CR1 = SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_MSTR | (conf & 0x3) | (br_div << 3); spi->I2SCFGR &= 0xF7FF; /* select SPI mode */ spi->CRCPR = 0x7; /* reset CRC polynomial */ /* enable the SPI device */ spi->CR1 |= SPI_CR1_SPE; return 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; }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { uint8_t speed_devider; SPI_TypeDef *spi_port; switch (speed) { case SPI_SPEED_100KHZ: return -2; /* not possible for stm32f4, APB2 minimum is 328 kHz */ break; case SPI_SPEED_400KHZ: speed_devider = 0x05 + spi_bus_div_map[dev]; /* makes 656 kHz */ break; case SPI_SPEED_1MHZ: speed_devider = 0x04 + spi_bus_div_map[dev]; /* makes 1.3 MHz */ break; case SPI_SPEED_5MHZ: speed_devider = 0x02 + spi_bus_div_map[dev]; /* makes 5.3 MHz */ break; case SPI_SPEED_10MHZ: speed_devider = 0x01 + spi_bus_div_map[dev]; /* makes 10.5 MHz */ break; default: return -1; } switch (dev) { #if SPI_0_EN case SPI_0: spi_port = SPI_0_DEV; /* enable clocks */ SPI_0_CLKEN(); SPI_0_SCK_PORT_CLKEN(); SPI_0_MISO_PORT_CLKEN(); SPI_0_MOSI_PORT_CLKEN(); break; #endif /* SPI_0_EN */ #if SPI_1_EN case SPI_1: spi_port = SPI_1_DEV; /* enable clocks */ SPI_1_CLKEN(); SPI_1_SCK_PORT_CLKEN(); SPI_1_MISO_PORT_CLKEN(); SPI_1_MOSI_PORT_CLKEN(); break; #endif /* SPI_1_EN */ #if SPI_2_EN case SPI_2: spi_port = SPI_2_DEV; /* enable clocks */ SPI_2_CLKEN(); SPI_2_SCK_PORT_CLKEN(); SPI_2_MISO_PORT_CLKEN(); SPI_2_MOSI_PORT_CLKEN(); break; #endif /* SPI_2_EN */ default: return -2; } /* configure SCK, MISO and MOSI pin */ spi_conf_pins(dev); /**************** SPI-Init *****************/ spi_port->I2SCFGR &= ~(SPI_I2SCFGR_I2SMOD);/* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ spi_port->CR1 = 0; spi_port->CR2 = 0; /* the NSS (chip select) is managed purely by software */ spi_port->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI; spi_port->CR1 |= (speed_devider << 3); /* Define serial clock baud rate. 001 leads to f_PCLK/4 */ spi_port->CR1 |= (SPI_CR1_MSTR); /* 1: master configuration */ spi_port->CR1 |= (conf); /* enable SPI */ spi_port->CR1 |= (SPI_CR1_SPE); return 0; }
int spi_init_slave(spi_t dev, spi_conf_t conf, char(*cb)(char data)) { SPI_TypeDef *spi_port; switch (dev) { #if SPI_0_EN case SPI_0: spi_port = SPI_0_DEV; /* enable clocks */ SPI_0_CLKEN(); SPI_0_SCK_PORT_CLKEN(); SPI_0_MISO_PORT_CLKEN(); SPI_0_MOSI_PORT_CLKEN(); /* configure interrupt channel */ NVIC_SetPriority(SPI_0_IRQ, SPI_IRQ_PRIO); /* set SPI interrupt priority */ NVIC_EnableIRQ(SPI_0_IRQ); /* set SPI interrupt priority */ break; #endif /* SPI_0_EN */ #if SPI_1_EN case SPI_1: spi_port = SPI_1_DEV; /* enable clocks */ SPI_1_CLKEN(); SPI_1_SCK_PORT_CLKEN(); SPI_1_MISO_PORT_CLKEN(); SPI_1_MOSI_PORT_CLKEN(); /* configure interrupt channel */ NVIC_SetPriority(SPI_1_IRQ, SPI_IRQ_PRIO); NVIC_EnableIRQ(SPI_1_IRQ); break; #endif /* SPI_1_EN */ #if SPI_2_EN case SPI_2: spi_port = SPI_2_DEV; /* enable clocks */ SPI_2_CLKEN(); SPI_2_SCK_PORT_CLKEN(); SPI_2_MISO_PORT_CLKEN(); SPI_2_MOSI_PORT_CLKEN(); /* configure interrupt channel */ NVIC_SetPriority(SPI_2_IRQ, SPI_IRQ_PRIO); NVIC_EnableIRQ(SPI_2_IRQ); break; #endif /* SPI_2_EN */ default: return -1; } /* configure sck, miso and mosi pin */ spi_conf_pins(dev); /***************** SPI-Init *****************/ spi_port->I2SCFGR &= ~(SPI_I2SCFGR_I2SMOD); spi_port->CR1 = 0; spi_port->CR2 = 0; /* enable RXNEIE flag to enable rx buffer not empty interrupt */ spi_port->CR2 |= (SPI_CR2_RXNEIE); /*1:not masked */ spi_port->CR1 |= (conf); /* the NSS (chip select) is managed by software and NSS is low (slave enabled) */ spi_port->CR1 |= SPI_CR1_SSM; /* set callback */ spi_config[dev].cb = cb; /* enable SPI device */ spi_port->CR1 |= SPI_CR1_SPE; return 0; }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { (void ) conf; if (dev) { return -1; } uint32_t f_baud = 0; switch(speed) { case SPI_SPEED_100KHZ: f_baud = 100; break; case SPI_SPEED_400KHZ: f_baud = 400; break; case SPI_SPEED_1MHZ: f_baud = 1000; break; case SPI_SPEED_5MHZ: f_baud = 5000; break; case SPI_SPEED_10MHZ: f_baud = 10000; break; } #if 0 /* TODO */ 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; } #endif /* Power*/ PCONP |= PCSSP0; /* Enable power for SSP0 (default is on)*/ /* PIN Setup*/ spi_conf_pins(dev); /* Interface Setup*/ SSP0CR0 = 7; /* Clock Setup*/ uint32_t pclksel; uint32_t cpsr; lpc2387_pclk_scale(F_CPU / 1000, f_baud, &pclksel, &cpsr); PCLKSEL1 &= ~(BIT10 | BIT11); /* CCLK to PCLK divider*/ PCLKSEL1 |= pclksel << 10; SSP0CPSR = cpsr; /* Enable*/ SSP0CR1 |= BIT1; /* SSP-Enable*/ int dummy; /* Clear RxFIFO:*/ while (SPI_RX_AVAIL) { /* while RNE (Receive FIFO Not Empty)...*/ dummy = SSP0DR; /* read data*/ } /* to suppress unused-but-set-variable */ (void) dummy; return 0; }
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; }
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; }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { uint8_t speed_divider; switch (speed) { case SPI_SPEED_100KHZ: return -2; /* not possible for stm32f3 */ break; case SPI_SPEED_400KHZ: speed_divider = 7; /* makes 656 kHz */ break; case SPI_SPEED_1MHZ: speed_divider = 6; /* makes 1.3 MHz */ break; case SPI_SPEED_5MHZ: speed_divider = 4; /* makes 5.3 MHz */ break; case SPI_SPEED_10MHZ: speed_divider = 3; /* makes 10.5 MHz */ break; default: return -1; } switch (dev) { #if SPI_0_EN case SPI_0: /* enable clocks */ SPI_0_CLKEN(); SPI_0_SCK_PORT_CLKEN(); SPI_0_MISO_PORT_CLKEN(); SPI_0_MOSI_PORT_CLKEN(); break; #endif /* SPI_0_EN */ #if SPI_1_EN case SPI_1: /* enable clocks */ SPI_1_CLKEN(); SPI_1_SCK_PORT_CLKEN(); SPI_1_MISO_PORT_CLKEN(); SPI_1_MOSI_PORT_CLKEN(); break; #endif /* SPI_1_EN */ #if SPI_2_EN case SPI_2: /* enable clocks */ SPI_2_CLKEN(); SPI_2_SCK_PORT_CLKEN(); SPI_2_MISO_PORT_CLKEN(); SPI_2_MOSI_PORT_CLKEN(); break; #endif /* SPI_2_EN */ default: return -2; } /* configure SCK, MISO and MOSI pin */ spi_conf_pins(dev); /**************** SPI-Init *****************/ #ifdef CPU_MODEL_STM32F303VC spi[dev]->I2SCFGR &= ~(SPI_I2SCFGR_I2SMOD);/* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ #endif spi[dev]->CR1 = 0; spi[dev]->CR2 = 0; /* the NSS (chip select) is managed purely by software */ spi[dev]->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI; spi[dev]->CR1 |= (speed_divider << 3); /* Define serial clock baud rate. 001 leads to f_PCLK/4 */ spi[dev]->CR1 |= (SPI_CR1_MSTR); /* 1: master configuration */ spi[dev]->CR1 |= (conf); spi[dev]->CR2 |= SPI_CR2_FRXTH; /* set FIFO reception threshold to 8bit (default: 16bit) */ /* enable SPI */ spi[dev]->CR1 |= (SPI_CR1_SPE); return 0; }
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; }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { if (dev != 0) { return -2; } /* reset SPI device */ SPI_DEV->CTL = USART_CTL_SWRST; /* configure pins */ spi_conf_pins(dev); /* configure USART to SPI mode with SMCLK driving it */ SPI_DEV->CTL |= (USART_CTL_CHAR | USART_CTL_SYNC | USART_CTL_MM); SPI_DEV->RCTL = 0; SPI_DEV->TCTL = (USART_TCTL_SSEL_SMCLK | USART_TCTL_STC); /* set polarity and phase */ switch (conf) { case SPI_CONF_SECOND_RISING: SPI_DEV->TCTL |= USART_TCTL_CKPH; break; case SPI_CONF_FIRST_FALLING: SPI_DEV->TCTL |= SPI_CONF_FIRST_FALLING; break; case SPI_CONF_SECOND_FALLING: SPI_DEV->TCTL |= (USART_TCTL_CKPH | SPI_CONF_FIRST_FALLING); break; default: /* do nothing */ break; } /* configure clock - we use no modulation for now */ uint32_t br = CLOCK_CMCLK; switch (speed) { case SPI_SPEED_100KHZ: br /= 100000; break; case SPI_SPEED_400KHZ: br /= 400000; break; case SPI_SPEED_1MHZ: br /= 1000000; break; case SPI_SPEED_5MHZ: br /= 5000000; break; default: /* other clock speeds are not supported */ return -1; } /* make sure the is not smaller then 2 */ if (br < 2) { br = 2; } SPI_DEV->BR0 = (uint8_t)br; SPI_DEV->BR1 = (uint8_t)(br >> 8); SPI_DEV->MCTL = 0; /* enable SPI mode */ SPI_ME |= SPI_ME_BIT; /* release from software reset */ SPI_DEV->CTL &= ~(USART_CTL_SWRST); return 0; }
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed) { if (dev != 0) { return -2; } /* reset SPI device */ SPI_DEV->CTL1 |= USCI_SPI_CTL1_SWRST; /* configure pins */ spi_conf_pins(dev); /* configure USART to SPI mode with SMCLK driving it */ SPI_DEV->CTL0 |= (USCI_SPI_CTL0_UCSYNC | USCI_SPI_CTL0_MST | USCI_SPI_CTL0_MODE_0 | USCI_SPI_CTL0_MSB); SPI_DEV->CTL1 |= (USCI_SPI_CTL1_SSEL_SMCLK); /* set polarity and phase */ switch (conf) { case SPI_CONF_FIRST_RISING: SPI_DEV->CTL0 |= (USCI_SPI_CTL0_CKPH & ~(USCI_SPI_CTL0_CKPL)); break; case SPI_CONF_SECOND_RISING: SPI_DEV->CTL0 |= (~(USCI_SPI_CTL0_CKPH) & ~(USCI_SPI_CTL0_CKPL)); break; case SPI_CONF_FIRST_FALLING: SPI_DEV->CTL0 |= (USCI_SPI_CTL0_CKPH & USCI_SPI_CTL0_CKPL); break; case SPI_CONF_SECOND_FALLING: SPI_DEV->CTL0 |= (~(USCI_SPI_CTL0_CKPH) & USCI_SPI_CTL0_CKPL); break; default: /* do nothing */ break; } /* configure clock - we use no modulation for now */ uint32_t br = CLOCK_CMCLK; switch (speed) { case SPI_SPEED_100KHZ: br /= 100000; break; case SPI_SPEED_400KHZ: br /= 400000; break; case SPI_SPEED_1MHZ: br /= 1000000; break; case SPI_SPEED_5MHZ: br /= 5000000; break; default: /* other clock speeds are not supported */ return -1; } /* make sure the is not smaller then 2 */ if (br < 2) { br = 2; } SPI_DEV->BR0 = (uint8_t)br; SPI_DEV->BR1 = (uint8_t)(br >> 8); /* release from software reset */ SPI_DEV->CTL1 &= ~(USCI_SPI_CTL1_SWRST); return 0; }