/** * \internal * \brief Initialize Proxy PLC controller. * * This function will change the system clock prescaler configuration to * match the parameters. * * \note The parameters to this function are device-specific. * */ static void _pplc_if_config(void) { uint32_t ul_cpuhz; uint8_t uc_div; ul_cpuhz = sysclk_get_cpu_hz(); uc_div = ul_cpuhz / gs_ul_pplc_clock; /* Enable SPI peripheral. */ spi_enable_clock(PPLC_SPI_MODULE); /* Reset SPI */ spi_disable(PPLC_SPI_MODULE); spi_reset(PPLC_SPI_MODULE); /* Configure SPI */ spi_set_master_mode(PPLC_SPI_MODULE); spi_disable_mode_fault_detect(PPLC_SPI_MODULE); spi_set_peripheral_chip_select_value(PPLC_SPI_MODULE, PPLC_PCS); spi_set_clock_polarity(PPLC_SPI_MODULE, PPLC_CS, 0); spi_set_clock_phase(PPLC_SPI_MODULE, PPLC_CS, 1); spi_set_bits_per_transfer(PPLC_SPI_MODULE, PPLC_CS, SPI_CSR_BITS_8_BIT); spi_set_fixed_peripheral_select(PPLC_SPI_MODULE); spi_set_baudrate_div(PPLC_SPI_MODULE, PPLC_CS, uc_div); spi_set_transfer_delay(PPLC_SPI_MODULE, PPLC_CS, PPLC_DLYBS, PPLC_DLYBCT); spi_configure_cs_behavior(PPLC_SPI_MODULE, PPLC_CS, SPI_CS_RISE_NO_TX); /* Get board PPLC PDC base address and enable receiver and transmitter */ g_pplc_pdc = spi_get_pdc_base(PPLC_SPI_MODULE); spi_enable(PPLC_SPI_MODULE); }
void platform_wifi_spi_rx_dma_irq(void) { uint8_t junk1; uint16_t junk2; pdc_packet_t pdc_spi_packet = { 0, 1 }; Pdc* spi_pdc = spi_get_pdc_base( wifi_spi.port ); uint32_t status = spi_read_status( wifi_spi.port ); uint32_t mask = spi_read_interrupt_mask( wifi_spi.port ); if ( ( mask & SPI_IMR_RXBUFF ) && ( status & SPI_SR_RXBUFF ) ) { pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS ); pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL ); pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); spi_disable_interrupt( wifi_spi.port, SPI_IER_RXBUFF ); } if ( ( mask & SPI_IMR_ENDTX ) && ( status & SPI_SR_ENDTX ) ) { pdc_disable_transfer( spi_pdc, PERIPH_PTCR_TXTDIS ); pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); spi_disable_interrupt( wifi_spi.port, SPI_IER_ENDTX ); /* Clear SPI RX data in a SPI send sequence */ spi_read( wifi_spi.port, &junk2, &junk1); } mico_rtos_set_semaphore( &spi_transfer_finished_semaphore ); }
platform_result_t sam4s_spi_transfer_internal( const platform_spi_t* spi, const uint8_t* data_out, uint8_t* data_in, uint32_t data_length ) { Pdc* spi_pdc = spi_get_pdc_base( spi->peripheral ); pdc_packet_t pdc_spi_packet; pdc_spi_packet.ul_addr = (uint32_t)data_in; pdc_spi_packet.ul_size = (uint32_t)data_length; pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL ); pdc_spi_packet.ul_addr = (uint32_t)data_out; pdc_spi_packet.ul_size = (uint32_t)data_length; pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); /* Enable the RX and TX PDC transfer requests */ pdc_enable_transfer( spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN ); /* Waiting transfer done*/ while ( ( spi_read_status( spi->peripheral ) & SPI_SR_RXBUFF ) == 0 ) { } /* Disable the RX and TX PDC transfer requests */ pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); return PLATFORM_SUCCESS; }
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length ) { OSStatus result; pdc_packet_t pdc_spi_packet = { (uint32_t)buffer, buffer_length }; Pdc* spi_pdc = spi_get_pdc_base( wifi_spi.port ); platform_mcu_powersave_disable(); platform_gpio_output_low( &wifi_spi_pins[WIFI_PIN_SPI_CS] ); pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL); if ( dir == BUS_READ ) { pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL); spi_enable_interrupt(wifi_spi.port, SPI_IER_RXBUFF ); pdc_enable_transfer( spi_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN ); } if ( dir == BUS_WRITE ) { spi_enable_interrupt( wifi_spi.port, SPI_IER_ENDTX ); pdc_enable_transfer( spi_pdc, PERIPH_PTCR_TXTEN ); } result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 ); platform_gpio_output_high( &wifi_spi_pins[WIFI_PIN_SPI_CS] ); platform_mcu_powersave_enable(); return result; }
OSStatus host_platform_bus_deinit( void ) { platform_mcu_powersave_disable( ); NVIC_DisableIRQ( platform_flexcom_irq_numbers[wifi_spi.spi_id] ); pdc_disable_transfer( spi_get_pdc_base( wifi_spi.port ), PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS ); spi_disable(wifi_spi.port); /* Deinit the SPI lines */ platform_gpio_peripheral_pin_init( wifi_spi.mosi_pin, INPUT_HIGH_IMPEDANCE ); platform_gpio_peripheral_pin_init( wifi_spi.miso_pin, INPUT_HIGH_IMPEDANCE ); platform_gpio_peripheral_pin_init( wifi_spi.clock_pin, INPUT_HIGH_IMPEDANCE ); /* Deinit the interrupt input for WLAN_IRQ */ platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE ); platform_gpio_irq_disable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ] ); /* Deinit SPI slave select GPIOs */ platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], INPUT_HIGH_IMPEDANCE ); #if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP ) platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], INPUT_HIGH_IMPEDANCE ); platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], INPUT_HIGH_IMPEDANCE ); #endif platform_mcu_powersave_enable( ); return kNoErr; }
platform_result_t platform_spi_init( const platform_spi_t* spi, const platform_spi_config_t* config ) { UNUSED_PARAMETER(spi); UNUSED_PARAMETER(config); platform_mcu_powersave_disable( ); Pdc* spi_pdc = spi_get_pdc_base( spi->peripheral ); /* Setup chip select pin */ platform_gpio_init( config->chip_select, OUTPUT_PUSH_PULL ); platform_gpio_output_high( config->chip_select ); /* Setup other pins */ platform_gpio_peripheral_pin_init( spi->mosi_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) ); platform_gpio_peripheral_pin_init( spi->miso_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) ); platform_gpio_peripheral_pin_init( spi->clk_pin, ( IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP ) ); /* Configure an SPI peripheral. */ pmc_enable_periph_clk( spi->peripheral_id ); spi_disable( spi->peripheral ); spi_reset( spi->peripheral ); spi_set_lastxfer( spi->peripheral ); spi_set_master_mode( spi->peripheral ); spi_disable_mode_fault_detect( spi->peripheral ); spi_set_peripheral_chip_select_value( spi->peripheral, 0 ); spi_set_clock_polarity( spi->peripheral, 0, ( ( config->mode && SPI_CLOCK_IDLE_HIGH ) ? (1) : (0) ) ); spi_set_clock_phase( spi->peripheral, 0, ( ( config->mode && SPI_CLOCK_RISING_EDGE ) ? (1) : (0) ) ); spi_set_bits_per_transfer( spi->peripheral, 0, SPI_CSR_BITS_8_BIT ); spi_set_baudrate_div( spi->peripheral, 0, (uint8_t)( CPU_CLOCK_HZ / config->speed ) ); spi_set_transfer_delay( spi->peripheral, 0, 0, 0 ); spi_enable( spi->peripheral ); pdc_disable_transfer( spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS ); platform_mcu_powersave_enable( ); return PLATFORM_SUCCESS; }
/** * \brief Initialize SPI as master. */ static void spi_master_initialize(void) { uint32_t i; puts("-I- Initialize SPI as master\r"); for (i = 0; i < COMM_BUFFER_SIZE; i++) { gs_uc_spi_m_tbuffer[i] = i; } /* Get pointer to SPI master PDC register base */ g_p_spim_pdc = spi_get_pdc_base(SPI_MASTER_BASE); #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 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); spi_set_peripheral_chip_select_value(SPI_MASTER_BASE, SPI_CHIP_SEL); 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() / gs_ul_spi_clock)); spi_set_transfer_delay(SPI_MASTER_BASE, SPI_CHIP_SEL, SPI_DLYBS, SPI_DLYBCT); spi_enable(SPI_MASTER_BASE); pdc_disable_transfer(g_p_spim_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); }
/** * \brief Initialize SPI as slave. */ static void spi_slave_initialize(void) { uint32_t i; /* Get pointer to SPI slave PDC register base */ g_p_spis_pdc = spi_get_pdc_base(SPI_MASTER_BASE); puts("-I- Initialize SPI as slave \r"); for (i = 0; i < COMM_BUFFER_SIZE; i++) { gs_uc_spi_s_tbuffer[i] = i; } #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 spi_disable(SPI_SLAVE_BASE); spi_reset(SPI_SLAVE_BASE); spi_set_slave_mode(SPI_SLAVE_BASE); spi_disable_mode_fault_detect(SPI_SLAVE_BASE); spi_set_peripheral_chip_select_value(SPI_SLAVE_BASE, SPI_CHIP_SEL); spi_set_clock_polarity(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY); spi_set_clock_phase(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE); spi_set_bits_per_transfer(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT); spi_enable(SPI_SLAVE_BASE); pdc_disable_transfer(g_p_spis_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); spi_slave_transfer(gs_uc_spi_s_tbuffer, COMM_BUFFER_SIZE, gs_uc_spi_s_rbuffer, COMM_BUFFER_SIZE); }
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; }
/** * \brief Set a given number of pixels to the same color * * Use this function to write a certain number of pixels to the same color * within a set limit. * * Limits have to be set prior to calling this function, e.g.: * \code * ili9341_set_top_left_limit(0, 0); * ili9341_set_bottom_right_limit(320, 240); * ... * \endcode * * \param color The color to write to the display * \param count The number of pixels to write with this color */ void ili9341_duplicate_pixel(const ili9341_color_t color, uint32_t count) { /* Sanity check to make sure that the pixel count is not zero */ Assert(count > 0); ili9341_send_command(ILI9341_CMD_MEMORY_WRITE); #if defined(ILI9341_DMA_ENABLED) ili9341_color_t chunk_buf[ILI9341_DMA_CHUNK_SIZE]; uint32_t chunk_len; # if SAM Pdc *SPI_DMA = spi_get_pdc_base(CONF_ILI9341_SPI); pdc_packet_t spi_pdc_data; pdc_enable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN); spi_pdc_data.ul_addr = (uint32_t)chunk_buf; # elif UC3 pdca_set_transfer_size(CONF_ILI9341_PDCA_CHANNEL, PDCA_TRANSFER_SIZE_BYTE); pdca_set_peripheral_select(CONF_ILI9341_PDCA_CHANNEL, CONF_ILI9341_PDCA_PID); # endif for (uint32_t i = 0; i < ILI9341_DMA_CHUNK_SIZE; i++) { chunk_buf[i] = le16_to_cpu(color); } while (count) { chunk_len = min(ILI9341_DMA_CHUNK_SIZE, count); ili9341_wait_for_send_done(); # if SAM spi_pdc_data.ul_size = (uint32_t)sizeof(ili9341_color_t) * chunk_len; pdc_tx_init(SPI_DMA, NULL, &spi_pdc_data); # elif UC3 pdca_reload_channel(CONF_ILI9341_PDCA_CHANNEL, chunk_buf, (uint32_t)sizeof(ili9341_color_t) * chunk_len); pdca_enable(CONF_ILI9341_PDCA_CHANNEL); # endif count -= chunk_len; } ili9341_wait_for_send_done(); ili9341_deselect_chip(); # if SAM pdc_disable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN); # elif UC3 pdca_disable(CONF_ILI9341_PDCA_CHANNEL); # endif #else while (count--) { ili9341_send_byte(color); ili9341_send_byte(color >> 8); } ili9341_wait_for_send_done(); ili9341_deselect_chip(); #endif }
/** * \brief Copy pixels from SRAM to the screen * * Used to copy a large quantitative of data to the screen in one go. * * Limits have to be set prior to calling this function, e.g.: * \code * ili9341_set_top_left_limit(0, 0); * ili9341_set_bottom_right_limit(320, 240); * ... * \endcode * * \param pixels Pointer to the pixel data * \param count Number of pixels to copy to the screen */ void ili9341_copy_pixels_to_screen(const ili9341_color_t *pixels, uint32_t count) { const ili9341_color_t *pixel = pixels; /* Sanity check to make sure that the pixel count is not zero */ Assert(count > 0); ili9341_send_command(ILI9341_CMD_MEMORY_WRITE); #if defined(ILI9341_DMA_ENABLED) ili9341_color_t chunk_buf[ILI9341_DMA_CHUNK_SIZE]; uint32_t chunk_len; # if SAM Pdc *SPI_DMA = spi_get_pdc_base(CONF_ILI9341_SPI); pdc_packet_t spi_pdc_data; pdc_enable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN); spi_pdc_data.ul_addr = (uint32_t)chunk_buf; # elif UC3 pdca_set_transfer_size(CONF_ILI9341_PDCA_CHANNEL, PDCA_TRANSFER_SIZE_BYTE); pdca_set_peripheral_select(CONF_ILI9341_PDCA_CHANNEL, CONF_ILI9341_PDCA_PID); # endif while (count) { /* We need to copy out the data to send in chunks into RAM, as the PDC * does not allow FLASH->Peripheral transfers */ chunk_len = min(ILI9341_DMA_CHUNK_SIZE, count); /* Wait for pending transfer to complete */ ili9341_wait_for_send_done(); for (uint32_t i = 0; i < chunk_len; i++) { chunk_buf[i] = le16_to_cpu(pixel[i]); } # if SAM spi_pdc_data.ul_size = (uint32_t)sizeof(ili9341_color_t) * chunk_len; pdc_tx_init(SPI_DMA, NULL, &spi_pdc_data); # elif UC3 pdca_reload_channel(CONF_ILI9341_PDCA_CHANNEL, chunk_buf, (uint32_t)sizeof(ili9341_color_t) * chunk_len); pdca_enable(CONF_ILI9341_PDCA_CHANNEL); # endif pixel += chunk_len; count -= chunk_len; } ili9341_wait_for_send_done(); ili9341_deselect_chip(); # if SAM pdc_disable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN); # elif UC3 pdca_disable(CONF_ILI9341_PDCA_CHANNEL); # endif #else while (count--) { ili9341_send_byte(*pixel); ili9341_send_byte(*pixel >> 8); pixel++; } ili9341_wait_for_send_done(); ili9341_deselect_chip(); #endif }
/** * \brief KSZ8851SNL initialization function. * * \return 0 on success, 1 on communication error. */ uint32_t ksz8851snl_init(void) { uint32_t count = 0; uint16_t dev_id = 0; /* Configure the SPI peripheral. */ spi_enable_clock(KSZ8851SNL_SPI); spi_disable(KSZ8851SNL_SPI); spi_reset(KSZ8851SNL_SPI); spi_set_master_mode(KSZ8851SNL_SPI); spi_disable_mode_fault_detect(KSZ8851SNL_SPI); spi_set_peripheral_chip_select_value(KSZ8851SNL_SPI, ~(uint32_t)(1 << KSZ8851SNL_CS_PIN)); spi_set_clock_polarity(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CLK_POLARITY); spi_set_clock_phase(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CLK_PHASE); spi_set_bits_per_transfer(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, (sysclk_get_cpu_hz() / KSZ8851SNL_CLOCK_SPEED)); spi_set_transfer_delay(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, CONFIG_SPI_MASTER_DELAY_BS, CONFIG_SPI_MASTER_DELAY_BCT); spi_enable(KSZ8851SNL_SPI); /* Get pointer to UART PDC register base. */ g_p_spi_pdc = spi_get_pdc_base(KSZ8851SNL_SPI); pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); /* Control RSTN and CSN pin from the driver. */ gpio_configure_pin(KSZ8851SNL_CSN_GPIO, KSZ8851SNL_CSN_FLAGS); gpio_set_pin_high(KSZ8851SNL_CSN_GPIO); gpio_configure_pin(KSZ8851SNL_RSTN_GPIO, KSZ8851SNL_RSTN_FLAGS); /* Reset the Micrel in a proper state. */ do { /* Perform hardware reset with respect to the reset timing from the datasheet. */ gpio_set_pin_low(KSZ8851SNL_RSTN_GPIO); delay_ms(100); gpio_set_pin_high(KSZ8851SNL_RSTN_GPIO); delay_ms(100); /* Init step1: read chip ID. */ dev_id = ksz8851_reg_read(REG_CHIP_ID); if (++count > 10) return 1; } while ((dev_id & 0xFFF0) != CHIP_ID_8851_16); /* Init step2-4: write QMU MAC address (low, middle then high). */ ksz8851_reg_write(REG_MAC_ADDR_0, (ETHERNET_CONF_ETHADDR4 << 8) | ETHERNET_CONF_ETHADDR5); ksz8851_reg_write(REG_MAC_ADDR_2, (ETHERNET_CONF_ETHADDR2 << 8) | ETHERNET_CONF_ETHADDR3); ksz8851_reg_write(REG_MAC_ADDR_4, (ETHERNET_CONF_ETHADDR0 << 8) | ETHERNET_CONF_ETHADDR1); /* Init step5: enable QMU Transmit Frame Data Pointer Auto Increment. */ ksz8851_reg_write(REG_TX_ADDR_PTR, ADDR_PTR_AUTO_INC); /* Init step6: configure QMU transmit control register. */ ksz8851_reg_write(REG_TX_CTRL, TX_CTRL_ICMP_CHECKSUM | TX_CTRL_UDP_CHECKSUM | TX_CTRL_TCP_CHECKSUM | TX_CTRL_IP_CHECKSUM | TX_CTRL_FLOW_ENABLE | TX_CTRL_PAD_ENABLE | TX_CTRL_CRC_ENABLE ); /* Init step7: enable QMU Receive Frame Data Pointer Auto Increment. */ ksz8851_reg_write(REG_RX_ADDR_PTR, ADDR_PTR_AUTO_INC); /* Init step8: configure QMU Receive Frame Threshold for one frame. */ ksz8851_reg_write(REG_RX_FRAME_CNT_THRES, 1); /* Init step9: configure QMU receive control register1. */ ksz8851_reg_write(REG_RX_CTRL1, RX_CTRL_UDP_CHECKSUM | RX_CTRL_TCP_CHECKSUM | RX_CTRL_IP_CHECKSUM | RX_CTRL_MAC_FILTER | RX_CTRL_FLOW_ENABLE | RX_CTRL_BROADCAST | RX_CTRL_ALL_MULTICAST| RX_CTRL_UNICAST); /* Init step10: configure QMU receive control register2. */ ksz8851_reg_write(REG_RX_CTRL2, RX_CTRL_IPV6_UDP_NOCHECKSUM | RX_CTRL_UDP_LITE_CHECKSUM | RX_CTRL_ICMP_CHECKSUM | RX_CTRL_BURST_LEN_FRAME); /* Init step11: configure QMU receive queue: trigger INT and auto-dequeue frame. */ ksz8851_reg_write(REG_RXQ_CMD, RXQ_CMD_CNTL); /* Init step12: adjust SPI data output delay. */ ksz8851_reg_write(REG_BUS_CLOCK_CTRL, BUS_CLOCK_166 | BUS_CLOCK_DIVIDEDBY_1); /* Init step13: restart auto-negotiation. */ ksz8851_reg_setbits(REG_PORT_CTRL, PORT_AUTO_NEG_RESTART); /* Init step13.1: force link in half duplex if auto-negotiation failed. */ if ((ksz8851_reg_read(REG_PORT_CTRL) & PORT_AUTO_NEG_RESTART) != PORT_AUTO_NEG_RESTART) { ksz8851_reg_clrbits(REG_PORT_CTRL, PORT_FORCE_FULL_DUPLEX); } /* Init step14: clear interrupt status. */ ksz8851_reg_write(REG_INT_STATUS, 0xFFFF); /* Init step15: set interrupt mask. */ ksz8851_reg_write(REG_INT_MASK, INT_RX); /* Init step16: enable QMU Transmit. */ ksz8851_reg_setbits(REG_TX_CTRL, TX_CTRL_ENABLE); /* Init step17: enable QMU Receive. */ ksz8851_reg_setbits(REG_RX_CTRL1, RX_CTRL_ENABLE); return 0; }
OSStatus host_platform_bus_init( void ) { pdc_packet_t pdc_spi_packet; Pdc* spi_pdc = spi_get_pdc_base( wifi_spi.port ); platform_mcu_powersave_disable( ); mico_rtos_init_semaphore( &spi_transfer_finished_semaphore, 1 ); /* Setup the SPI lines */ platform_gpio_peripheral_pin_init( wifi_spi.mosi_pin, ( wifi_spi.mosi_pin_mux_mode | IOPORT_MODE_PULLUP ) ); platform_gpio_peripheral_pin_init( wifi_spi.miso_pin, ( wifi_spi.miso_pin_mux_mode | IOPORT_MODE_PULLUP ) ); platform_gpio_peripheral_pin_init( wifi_spi.clock_pin, ( wifi_spi.clock_pin_mux_mode | IOPORT_MODE_PULLUP ) ); /* Setup the interrupt input for WLAN_IRQ */ platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE ); platform_gpio_irq_enable( &wifi_spi_pins[WIFI_PIN_SPI_IRQ], IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0 ); /* Setup SPI slave select GPIOs */ platform_gpio_init( &wifi_spi_pins[WIFI_PIN_SPI_CS], OUTPUT_PUSH_PULL ); platform_gpio_output_high( &wifi_spi_pins[WIFI_PIN_SPI_CS] ); #if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP ) /* Set GPIO_B[1:0] to 01 to put WLAN module into gSPI mode */ platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL ); platform_gpio_output_high( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] ); platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL ); platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] ); #endif /* Enable the peripheral and set SPI mode. */ flexcom_enable( flexcom_base[ wifi_spi.spi_id ] ); flexcom_set_opmode( flexcom_base[ wifi_spi.spi_id ], FLEXCOM_SPI ); /* Init pdc, and clear RX TX. */ pdc_spi_packet.ul_addr = 0; pdc_spi_packet.ul_size = 1; pdc_tx_init( spi_pdc, &pdc_spi_packet, NULL ); pdc_rx_init( spi_pdc, &pdc_spi_packet, NULL ); spi_disable_interrupt(wifi_spi.port, 0xffffffff ); spi_disable( wifi_spi.port ); spi_reset( wifi_spi.port ); spi_set_lastxfer( wifi_spi.port ); spi_set_master_mode( wifi_spi.port ); spi_disable_mode_fault_detect( wifi_spi.port ); spi_set_clock_polarity( wifi_spi.port, 0, SPI_CLK_POLARITY ); spi_set_clock_phase( wifi_spi.port, 0, SPI_CLK_PHASE ); spi_set_bits_per_transfer( wifi_spi.port, 0, SPI_CSR_BITS_8_BIT ); spi_set_baudrate_div( wifi_spi.port, 0, (sysclk_get_cpu_hz() / SPI_BAUD_RATE) ); spi_set_transfer_delay( wifi_spi.port, 0, 0, 0 ); /* 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 ARMCM4 interrupt priority logic is inverted, the highest value */ /* is the lowest priority */ /* Configure SPI interrupts . */ NVIC_EnableIRQ( platform_flexcom_irq_numbers[wifi_spi.spi_id] ); spi_enable(wifi_spi.port); platform_mcu_powersave_enable( ); return kNoErr; }
/** * \brief KSZ8851SNL initialization function. * * \return 0 on success, 1 on communication error. */ uint32_t ksz8851snl_init(void) { uint32_t count = 10; uint16_t dev_id = 0; uint8_t id_ok = 0; /* Configure the SPI peripheral. */ spi_enable_clock(KSZ8851SNL_SPI); spi_disable(KSZ8851SNL_SPI); spi_reset(KSZ8851SNL_SPI); spi_set_master_mode(KSZ8851SNL_SPI); spi_disable_mode_fault_detect(KSZ8851SNL_SPI); spi_set_peripheral_chip_select_value(KSZ8851SNL_SPI, ~(uint32_t)(1UL << KSZ8851SNL_CS_PIN)); spi_set_fixed_peripheral_select(KSZ8851SNL_SPI); //spi_disable_peripheral_select_decode(KSZ8851SNL_SPI); spi_set_clock_polarity(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CLK_POLARITY); spi_set_clock_phase(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CLK_PHASE); spi_set_bits_per_transfer(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, (sysclk_get_cpu_hz() / KSZ8851SNL_CLOCK_SPEED)); // spi_set_transfer_delay(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, CONFIG_SPI_MASTER_DELAY_BS, // CONFIG_SPI_MASTER_DELAY_BCT); spi_set_transfer_delay(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, 0, 0); spi_enable(KSZ8851SNL_SPI); /* Get pointer to UART PDC register base. */ g_p_spi_pdc = spi_get_pdc_base(KSZ8851SNL_SPI); pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); /* Control RSTN and CSN pin from the driver. */ gpio_configure_pin(KSZ8851SNL_CSN_GPIO, KSZ8851SNL_CSN_FLAGS); gpio_set_pin_high(KSZ8851SNL_CSN_GPIO); gpio_configure_pin(KSZ8851SNL_RSTN_GPIO, KSZ8851SNL_RSTN_FLAGS); /* Reset the Micrel in a proper state. */ while( count-- ) { /* Perform hardware reset with respect to the reset timing from the datasheet. */ gpio_set_pin_low(KSZ8851SNL_RSTN_GPIO); vTaskDelay(2); gpio_set_pin_high(KSZ8851SNL_RSTN_GPIO); vTaskDelay(2); /* Init step1: read chip ID. */ dev_id = ksz8851_reg_read(REG_CHIP_ID); if( ( dev_id & 0xFFF0 ) == CHIP_ID_8851_16 ) { id_ok = 1; break; } } if( id_ok != 0 ) { ksz8851snl_set_registers(); } return id_ok ? 1 : -1; }