// spiClock is 0 to 6, relecting AVR clock dividers 2,4,8,16,32,64,128 // Due can only go as slow as AVR divider 32 -- slowest Due clock is 329,412 Hz void HAL::spiInit(uint8_t spiClock) { #if MOTHERBOARD == 500 || MOTHERBOARD == 501 if (spiInitMaded == false) { #endif if (spiClock > 4) spiClock = 1; #if MOTHERBOARD == 500 || MOTHERBOARD == 501 // Set SPI mode 1, clock, select not active after transfer, with delay between transfers SPI_ConfigureNPCS(SPI0, SPI_CHAN_DAC, SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDueDividors[spiClock]) | SPI_CSR_DLYBCT(1)); // Set SPI mode 0, clock, select not active after transfer, with delay between transfers SPI_ConfigureNPCS(SPI0, SPI_CHAN_EEPROM1, SPI_CSR_NCPHA | SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDueDividors[spiClock]) | SPI_CSR_DLYBCT(1)); #endif// MOTHERBOARD==500 || MOTHERBOARD==501 // Set SPI mode 0, clock, select not active after transfer, with delay between transfers SPI_ConfigureNPCS(SPI0, SPI_CHAN, SPI_CSR_NCPHA | SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDueDividors[spiClock]) | SPI_CSR_DLYBCT(1)); SPI_Enable(SPI0); #if MOTHERBOARD == 500 || MOTHERBOARD == 501 spiInitMaded = true; } #endif }
void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) { uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin); mode[ch] = _mode | SPI_CSR_CSAAT; // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed // transfer. Some device needs that for working properly. //TODO: See if this is needed for Flutter SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1)); }
void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) { uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin); divider[ch] = _divider; // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed // transfer. Some device needs that for working properly. SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1)); }
void ledsInit(void){ uint8_t i; //init SPI SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PCS(0)); SPI_ConfigureNPCS(SPI0, 0 , SPI_CSR_NCPHA | SPI_CSR_BITS_12_BIT | SPI_CSR_SCBR(3) | SPI_CSR_DLYBS(2) | SPI_CSR_DLYBCT(0)); //30MHz spi speed SPI_Enable(SPI0); SPI0->SPI_IDR = 0xFFFFFFFF; NVIC_EnableIRQ(SPI0_IRQn); //init pins: SPI gpioSetFun(MISO, GPIO_FUNC_A); gpioSetFun(MOSI, GPIO_FUNC_A); gpioSetFun(SCLK, GPIO_FUNC_A); //init pins: debug LED gpioSetFun(DBGLED, GPIO_FUNC_GPIO); gpioSetDir(DBGLED, 0); gpioSetVal(DBGLED, 0); //init pins: latch gpioSetFun(XLAT, GPIO_FUNC_GPIO); gpioSetDir(XLAT, 0); gpioSetVal(XLAT, 0); //init pins: blanking for(i = 0; i < sizeof(blanks); i++){ gpioSetFun(blanks[i], GPIO_FUNC_GPIO); gpioSetDir(blanks[i], 0); gpioSetVal(blanks[i], 1); } periodicAdd(ledUpdate, 0, 4); }
/** * \brief Initialization of the SPI for communication with ADS7843 component. */ extern void ADS7843_Initialize( void ) { volatile uint32_t uDummy; /* Configure pins */ PIO_Configure(pinsSPI, PIO_LISTSIZE(pinsSPI)); PIO_Configure(pinBusy, PIO_LISTSIZE(pinBusy)); SPI_Configure(BOARD_TSC_SPI_BASE, BOARD_TSC_SPI_ID, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS(BOARD_TSC_NPCS) /* Value of the SPI configuration register. */ ); SPI_ConfigureNPCS(BOARD_TSC_SPI_BASE, BOARD_TSC_NPCS, SPI_CSR_NCPHA | SPI_CSR_DLYBS(DELAY_BEFORE_SPCK) | SPI_CSR_DLYBCT(DELAY_BETWEEN_CONS_COM) | SPI_CSR_SCBR(0xC8) ); SPI_Enable(BOARD_TSC_SPI_BASE); for (uDummy=0; uDummy<100000; uDummy++); uDummy = REG_SPI_SR; uDummy = REG_SPI_RDR; SendCommand(CMD_ENABLE_PENIRQ); }
void hwspi0_init_default(void){ pmc_enable_periph_clk(ID_SPI0); pmc_enable_periph_clk(ID_PIOA); PIO_Configure(PIOA, PIO_PERIPH_A, PIO_MOSI, PIO_DEFAULT); PIO_Configure(PIOA, PIO_PERIPH_A, PIO_MISO, PIO_DEFAULT); PIO_Configure(PIOA, PIO_PERIPH_A, PIO_SCK, PIO_DEFAULT); SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS); SPI_Enable(SPI0); SPI_ConfigureNPCS(SPI0, 0, SPI_CSR_CSAAT | SPI_MODE0 | SPI_CSR_SCBR(SPI_CLOCK_DIV16) | SPI_CSR_DLYBCT(1)); SPI_ConfigureNPCS(SPI0, 1, SPI_CSR_CSAAT | SPI_MODE0 | SPI_CSR_SCBR(SPI_CLOCK_DIV16) | SPI_CSR_DLYBCT(1)); SPI_ConfigureNPCS(SPI0, 2, SPI_CSR_CSAAT | SPI_MODE0 | SPI_CSR_SCBR(SPI_CLOCK_DIV16) | SPI_CSR_DLYBCT(1)); SPI_ConfigureNPCS(SPI0, 3, SPI_CSR_CSAAT | SPI_MODE0 | SPI_CSR_SCBR(SPI_CLOCK_DIV16) | SPI_CSR_DLYBCT(1)); //SPI_ConfigureNPCS(SPI0, 0, SPI_BITS_8 | SCBR); }
/** * @brief Configures and activates the SPI peripheral. * * @param[in] spip pointer to the @p SPIDriver object * * @notapi */ void spi_lld_start(SPIDriver *spip) { uint8_t scbr = spip->config->speed == 0 ? 0xFF : SystemCoreClock < spip->config->speed ? 0x01 : SystemCoreClock / spip->config->speed > 0xFF ? 0xFF : SystemCoreClock / spip->config->speed; if (spip->state == SPI_STOP) { uint32_t irq_priority = spip->config->irq_priority ? spip->config->irq_priority : SAM3XA_SPI_DEFAULT_IRQ_PRIORITY; chDbgCheck(CORTEX_IS_VALID_KERNEL_PRIORITY(irq_priority), "SPI irq_priority"); pmc_enable_peripheral_clock(spip->peripheral_id); nvicEnableVector(spip->irq_id, CORTEX_PRIORITY_MASK(irq_priority)); spip->spi->SPI_CR = SPI_CR_SPIDIS; spip->spi->SPI_CR = SPI_CR_SWRST; spip->spi->SPI_CR = SPI_CR_SWRST; spip->spi->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS; spip->spi->SPI_CSR[0] = SPI_CSR_BITS_8_BIT | SPI_CSR_CSAAT | SPI_CSR_SCBR(scbr) | ( spip->config->spi_mode == 1 ? 0 : spip->config->spi_mode == 2 ? SPI_CSR_CPOL | SPI_CSR_NCPHA : spip->config->spi_mode == 3 ? SPI_CSR_CPOL : SPI_CSR_NCPHA); peripheral_pin_apply(&spip->config->spck_pin); peripheral_pin_apply(&spip->config->miso_pin); peripheral_pin_apply(&spip->config->mosi_pin); palSetPad(spip->config->cs_pin.port, spip->config->cs_pin.pin); palSetPadMode(spip->config->cs_pin.port, spip->config->cs_pin.pin, PAL_MODE_OUTPUT_OPENDRAIN); spip->spi->SPI_CR = SPI_CR_SPIEN; } else { // MMC_SD will reconfigure us without stopping spip->spi->SPI_CSR[0] = SPI_CSR_BITS_8_BIT | SPI_CSR_CSAAT | SPI_CSR_SCBR(scbr) | ( spip->config->spi_mode == 1 ? 0 : spip->config->spi_mode == 2 ? SPI_CSR_CPOL | SPI_CSR_NCPHA : spip->config->spi_mode == 3 ? SPI_CSR_CPOL : SPI_CSR_NCPHA); } }
// spiClock is 0 to 6, relecting AVR clock dividers 2,4,8,16,32,64,128 // Due can only go as slow as AVR divider 32 -- slowest Due clock is 329,412 Hz void HAL::spiInit(uint8_t spiClock) { if(spiClock>4) spiClock = 1; // Set SPI mode 0, clock, select not active after transfer, with delay between transfers SPI_ConfigureNPCS(SPI0, SPI_CHAN, SPI_CSR_NCPHA | SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDueDividors[spiClock]) | SPI_CSR_DLYBCT(1)); SPI_Enable(SPI0); }
// ============================================================================= // 功能:SPI时钟配置函数,时钟来源为50M,经SCR和CPSR分频得到时钟,时钟计算公式为: // SCK = PCLK / (CPSDVSR *[SCR+1]) // 参数:spi_dev,设备句柄 // spiclk,欲配置的时钟速度,单位为Hz // 返回:true=成功,false=失败 // 说明:此驱动固定SCR = 1;而根据手册,CPSDVSR必须为2-254的偶数,因此,频率范围为 // 12.5M ~ 100kHz // ============================================================================= static void __SPI_SetClk(volatile tagSpiReg *Reg,u32 Fre,u8 cs) { if(cs > CN_CS_MAX) return; Reg->SPI_CR |= SPI_CR_SPIDIS; Reg->SPI_CSR[cs] &= ~SPI_CSR_SCBR_Msk; Reg->SPI_CSR[cs] |= SPI_CSR_SCBR(CN_CFG_MCLK/2/Fre); Reg->SPI_CR |= SPI_CR_SPIEN; }
//------------------------------------------------------------------------------ // initialize SPI controller void spiInit(uint8_t bitOrder, uint8_t spiMode, uint8_t spiClockDivider) { uint8_t scbr; Spi* pSpi = SPI0; scbr = spiClockDivider; // disable SPI pSpi->SPI_CR = SPI_CR_SPIDIS; // reset SPI pSpi->SPI_CR = SPI_CR_SWRST; // no mode fault detection, set master mode pSpi->SPI_MR = SPI_PCS(SPI_CHIP_SEL) | SPI_MR_MODFDIS | SPI_MR_MSTR; if (spiMode == SPI_MODE0) { // SPI_MODE0, SPI_MODE1; other modes currently not supported. // mode 0, 8-bit, pSpi->SPI_CSR[SPI_CHIP_SEL] = SPI_CSR_SCBR(scbr) | SPI_CSR_NCPHA; } else { // mode 1, 8-bit, pSpi->SPI_CSR[SPI_CHIP_SEL] = SPI_CSR_SCBR(scbr); } // enable SPI pSpi->SPI_CR |= SPI_CR_SPIEN; }
int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk) { (void) cs; /* lock bus */ mutex_lock(&locks[bus]); /* enable SPI device clock */ PMC->PMC_PCER0 |= (1 << spi_config[bus].id); /* set mode and speed */ dev(bus)->SPI_CSR[0] = (SPI_CSR_SCBR(CLOCK_CORECLOCK / clk) | mode); dev(bus)->SPI_MR = (SPI_MR_MSTR | SPI_MR_MODFDIS); dev(bus)->SPI_CR = SPI_CR_SPIEN; return SPI_OK; }
//------------------------------------------------------------------------------ // initialize SPI controller void SdSpi::init(uint8_t sckDivisor) { uint8_t scbr = sckDivisor; Spi* pSpi = SPI0; // disable SPI pSpi->SPI_CR = SPI_CR_SPIDIS; // reset SPI pSpi->SPI_CR = SPI_CR_SWRST; // no mode fault detection, set master mode pSpi->SPI_MR = SPI_PCS(SPI_CHIP_SEL) | SPI_MR_MODFDIS | SPI_MR_MSTR; // mode 0, 8-bit, pSpi->SPI_CSR[SPI_CHIP_SEL] = SPI_CSR_SCBR(scbr) | SPI_CSR_NCPHA; // enable SPI pSpi->SPI_CR |= SPI_CR_SPIEN; }
// ============================================================================= // 功能: SPI默认硬件初始化配置,主要是时钟配置和GPIO写保护引脚配置 // 参数: RegBaseAddr,寄存器基址 // 返回: 无 // ============================================================================= static void __SPI_HardConfig(u32 BaseAddr) { tagSpiReg *Reg; u32 temp,Fre; Reg = (tagSpiReg *)BaseAddr; XDMAD_Initialize(&dmad,0); Reg->SPI_CR = SPI_CR_SPIDIS|SPI_CR_SWRST; //复位控制器 Reg->SPI_MR = SPI_MR_MSTR|SPI_MR_MODFDIS|QSPI_MR_NBBITS_8_BIT; //默认使用4M波特率 Fre = 4*1000*1000; for(temp = 0; temp < 4; temp ++) { Reg->SPI_CSR[temp] = SPI_CSR_CSAAT|SPI_CSR_SCBR(CN_CFG_MCLK/2/Fre); } //使用DMA方式 // __SPI_DmaConfig(BaseAddr); Reg->SPI_CR = SPI_CR_SPIEN; }
void strain_init() { PMC_EnablePeripheral(ID_SPI); PIO_Configure(&pin_cs_adc_strain, 1); PIO_Configure(&pin_spi_sck, 1); PIO_Configure(&pin_spi_mosi, 1); PIO_Configure(&pin_spi_miso, 1); SPI->SPI_CR = SPI_CR_SPIDIS; SPI->SPI_CR = SPI_CR_SWRST; SPI->SPI_CR = SPI_CR_SWRST; SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS; SPI->SPI_IDR = 0xffffffff; // set scbr to F_CPU / F_SPI SPI->SPI_CSR[0] = SPI_CSR_BITS_16_BIT | SPI_CSR_SCBR(5) | SPI_CSR_NCPHA; // | SPI_CSR_CPOL;*/ SPI->SPI_CR = SPI_CR_SPIEN; volatile uint32_t dummy; for (dummy = 0; dummy < 100000; dummy++) { } // why? atmel does it dummy = REG_SPI_SR; dummy = REG_SPI_RDR; for (int i = 0; i < TACTILE_NUM_TAXELS; i++) g_tactile_last_scan[i] = g_tactile_current_scan[i] = 0; }
void LCD_Init(void){ GPIO->GPIO_PORT[OLED1_DISPLAY_MOSI_PIN/32].GPIO_GPERC = OELD1_DISPLAY_MOSI_GPIO; GPIO->GPIO_PORT[OLED1_DISPLAY_SCK_PIN/32].GPIO_GPERC = OLED1_DISPLAY_SCK_GPIO; gpio_set_mux(OELD1_DISPLAY_MOSI_GPIO, OLED1_DISPLAY_MOSI_PIN, MUX_PERIPHERAL_A); gpio_set_mux(OLED1_DISPLAY_SCK_GPIO, OLED1_DISPLAY_SCK_PIN, MUX_PERIPHERAL_B); // CS pin as output gpio_set_output(OLED1_DISPLAY_SS_GPIO, OLED1_DISPLAY_SS_PIN); GPIO->GPIO_PORT[OLED1_DISPLAY_SS_PIN/32].GPIO_OVRS = OLED1_DISPLAY_SS_GPIO; // OLED reset pin as output gpio_set_output(OLED1_DISPLAY_RESET_GPIO, OLED1_DISPLAY_RESET_PIN); GPIO->GPIO_PORT[OLED1_DISPLAY_RESET_PIN/32].GPIO_OVRS = OLED1_DISPLAY_RESET_GPIO; // OLED data/cmd pin as output gpio_set_output(OLED1_DATACMD_GPIO, OLED1_DATACMD_PIN); GPIO->GPIO_PORT[OLED1_DATACMD_PIN/32].GPIO_OVRS = OLED1_DATACMD_GPIO; // Enable SPI clock. PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAA) | PM_UNLOCK_ADDR(0x028); PM->PM_PBAMASK |= PM_PBAMASK_SPI; // Set up SPI mode SPI->SPI_MR |= SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PCS(0b1011); // Configure NPCS2 SPI->SPI_CSR[2] |= SPI_CSR_SCBR(1) | SPI_CSR_DLYBCT(0x01) | SPI_CSR_CPOL; //Enable the SPI module. SPI->SPI_CR |= SPI_CR_SPIEN; LCD_Poweron_Reset(); #if 1 //128x32 //Set Display off LCD_buffer[0] = OLED_SET_DISPLAY_OFF; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set Display clock Div Ration LCD_buffer[0] = OLED_SET_FREQUENCY; LCD_buffer[1] = 0x80; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display mux ratio LCD_buffer[0] = OLED_SET_MUX_RATIO; LCD_buffer[1] = 0x1F; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display offset LCD_buffer[0] = OLED_SET_DISP_OFFSET; LCD_buffer[1] = 0x00; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display Start line LCD_buffer[0] = OLED_SET_START_LINE(0); SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Enable charge pump LCD_buffer[0] = 0x8D; LCD_buffer[1] = 0x14; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display Segment remap LCD_buffer[0] = OLED_SET_SEG_REMAP_REW; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set Display COM Scan Direction LCD_buffer[0] = OLED_SET_COM_SCAN_DIR_REW; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set COM pins HW Config LCD_buffer[0] = OLED_SET_COM_HW_CONF; LCD_buffer[1] = 0x02; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Contrast LCD_buffer[0] = OLED_SET_CONTRAST; LCD_buffer[1] = 0x8F; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Precharge LCD_buffer[0] = OLED_SET_PRECHARGE; LCD_buffer[1] = 0x22; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set VCOMH Deselect Level LCD_buffer[0] = OLED_SET_VCOM_DESELECT; LCD_buffer[1] = 0x40; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display On/Off LCD_buffer[0] = OLED_ENTIRE_DISPLAY_OFF; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set Display Normal/Inverse LCD_buffer[0] = OLED_SET_DISPLAY_NORMAL; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set Display On LCD_buffer[0] = OLED_SET_DISPLAY_ON; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); #else //128x64 //Set Display off LCD_buffer[0] = OLED_SET_DISPLAY_OFF; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set Display clock Div Ration LCD_buffer[0] = OLED_SET_FREQUENCY; LCD_buffer[1] = 0x80; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display mux ratio LCD_buffer[0] = OLED_SET_MUX_RATIO; LCD_buffer[1] = 0x1F; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display offset LCD_buffer[0] = OLED_SET_DISP_OFFSET; LCD_buffer[1] = 0x00; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display Start line LCD_buffer[0] = OLED_SET_START_LINE(0); SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Enable charge pump LCD_buffer[0] = 0x8D; LCD_buffer[1] = 0x14; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display Segment remap LCD_buffer[0] = OLED_SET_SEG_REMAP_REW; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set Display COM Scan Direction LCD_buffer[0] = OLED_SET_COM_SCAN_DIR_REW; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set COM pins HW Config LCD_buffer[0] = OLED_SET_COM_HW_CONF; LCD_buffer[1] = 0x12; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Contrast LCD_buffer[0] = OLED_SET_CONTRAST; LCD_buffer[1] = 0x9F; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Precharge LCD_buffer[0] = OLED_SET_PRECHARGE; LCD_buffer[1] = 0x22; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set VCOMH Deselect Level LCD_buffer[0] = OLED_SET_VCOM_DESELECT; LCD_buffer[1] = 0x30; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); //Set Display On/Off LCD_buffer[0] = OLED_ENTIRE_DISPLAY_OFF; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set Display Normal/Inverse LCD_buffer[0] = OLED_SET_DISPLAY_NORMAL; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); //Set Display On LCD_buffer[0] = OLED_SET_DISPLAY_ON; SPI_Send_Buffer(&LCD_buffer[0], 1, LCD_COMMAND); #endif //Clear all RAM for(uint8_t page = 0; page<8; page++) { SPI_Send_Byte(LCD_COMMAND, OLED_SET_START_PAGE(page)); for(uint8_t col = 0; col<128; col++){ SPI_Send_Byte(LCD_DATA, 0x00); } } SPI_Send_Byte(LCD_COMMAND, OLED_SET_START_PAGE(0)); LCD_buffer[0] = 0x22; LCD_buffer[1] = 0; LCD_buffer[2] = 3; SPI_Send_Buffer(&LCD_buffer[0], 3, LCD_COMMAND); LCD_buffer[0] = OLED_SET_ADDRESS_MODE; LCD_buffer[1] = 0x00; SPI_Send_Buffer(&LCD_buffer[0], 2, LCD_COMMAND); }
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; }