OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length ) { OSStatus result; int i; for(i=0; i<buffer_length; i++) { buffer_temp_32[i] = SPI0_TXCMD | (uint32_t)buffer[i];; } dmaSPITX.dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * dmaSPITX.period, 32); dmaSPITX.srcAddr = (uint32_t)buffer_temp_32; dmaSPITX.length = buffer_length * 4; dmaSPIRX.dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * dmaSPIRX.period, 32); dmaSPIRX.destAddr = (uint32_t)buffer; dmaSPIRX.length = buffer_length; MCU_CLOCKS_NEEDED(); SPI0_CS_ENABLE; setup_edma_loop(&dmaSPITX); setup_edma_loop(&dmaSPIRX); EDMA_DRV_StartChannel(dmaSPIRX.dmaCh); EDMA_DRV_StartChannel(dmaSPITX.dmaCh); result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 ); disable_edma_loop(&dmaSPIRX); disable_edma_loop(&dmaSPITX); SPI0_CS_DISABLE; MCU_CLOCKS_NOT_NEEDED(); free_align(dmaSPITX.dmaChStcd); free_align(dmaSPIRX.dmaChStcd); return result; }
/** @brief Enables the MCU to enter deep sleep mode when all threads are suspended. * * @note: When all threads are suspended, mcu can shut down some peripherals to * save power. For example, STM32 enters STOP mode in this condition, * its peripherals are not working and needs to be wake up by an external * interrupt or MICO core's internal timer. So if you are using a peripherals, * you should disable this function temporarily. * To make this function works, you should not disable the macro in MicoDefault.h: * MICO_DISABLE_MCU_POWERSAVE * * @param enable : 1 = enable MCU powersave, 0 = disable MCU powersave * @return none */ void MicoMcuPowerSaveConfig( int enable ){ if (enable == 1) MCU_CLOCKS_NOT_NEEDED(); else MCU_CLOCKS_NEEDED(); }
OSStatus host_platform_bus_init( void ) { OSStatus result; MCU_CLOCKS_NEEDED(); result = mico_rtos_init_semaphore( &sdio_transfer_finished_semaphore, 1); //result = mico_rtos_set_semaphore( &sdio_transfer_finished_semaphore); if ( result != kNoErr ) { return result; } // mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 10000 ); GpioSdIoConfig(1); SdioControllerInit(); SdioSetClk(0); NVIC_EnableIRQ(SD_IRQn); //SdioEnableClk(); MCU_CLOCKS_NOT_NEEDED(); return kNoErr; }
OSStatus host_platform_bus_deinit( void ) { MCU_CLOCKS_NEEDED(); DSPI_DRV_MasterDeinit(0); MCU_CLOCKS_NOT_NEEDED(); mico_rtos_deinit_semaphore(&spi_transfer_finished_semaphore); return kNoErr; }
OSStatus host_platform_bus_deinit( void ) { MCU_CLOCKS_NEEDED(); #ifdef USE_OWN_SPI_DRV pdc_disable_transfer(spi_m_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); spi_disable(SPI_MASTER_BASE); #else spi_master_vec_disable(&spi_master); #endif MCU_CLOCKS_NOT_NEEDED(); return kNoErr; }
OSStatus host_platform_bus_init( void ) { edma_user_config_t g_edmaUserConfig; /* Create a semephore to check for completed eDMA transfers. */ mico_rtos_init_semaphore(&spi_transfer_finished_semaphore, 1); MCU_CLOCKS_NEEDED(); configure_spi_pins(0); // initlize spi0 GPIO PORT_HAL_SetMuxMode(PORTD_BASE,0u,kPortMuxAsGpio); // configure CS as gpio, use software configure CS. GPIO_DRV_OutputPinInit(&spiCsPin[0]); SPI0_CS_DISABLE; /* Initialize eDMA & DMAMUX */ g_edmaUserConfig.chnArbitration = kEDMAChnArbitrationRoundrobin; g_edmaUserConfig.notHaltOnError = false; EDMA_DRV_Init(&g_edmaState, &g_edmaUserConfig); /* DSPI Master Configuration */ dspi_edma_master_setup(&dspiMasterState, 0, 10000000, 8); MCU_CLOCKS_NOT_NEEDED(); dmaSPITX.dmaChanNum = DMA_CH0; dmaSPITX.dmaCh = &dmaCh0; dmaSPITX.type = kEDMAMemoryToPeripheral; dmaSPITX.chSource = kDmaRequestMux0SPI0Tx; dmaSPITX.srcAddr = (uint32_t)NULL; dmaSPITX.destAddr = (uint32_t)&SPI0->PUSHR; dmaSPITX.length = 0; dmaSPITX.size = 4; dmaSPITX.watermark = 4; dmaSPITX.period = 0x01U; dmaSPITX.dmaCallBack = stop_edma_loop; dmaSPIRX.dmaChanNum = DMA_CH1; dmaSPIRX.dmaCh = &dmaCh1; dmaSPIRX.type = kEDMAPeripheralToMemory; dmaSPIRX.chSource = kDmaRequestMux0SPI0Rx; dmaSPIRX.srcAddr = (uint32_t)&SPI0->POPR; dmaSPIRX.destAddr = (uint32_t)NULL; dmaSPIRX.length = 0; dmaSPIRX.size = 1; dmaSPIRX.watermark = 1; dmaSPIRX.period = 0x01U; dmaSPIRX.dmaCallBack = stop_edma_loop_putsem; dmaSPIRX.dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * dmaSPIRX.period, 32); spi_status_print(SPI0); return kNoErr; }
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length ) { OSStatus result; uint32_t junk; MCU_CLOCKS_NEEDED(); SPIX_DMA_TX_STREAM->NDTR = buffer_length; SPIX_DMA_TX_STREAM->M0AR = (uint32_t) buffer; if ( dir == BUS_READ ) { SPIX_DMA_RX_STREAM->NDTR = buffer_length; SPIX_DMA_RX_STREAM->M0AR = (uint32_t) buffer; SPIX_DMA_RX_STREAM->CR |= DMA_MemoryInc_Enable | ( 1 << 4); } else { SPIX_DMA_RX_STREAM->NDTR = buffer_length; SPIX_DMA_RX_STREAM->M0AR = (uint32_t) &junk; SPIX_DMA_RX_STREAM->CR &= ( ~DMA_MemoryInc_Enable ) | ( 1 << 4); } GPIO_ResetBits( SPI_BUS_CS_BANK, ( 1 << SPI_BUS_CS_PIN ) ); /* CS low (to select) */ DMA_Cmd( SPIX_DMA_RX_STREAM, ENABLE ); DMA_Cmd( SPIX_DMA_TX_STREAM, ENABLE ); /* Wait for DMA TX to complete */ result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 ); // loop_count = 0; // while ( ( DMA_GetFlagStatus( SPIX_DMA_RX_STREAM, DMA_FLAG_TCIF3 ) == RESET ) && ( loop_count < (uint32_t) DMA_TIMEOUT_LOOPS ) ) // { // loop_count++; // } DMA_Cmd( SPIX_DMA_RX_STREAM, DISABLE ); DMA_Cmd( SPIX_DMA_TX_STREAM, DISABLE ); /* Clear the CS pin and the DMA status flag */ GPIO_SetBits( SPI_BUS_CS_BANK, ( 1 << SPI_BUS_CS_PIN ) ); /* CS high (to deselect) */ DMA_ClearFlag( SPIX_DMA_RX_STREAM, SPIX_DMA_RX_TCFLAG ); DMA_ClearFlag( SPIX_DMA_TX_STREAM, SPIX_DMA_TX_TCFLAG ); MCU_CLOCKS_NOT_NEEDED(); return result; }
OSStatus host_platform_bus_deinit( void ) { GPIO_InitTypeDef gpio_init_structure; MCU_CLOCKS_NEEDED(); /* Disable SPI and SPI DMA */ SPI_Cmd( SPIX, DISABLE ); SPI_I2S_DeInit( SPIX ); SPI_I2S_DMACmd( SPIX, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, DISABLE ); DMA_DeInit( SPIX_DMA_TX_STREAM ); DMA_DeInit( SPIX_DMA_RX_STREAM ); /* Clear GPIO_B[1:0] */ MicoGpioFinalize( (mico_gpio_t)WL_GPIO0 ); MicoGpioFinalize( (mico_gpio_t)WL_GPIO1 ); /* Clear SPI slave select GPIOs */ gpio_init_structure.GPIO_Mode = GPIO_Mode_AIN; gpio_init_structure.GPIO_OType = GPIO_OType_PP; gpio_init_structure.GPIO_Speed = GPIO_Speed_100MHz; gpio_init_structure.GPIO_Pin = ( 1 << SPI_BUS_CS_PIN ); GPIO_Init( SPI_BUS_CS_BANK, &gpio_init_structure ); /* Clear the SPI lines */ gpio_init_structure.GPIO_Mode = GPIO_Mode_AIN; gpio_init_structure.GPIO_OType = GPIO_OType_PP; gpio_init_structure.GPIO_Speed = GPIO_Speed_100MHz; gpio_init_structure.GPIO_Pin = ( 1 << SPI_BUS_CLOCK_PIN ) | ( 1 << SPI_BUS_MISO_PIN ) | ( 1 << SPI_BUS_MOSI_PIN ); GPIO_Init( SPI_BUS_CLOCK_BANK, &gpio_init_structure ); gpio_irq_disable( SPI_IRQ_BANK, SPI_IRQ_PIN ); /* Disable SPI_SLAVE Periph clock and DMA1 clock */ RCC_APB1PeriphClockCmd( SPIX_CLK, DISABLE ); RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA1, DISABLE ); RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG, DISABLE ); MCU_CLOCKS_NOT_NEEDED(); return kNoErr; }
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length ) { OSStatus result; uint8_t *junk; MCU_CLOCKS_NEEDED(); #ifdef USE_OWN_SPI_DRV pdc_packet_t pdc_spi_packet; pdc_spi_packet.ul_addr = (uint32_t)buffer; pdc_spi_packet.ul_size = buffer_length; pdc_tx_init(spi_m_pdc, &pdc_spi_packet, NULL); if ( dir == BUS_READ ) { pdc_spi_packet.ul_addr = (uint32_t)buffer; pdc_spi_packet.ul_size = buffer_length; } if ( dir == BUS_WRITE ) { junk = malloc(buffer_length); pdc_spi_packet.ul_addr = (uint32_t)junk; pdc_spi_packet.ul_size = buffer_length; } pdc_rx_init(spi_m_pdc, &pdc_spi_packet, NULL); #if 0 if ( dir == BUS_WRITE ) { spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_ENDTX); NVIC_EnableIRQ(SPI_IRQn); } else { spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_ENDRX); NVIC_EnableIRQ(SPI_IRQn); } #endif //platform_log("dir = %d, len = %d",dir, buffer_length);//TBD #ifndef HARD_CS_NSS0 mico_gpio_output_low( MICO_GPIO_15 ); #endif /* Enable the RX and TX PDC transfer requests */ pdc_enable_transfer(spi_m_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN);//pdc buffer address increase automatic. //platform_log("pdc status = 0x%x",pdc_read_status(spi_m_pdc)); #ifndef NO_MICO_RTOS result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 ); #else /* Waiting transfer done*/ while((spi_read_status(SPI_MASTER_BASE) & SPI_SR_RXBUFF) == 0) { __asm("wfi"); } #endif if ( dir == BUS_WRITE ) { if (junk) free(junk); } /* Disable the RX and TX PDC transfer requests */ pdc_disable_transfer(spi_m_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); #ifndef HARD_CS_NSS0 mico_gpio_output_high( MICO_GPIO_15 ); #endif #if 1 //clear PDC Perph Status flags pdc_spi_packet.ul_addr = NULL; pdc_spi_packet.ul_size = 3; pdc_tx_init(spi_m_pdc, &pdc_spi_packet, NULL); pdc_rx_init(spi_m_pdc, &pdc_spi_packet, NULL); #endif #else //spi_master_vec : tx_dscr[0].data = buffer; tx_dscr[0].length = buffer_length; tx_dscr[1].data = NULL; tx_dscr[1].length = 0; //if ( dir == BUS_READ ) { rx_dscr[0].data = buffer; rx_dscr[0].length = buffer_length; //} else { // rx_dscr[0].data = &junk; // rx_dscr[0].length = 0; //} rx_dscr[1].data = NULL; rx_dscr[1].length = 0; #ifndef HARD_CS_NSS0 mico_gpio_output_low( MICO_GPIO_15 ); #endif if (spi_master_vec_transceive_buffer_wait(&spi_master, tx_dscr, rx_dscr) != STATUS_OK) { platform_log("STATUS = -1"); return kGeneralErr; } #ifndef HARD_CS_NSS0 mico_gpio_output_high( MICO_GPIO_15 ); #endif #endif /* USE_OWN_SPI_DR */ MCU_CLOCKS_NOT_NEEDED(); #ifdef USE_OWN_SPI_DRV return result; #else return 0; #endif }
OSStatus host_platform_bus_init( void ) { #ifndef USE_OWN_SPI_DRV struct spi_master_vec_config spi; #else pdc_packet_t pdc_spi_packet; #endif OSStatus result; MCU_CLOCKS_NEEDED(); spi_disable_interrupt(SPI_MASTER_BASE, 0xffffffff); //Disable_global_interrupt();//TBD! result = mico_rtos_init_semaphore( &spi_transfer_finished_semaphore, 1 ); if ( result != kNoErr ) { return result; } mico_gpio_initialize( (mico_gpio_t)MICO_GPIO_9, INPUT_PULL_UP ); //ioport_port_mask_t ul_mask = ioport_pin_to_mask(CREATE_IOPORT_PIN(PORTA,24)); //pio_set_input(PIOA,ul_mask, PIO_PULLUP|PIO_DEBOUNCE); mico_gpio_enable_IRQ( (mico_gpio_t)MICO_GPIO_9, IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, NULL ); #ifndef HARD_CS_NSS0 mico_gpio_initialize( MICO_GPIO_15, OUTPUT_PUSH_PULL);//spi ss/cs mico_gpio_output_high( MICO_GPIO_15 );//MICO_GPIO_15 TBD! #else ioport_set_pin_peripheral_mode(SPI_NPCS0_GPIO, SPI_NPCS0_FLAGS);//TBD! #endif /* set PORTB 01 to high to put WLAN module into g_SPI mode */ mico_gpio_initialize( (mico_gpio_t)WL_GPIO0, OUTPUT_PUSH_PULL ); mico_gpio_output_high( (mico_gpio_t)WL_GPIO0 ); #ifdef USE_OWN_SPI_DRV #if (SAMG55) /* Enable the peripheral and set SPI mode. */ flexcom_enable(BOARD_FLEXCOM_SPI); flexcom_set_opmode(BOARD_FLEXCOM_SPI, FLEXCOM_SPI); #else /* Configure an SPI peripheral. */ pmc_enable_periph_clk(SPI_ID); #endif //Init pdc, and clear RX TX. spi_m_pdc = spi_get_pdc_base(SPI_MASTER_BASE); pdc_spi_packet.ul_addr = NULL; pdc_spi_packet.ul_size = 3; pdc_tx_init(spi_m_pdc, &pdc_spi_packet, NULL); pdc_rx_init(spi_m_pdc, &pdc_spi_packet, NULL); spi_disable(SPI_MASTER_BASE); spi_reset(SPI_MASTER_BASE); spi_set_lastxfer(SPI_MASTER_BASE); spi_set_master_mode(SPI_MASTER_BASE); spi_disable_mode_fault_detect(SPI_MASTER_BASE); #ifdef HARD_CS_NSS0 //spi_enable_peripheral_select_decode(SPI_MASTER_BASE); //spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_SEL); spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_PCS); //use soft nss comment here #endif spi_set_clock_polarity(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY); spi_set_clock_phase(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE); spi_set_bits_per_transfer(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(SPI_MASTER_BASE, SPI_CHIP_SEL, (sysclk_get_cpu_hz() / SPI_BAUD_RATE)); spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS, SPI_DLYBCT); /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */ /* otherwise FreeRTOS will not be able to mask the interrupt */ /* keep in mind that ARMCM3 interrupt priority logic is inverted, the highest value */ /* is the lowest priority */ /* Configure SPI interrupts . */ spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_RXBUFF); //spi_enable_interrupt(SPI_MASTER_BASE, SPI_IER_NSSR | SPI_IER_RXBUFF); NVIC_DisableIRQ(SPI_IRQn); //irq_register_handler(SPI_IRQn, 3); NVIC_ClearPendingIRQ(SPI_IRQn); NVIC_SetPriority(SPI_IRQn, 3); NVIC_EnableIRQ(SPI_IRQn); spi_enable(SPI_MASTER_BASE); #else spi.baudrate = SPI_BAUD_RATE; if (STATUS_OK != spi_master_vec_init(&spi_master, SPI_MASTER_BASE, &spi)) { return -1; } spi_master_vec_enable(&spi_master); #endif //if (!Is_global_interrupt_enabled()) // Enable_global_interrupt(); MCU_CLOCKS_NOT_NEEDED(); return kNoErr; }
OSStatus host_platform_sdio_transfer( bus_transfer_direction_t direction, sdio_command_t command, sdio_transfer_mode_t mode, sdio_block_size_t block_size, uint32_t argument, /*@null@*/ uint32_t* data, uint16_t data_size, sdio_response_needed_t response_expected, /*@out@*/ /*@null@*/ uint32_t* response ) { UNUSED_PARAMETER(mode); OSStatus result = kNoErr; uint16_t attempts = 0; uint8_t response_full[6]; uint32_t blockNumber, blockIdx; bool status; check_string(!((command == SDIO_CMD_53) && (data == NULL)), "Bad args" ); if ( response != NULL ) { *response = 0; } MCU_CLOCKS_NEEDED(); restart: // SDIO->ICR = (uint32_t) 0xFFFFFFFF; ++attempts; /* Check if we've tried too many times */ if (attempts >= (uint16_t) BUS_LEVEL_MAX_RETRIES) { result = kGeneralErr; platform_log("SDIO error!"); mico_thread_sleep(0xFFFFFFFF); goto exit; } /* Prepare the data transfer register */ if ( command == SDIO_CMD_53 ) { if ( direction == BUS_READ ) { if(mode == SDIO_BYTE_MODE) SdioStartReciveData((uint8_t*)data, data_size); else SdioStartReciveData((uint8_t*)data, block_size); //require_noerr_quiet(SdioSendCommand(command, argument, 2), restart); SdioDataInterruptEn(); waiting = true; status = SdioSendCommand(command, argument, 1); if(status != 0){ goto restart; } result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); waiting = false; if ( result != kNoErr ) { printf("@@, %d", data_size); //SdioDataInterruptDis(); goto restart; } //while(!SdioIsDatTransDone()); if(mode == SDIO_BLOCK_MODE){ blockNumber = argument & (uint32_t) ( 0x1FF ) ; for( blockIdx = 1; blockIdx < blockNumber; blockIdx++ ){ SdioStartReciveData( (uint8_t *)data + blockIdx * block_size, block_size); waiting = true; result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); waiting = false; if ( result != kNoErr ) { printf("@, %d", data_size); //SdioDataInterruptDis(); goto restart; } //while(!SdioIsDatTransDone()); } } SdioEndDatTrans(); SdioDataInterruptDis(); //memcpy( data, temp_dma_buffer, (size_t) data_size ); }else{ //memcpy(temp_dma_buffer, data, data_size); //require_noerr_quiet(SdioSendCommand(command, argument, 2), restart); status = SdioSendCommand(command, argument, 1); if(status != 0){ goto restart; } SdioDataInterruptEn(); if(mode == SDIO_BYTE_MODE){ waiting = true; SdioStartSendData((uint8_t *)data, data_size); result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); waiting = false; if ( result != kNoErr ) { printf("$, %d", data_size); //SdioDataInterruptDis(); goto restart; } //while(!SdioIsDatTransDone()); }else{ blockNumber = argument & (uint32_t) ( 0x1FF ) ; for( blockIdx = 0; blockIdx < blockNumber; blockIdx++ ){ SdioStartSendData( (uint8_t *)data + blockIdx * block_size, block_size); waiting = true; result = mico_rtos_get_semaphore( &sdio_transfer_finished_semaphore, (uint32_t) 50 ); waiting = false; if ( result != kNoErr ) { printf("-, %d", data_size); //SdioDataInterruptDis(); goto restart; } //while(!SdioIsDatTransDone()); } } SdioEndDatTrans(); SdioDataInterruptDis(); } } else { status = SdioSendCommand(command, argument, 50); if( response_expected == RESPONSE_NEEDED && status != 0 ) { goto restart; } } if ( response != NULL ) { SdioGetCmdResp(response_full, 6); *response = hton32(*(uint32_t *)&response_full[1]); } result = kNoErr; exit: MCU_CLOCKS_NOT_NEEDED(); return result; }
OSStatus host_platform_bus_init( void ) { SPI_InitTypeDef spi_init; DMA_InitTypeDef dma_init_structure; GPIO_InitTypeDef gpio_init_structure; NVIC_InitTypeDef nvic_init_structure; MCU_CLOCKS_NEEDED(); mico_rtos_init_semaphore(&spi_transfer_finished_semaphore, 1); /* Enable SPI_SLAVE DMA clock */ RCC_AHB1PeriphClockCmd( SPIX_DMA_CLK, ENABLE ); /* Enable SPI_SLAVE Periph clock */ SPIX_CLK_FUNCTION( SPIX_CLK, ENABLE ); /* Enable GPIO Bank B & C */ RCC_AHB1PeriphClockCmd( SPI_BUS_CLOCK_BANK_CLK | SPI_BUS_MISO_BANK_CLK | SPI_BUS_MOSI_BANK_CLK | SPI_BUS_CS_BANK_CLK | SPI_IRQ_CLK, ENABLE ); /* Enable SYSCFG. Needed for selecting EXTI interrupt line */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG, ENABLE ); /* Setup the interrupt input for WLAN_IRQ */ gpio_init_structure.GPIO_Mode = GPIO_Mode_IN; gpio_init_structure.GPIO_PuPd = GPIO_PuPd_NOPULL; gpio_init_structure.GPIO_Speed = GPIO_Speed_100MHz; gpio_init_structure.GPIO_Pin = ( 1 << SPI_IRQ_PIN ); GPIO_Init( SPI_IRQ_BANK, &gpio_init_structure ); gpio_irq_enable(SPI_IRQ_BANK, SPI_IRQ_PIN, IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0); /* Setup the SPI lines */ /* Setup SPI slave select GPIOs */ gpio_init_structure.GPIO_Mode = GPIO_Mode_AF; gpio_init_structure.GPIO_OType = GPIO_OType_PP; gpio_init_structure.GPIO_Speed = GPIO_Speed_100MHz; gpio_init_structure.GPIO_Pin = ( 1 << SPI_BUS_CLOCK_PIN ) | ( 1 << SPI_BUS_MISO_PIN ) | ( 1 << SPI_BUS_MOSI_PIN ); GPIO_Init( SPI_BUS_CLOCK_BANK, &gpio_init_structure ); GPIO_PinAFConfig( SPI_BUS_CLOCK_BANK, SPI_BUS_CLOCK_PIN, SPIX_AF ); GPIO_PinAFConfig( SPI_BUS_MISO_BANK, SPI_BUS_MISO_PIN, SPIX_AF ); GPIO_PinAFConfig( SPI_BUS_MOSI_BANK, SPI_BUS_MOSI_PIN, SPIX_AF ); /* Setup SPI slave select GPIOs */ gpio_init_structure.GPIO_Mode = GPIO_Mode_OUT; gpio_init_structure.GPIO_OType = GPIO_OType_PP; gpio_init_structure.GPIO_Speed = GPIO_Speed_100MHz; gpio_init_structure.GPIO_Pin = ( 1 << SPI_BUS_CS_PIN ); GPIO_Init( SPI_BUS_CS_BANK, &gpio_init_structure ); GPIO_SetBits( SPI_BUS_CS_BANK, ( 1 << SPI_BUS_CS_PIN ) ); /* Set CS high (disabled) */ /* Set GPIO_B[1:0] to 01 to put WLAN module into gSPI mode */ MicoGpioInitialize( (mico_gpio_t)WL_GPIO0, OUTPUT_PUSH_PULL ); MicoGpioOutputHigh( (mico_gpio_t)WL_GPIO0 ); MicoGpioInitialize( (mico_gpio_t)WL_GPIO1, OUTPUT_PUSH_PULL ); MicoGpioOutputLow( (mico_gpio_t)WL_GPIO1 ); /* Setup DMA for SPIX RX */ DMA_DeInit( SPIX_DMA_RX_STREAM ); dma_init_structure.DMA_Channel = SPIX_DMA_RX_CHANNEL; dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t) &SPIX->DR; dma_init_structure.DMA_Memory0BaseAddr = 0; dma_init_structure.DMA_DIR = DMA_DIR_PeripheralToMemory; dma_init_structure.DMA_BufferSize = 0; dma_init_structure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma_init_structure.DMA_MemoryInc = DMA_MemoryInc_Enable; dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma_init_structure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma_init_structure.DMA_Mode = DMA_Mode_Normal; dma_init_structure.DMA_Priority = DMA_Priority_VeryHigh; dma_init_structure.DMA_FIFOMode = DMA_FIFOMode_Disable; dma_init_structure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; dma_init_structure.DMA_MemoryBurst = DMA_MemoryBurst_Single; dma_init_structure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init( SPIX_DMA_RX_STREAM, &dma_init_structure ); /* Setup DMA for SPIX TX */ DMA_DeInit( SPIX_DMA_TX_STREAM ); dma_init_structure.DMA_Channel = SPIX_DMA_TX_CHANNEL; dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t) &SPIX->DR; dma_init_structure.DMA_Memory0BaseAddr = 0; dma_init_structure.DMA_DIR = DMA_DIR_MemoryToPeripheral; dma_init_structure.DMA_BufferSize = 0; dma_init_structure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma_init_structure.DMA_MemoryInc = DMA_MemoryInc_Enable; dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma_init_structure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma_init_structure.DMA_Mode = DMA_Mode_Normal; dma_init_structure.DMA_Priority = DMA_Priority_VeryHigh; dma_init_structure.DMA_FIFOMode = DMA_FIFOMode_Disable; dma_init_structure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; dma_init_structure.DMA_MemoryBurst = DMA_MemoryBurst_Single; dma_init_structure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init( SPIX_DMA_TX_STREAM, &dma_init_structure ); /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */ /* otherwise FreeRTOS will not be able to mask the interrupt */ /* keep in mind that ARMCM3 interrupt priority logic is inverted, the highest value */ /* is the lowest priority */ nvic_init_structure.NVIC_IRQChannel = SPIX_DMA_RX_IRQ_CHANNEL; nvic_init_structure.NVIC_IRQChannelPreemptionPriority = (uint8_t) 0x3; nvic_init_structure.NVIC_IRQChannelSubPriority = 0x0; nvic_init_structure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &nvic_init_structure ); DMA_ITConfig(SPIX_DMA_RX_STREAM, DMA_IT_TC, ENABLE); /* Enable DMA for TX */ SPI_I2S_DMACmd( SPIX, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE ); /* Setup SPI */ spi_init.SPI_Direction = SPI_Direction_2Lines_FullDuplex; spi_init.SPI_Mode = SPI_Mode_Master; spi_init.SPI_DataSize = SPI_DataSize_8b; spi_init.SPI_CPOL = SPI_CPOL_High; spi_init.SPI_CPHA = SPI_CPHA_2Edge; spi_init.SPI_NSS = SPI_NSS_Soft; spi_init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; spi_init.SPI_FirstBit = SPI_FirstBit_MSB; spi_init.SPI_CRCPolynomial = (uint16_t) 7; /* Init SPI and enable it */ SPI_Init( SPIX, &spi_init ); SPI_Cmd( SPIX, ENABLE ); MCU_CLOCKS_NOT_NEEDED(); return kNoErr; }