Browse Source

[bsp][stm32/pandora]增加AP6181移植文件

yangjie 5 years ago
parent
commit
9b889944ba

+ 12 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/SConscript

@@ -0,0 +1,12 @@
+import os
+from building import *
+
+objs = []
+cwd  = GetCurrentDir()
+list = os.listdir(cwd)
+
+for item in list:
+    if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
+        objs = objs + SConscript(os.path.join(item, 'SConscript'))
+
+Return('objs')

+ 194 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/drv_sdio_adapter.c

@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <drivers/mmcsd_core.h>
+#include <drivers/sdio.h>
+
+#include "stm32l4xx.h"
+
+#ifdef BSP_USING_STM32_SDIO
+
+#include <stm32_sdio.h>
+
+static DMA_HandleTypeDef SDTxDMAHandler;
+static DMA_HandleTypeDef SDRxDMAHandler;
+
+static struct rt_mmcsd_host *host;
+
+void SDMMC1_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    /* Process All SDIO Interrupt Sources */
+    rthw_sdio_irq_process(host);
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+/**
+  * @brief  Configures the DMA2 Channel4 for SDIO Tx request.
+  * @param  BufferSRC: pointer to the source buffer
+  * @param  BufferSize: buffer size
+  * @retval None
+  */
+void SD_LowLevel_DMA_TxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
+{
+    DMA2_Channel4->CCR &= ~0x00000001;
+
+    DMA2->IFCR = DMA_ISR_GIF1 << 4;
+    
+    DMA2_CSELR->CSELR &= ~(0xf << (3 * 4));   // channel 4
+    DMA2_CSELR->CSELR |= (uint32_t) (0x07 << (3 * 4)); 
+    
+    DMA2_Channel4->CCR   = DMA_MEMORY_TO_PERIPH | DMA_PINC_DISABLE | DMA_MINC_ENABLE | \
+                           DMA_PDATAALIGN_WORD | DMA_MDATAALIGN_WORD | DMA_NORMAL | DMA_PRIORITY_MEDIUM;
+    DMA2_Channel4->CNDTR = BufferSize;
+    DMA2_Channel4->CPAR  = (uint32_t)dst;
+    DMA2_Channel4->CMAR = (uint32_t)src;
+
+    DMA2_Channel4->CCR  |= 0x00000001;
+    
+//    HAL_DMA_Start(&SDTxDMAHandler, (uint32_t)src, (uint32_t)dst, BufferSize);
+}
+
+/**
+  * @brief  Configures the DMA2 Channel4 for SDIO Rx request.
+  * @param  BufferDST: pointer to the destination buffer
+  * @param  BufferSize: buffer size
+  * @retval None
+  */
+void SD_LowLevel_DMA_RxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
+{
+
+    DMA2_Channel4->CCR &= ~0x00000001;
+
+    DMA2->IFCR = DMA_ISR_GIF1 << 4;
+    
+    DMA2_CSELR->CSELR &= ~(0xf << (3 * 4));   // channel 4
+    DMA2_CSELR->CSELR |= (uint32_t) (0x07 << (3 * 4)); 
+
+    DMA2_Channel4->CCR   = DMA_PERIPH_TO_MEMORY | DMA_PINC_DISABLE | DMA_MINC_ENABLE | \
+                           DMA_PDATAALIGN_WORD | DMA_MDATAALIGN_WORD | DMA_NORMAL | DMA_PRIORITY_MEDIUM;
+    DMA2_Channel4->CNDTR = BufferSize;
+    DMA2_Channel4->CPAR  = (uint32_t)src;
+    DMA2_Channel4->CMAR = (uint32_t)dst;
+
+    DMA2_Channel4->CCR  |= 0x00000001;
+}
+
+void SD_LowLevel_Init(void)
+{
+    {
+        // clock enable
+        __HAL_RCC_GPIOB_CLK_ENABLE();
+        __HAL_RCC_GPIOC_CLK_ENABLE();
+        __HAL_RCC_GPIOD_CLK_ENABLE();
+        __HAL_RCC_DMA2_CLK_ENABLE();
+        __HAL_RCC_SDMMC1_CLK_ENABLE();
+    }
+
+    {
+        HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
+    }
+
+    {
+        // init sdio hardware
+        GPIO_InitTypeDef GPIO_InitStruct;
+
+        /*Configure GPIO pin Output Level */
+        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET);
+        GPIO_InitStruct.Pin = GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+        GPIO_InitStruct.Pull = GPIO_NOPULL;
+        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+        HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+        rt_thread_delay(1);
+        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET);
+
+        /* Setup GPIO pins for SDIO data & clock */
+        /**SDMMC1 GPIO Configuration
+        PC8     ------> SDMMC1_D0
+        PC9     ------> SDMMC1_D1
+        PC10     ------> SDMMC1_D2
+        PC11     ------> SDMMC1_D3
+        PC12     ------> SDMMC1_CK
+        PD2     ------> SDMMC1_CMD
+        */
+        GPIO_InitStruct.Pin = GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLUP;
+        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
+        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+        
+        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10 | GPIO_PIN_11
+                              | GPIO_PIN_12;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLUP;
+        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
+        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+        GPIO_InitStruct.Pin = GPIO_PIN_2;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLUP;
+        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
+
+        HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+    }
+
+    {
+    }
+}
+
+static rt_uint32_t stm32_sdio_clock_get(struct stm32_sdio *hw_sdio)
+{
+    return HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
+}
+
+static rt_err_t DMA_TxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size)
+{
+    SD_LowLevel_DMA_TxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
+    return RT_EOK;
+}
+
+static rt_err_t DMA_RxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size)
+{
+    SD_LowLevel_DMA_RxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
+    return RT_EOK;
+}
+
+int stm32f4xx_sdio_init(void)
+{
+    struct stm32_sdio_des sdio_des;
+
+    SD_LowLevel_Init();
+
+    sdio_des.clk_get = stm32_sdio_clock_get;
+    sdio_des.hw_sdio = (struct stm32_sdio *)0x40012800U;
+    sdio_des.rxconfig = DMA_RxConfig;
+    sdio_des.txconfig = DMA_TxConfig;
+
+    host = sdio_host_create(&sdio_des);
+    if (host == RT_NULL)
+    {
+        rt_kprintf("%s host create fail\n");
+        return -1;
+    }
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(stm32f4xx_sdio_init);
+
+#endif

+ 14 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/easyflash/SConscript

@@ -0,0 +1,14 @@
+
+from building import *
+import rtconfig
+
+cwd     = GetCurrentDir()
+
+src = []
+
+src     += Glob('*.c')
+CPPPATH = [cwd]
+
+group = DefineGroup('EasyFlash', src, depend = ['PKG_USING_EASYFLASH'], CPPPATH = CPPPATH)
+
+Return('group')

+ 190 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/easyflash/ef_fal_port.c

@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 
+ */
+
+#include <easyflash.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sfud.h>
+#include <rthw.h>
+#include <rtthread.h>
+#include <fal.h>
+
+/* EasyFlash partition name on FAL partition table */
+#define FAL_EF_PART_NAME               "easyflash"
+
+/* default ENV set for user */
+static const ef_env default_env_set[] = {
+        {"boot_times", "0"}
+};
+
+static char log_buf[RT_CONSOLEBUF_SIZE];
+static struct rt_semaphore env_cache_lock;
+static const struct fal_partition *part = NULL;
+
+/**
+ * Flash port for hardware initialize.
+ *
+ * @param default_env default ENV set for user
+ * @param default_env_size default ENV size
+ *
+ * @return result
+ */
+EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size) {
+    EfErrCode result = EF_NO_ERR;
+
+    *default_env = default_env_set;
+    *default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]);
+
+    rt_sem_init(&env_cache_lock, "env lock", 1, RT_IPC_FLAG_PRIO);
+
+    part = fal_partition_find(FAL_EF_PART_NAME);
+    EF_ASSERT(part);
+
+    return result;
+}
+
+/**
+ * Read data from flash.
+ * @note This operation's units is word.
+ *
+ * @param addr flash address
+ * @param buf buffer to store read data
+ * @param size read bytes size
+ *
+ * @return result
+ */
+EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size) {
+    EfErrCode result = EF_NO_ERR;
+
+    fal_partition_read(part, addr, (uint8_t *)buf, size);
+
+    return result;
+}
+
+/**
+ * Erase data on flash.
+ * @note This operation is irreversible.
+ * @note This operation's units is different which on many chips.
+ *
+ * @param addr flash address
+ * @param size erase bytes size
+ *
+ * @return result
+ */
+EfErrCode ef_port_erase(uint32_t addr, size_t size) {
+    EfErrCode result = EF_NO_ERR;
+
+    /* make sure the start address is a multiple of FLASH_ERASE_MIN_SIZE */
+    EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0);
+
+    if (fal_partition_erase(part, addr, size) < 0)
+    {
+        result = EF_ERASE_ERR;
+    }
+
+    return result;
+}
+/**
+ * Write data to flash.
+ * @note This operation's units is word.
+ * @note This operation must after erase. @see flash_erase.
+ *
+ * @param addr flash address
+ * @param buf the write data buffer
+ * @param size write bytes size
+ *
+ * @return result
+ */
+EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) {
+    EfErrCode result = EF_NO_ERR;
+
+    if (fal_partition_write(part, addr, (uint8_t *)buf, size) < 0)
+    {
+        result = EF_WRITE_ERR;
+    }
+
+    return result;
+}
+
+/**
+ * lock the ENV ram cache
+ */
+void ef_port_env_lock(void) {
+    rt_sem_take(&env_cache_lock, RT_WAITING_FOREVER);
+}
+
+/**
+ * unlock the ENV ram cache
+ */
+void ef_port_env_unlock(void) {
+    rt_sem_release(&env_cache_lock);
+}
+
+/**
+ * This function is print flash debug info.
+ *
+ * @param file the file which has call this function
+ * @param line the line number which has call this function
+ * @param format output format
+ * @param ... args
+ *
+ */
+void ef_log_debug(const char *file, const long line, const char *format, ...) {
+
+#ifdef PRINT_DEBUG
+
+    va_list args;
+
+    /* args point to the first variable parameter */
+    va_start(args, format);
+    ef_print("[Flash] (%s:%ld) ", file, line);
+    /* must use vprintf to print */
+    rt_vsprintf(log_buf, format, args);
+    ef_print("%s", log_buf);
+    va_end(args);
+
+#endif
+
+}
+
+/**
+ * This function is print flash routine info.
+ *
+ * @param format output format
+ * @param ... args
+ */
+void ef_log_info(const char *format, ...) {
+    va_list args;
+
+    /* args point to the first variable parameter */
+    va_start(args, format);
+    ef_print("[Flash] ");
+    /* must use vprintf to print */
+    rt_vsprintf(log_buf, format, args);
+    ef_print("%s", log_buf);
+    va_end(args);
+}
+/**
+ * This function is print flash non-package info.
+ *
+ * @param format output format
+ * @param ... args
+ */
+void ef_print(const char *format, ...) {
+    va_list args;
+
+    /* args point to the first variable parameter */
+    va_start(args, format);
+    /* must use vprintf to print */
+    rt_vsprintf(log_buf, format, args);
+    rt_kprintf("%s", log_buf);
+    va_end(args);
+}

+ 20 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/fal/SConscript

@@ -0,0 +1,20 @@
+
+from building import *
+import rtconfig
+
+cwd     = GetCurrentDir()
+
+src = []
+
+src     += Glob('*.c')
+CPPPATH = [cwd]
+LOCAL_CCFLAGS = ''
+
+if rtconfig.CROSS_TOOL == 'gcc':
+    LOCAL_CCFLAGS += ' -std=c99'
+elif rtconfig.CROSS_TOOL == 'keil':
+    LOCAL_CCFLAGS += ' --c99'
+
+group = DefineGroup('fal', src, depend = ['PKG_USING_FAL'], CPPPATH = CPPPATH, LOCAL_CCFLAGS = LOCAL_CCFLAGS)
+
+Return('group')

+ 44 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/fal/fal_cfg.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-08-21     MurphyZhao   the first version
+ */
+#ifndef _FAL_CFG_H_
+#define _FAL_CFG_H_
+
+#include <rtthread.h>
+#include <board.h>
+
+/* enable stm32l4 onchip flash driver sample */
+#define FAL_FLASH_PORT_DRIVER_STM32L4
+/* enable SFUD flash driver sample */
+#define FAL_FLASH_PORT_DRIVER_SFUD
+
+extern const struct fal_flash_dev stm32_onchip_flash;
+extern const struct fal_flash_dev nor_flash0;
+
+/* flash device table */
+#define FAL_FLASH_DEV_TABLE                                          \
+{                                                                    \
+    &stm32_onchip_flash,                                             \
+    &nor_flash0,                                                     \
+}
+/* ====================== Partition Configuration ========================== */
+#ifdef FAL_PART_HAS_TABLE_CFG
+/* partition table */
+#define FAL_PART_TABLE                                                                                              \
+{                                                                                                                   \
+    {FAL_PART_MAGIC_WROD,        "app", "onchip_flash",                                    0,       384 * 1024, 0}, \
+    {FAL_PART_MAGIC_WROD,      "param", "onchip_flash",                           384 * 1024,       128 * 1024, 0}, \
+    {FAL_PART_MAGIC_WROD,  "easyflash",    "nor_flash",                                    0,       512 * 1024, 0}, \
+    {FAL_PART_MAGIC_WROD,   "download",    "nor_flash",                           512 * 1024,      1024 * 1024, 0}, \
+    {FAL_PART_MAGIC_WROD, "wifi_image",    "nor_flash",                  (512 + 1024) * 1024,       512 * 1024, 0}, \
+    {FAL_PART_MAGIC_WROD,       "font",    "nor_flash",            (512 + 1024 + 512) * 1024,  7 * 1024 * 1024, 0}, \
+    {FAL_PART_MAGIC_WROD, "filesystem",    "nor_flash", (512 + 1024 + 512 + 7 * 1024) * 1024,  7 * 1024 * 1024, 0}, \
+}
+#endif /* FAL_PART_HAS_TABLE_CFG */
+#endif /* _FAL_CFG_H_ */

+ 58 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/fal/fal_flash_sfud_port.c

@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-01-26     armink       the first version
+ * 2018-08-21     MurphyZhao   update to stm32l4xx
+ */
+
+#include <fal.h>
+
+#include <sfud.h>
+#include <spi_flash_sfud.h>
+
+sfud_flash sfud_norflash0;
+
+static int fal_sfud_init(void)
+{
+    sfud_flash_t sfud_flash0 = NULL;
+    sfud_flash0 = (sfud_flash_t)rt_sfud_flash_find("qspi10");
+    if (NULL == sfud_flash0)
+    {
+        return -1;
+    }
+
+    sfud_norflash0 = *sfud_flash0;
+    return 0;
+}
+
+static int read(long offset, uint8_t *buf, size_t size)
+{
+    sfud_read(&sfud_norflash0, nor_flash0.addr + offset, size, buf);
+
+    return size;
+}
+
+static int write(long offset, const uint8_t *buf, size_t size)
+{
+    if (sfud_write(&sfud_norflash0, nor_flash0.addr + offset, size, buf) != SFUD_SUCCESS)
+    {
+        return -1;
+    }
+
+    return size;
+}
+
+static int erase(long offset, size_t size)
+{
+    if (sfud_erase(&sfud_norflash0, nor_flash0.addr + offset, size) != SFUD_SUCCESS)
+    {
+        return -1;
+    }
+
+    return size;
+}
+const struct fal_flash_dev nor_flash0 = { "nor_flash", 0, (16 * 1024 * 1024), 4096, {fal_sfud_init, read, write, erase} };

+ 0 - 69
bsp/stm32/stm32l475-atk-pandora/board/ports/fal_cfg.h

@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- * 2018-12-5      SummerGift   first version
- */
-
-#ifndef _FAL_CFG_H_
-#define _FAL_CFG_H_
-
-#include <rtthread.h>
-#include <board.h>
-
-#if defined(BSP_USING_ON_CHIP_FLASH)
-extern const struct fal_flash_dev stm32_onchip_flash;
-#endif /* BSP_USING_ON_CHIP_FLASH */
-
-#if defined(BSP_USING_QSPI_FLASH)
-extern struct fal_flash_dev nor_flash0;
-#endif /* BSP_USING_QSPI_FLASH */
-
-/* ========================= Device Configuration ========================== */
-#ifdef BSP_USING_ON_CHIP_FLASH
-#define ONCHIP_FLASH_DEV     &stm32_onchip_flash,  
-#else
-#define ONCHIP_FLASH_DEV    
-#endif /* BSP_USING_ON_CHIP_FLASH */
-
-#ifdef BSP_USING_QSPI_FLASH
-#define SPI_FLASH_DEV        &nor_flash0,  
-#else
-#define SPI_FLASH_DEV    
-#endif /* BSP_USING_QSPI_FLASH */
-
-/* flash device table */
-#define FAL_FLASH_DEV_TABLE                                          \
-{                                                                    \
-    ONCHIP_FLASH_DEV                                                 \
-    SPI_FLASH_DEV                                                    \
-}
-
-/* ====================== Partition Configuration ========================== */
-#ifdef FAL_PART_HAS_TABLE_CFG
-
-#ifdef BSP_USING_ON_CHIP_FLASH
-#define ONCHIP_FLASH_PATITION          {FAL_PART_MAGIC_WROD, "app",   "onchip_flash",   0,           496 * 1024, 0},      \
-                                       {FAL_PART_MAGIC_WROD, "param", "onchip_flash",   496* 1024,   16 * 1024,  0},
-#else
-#define ONCHIP_FLASH_PATITION
-#endif
-
-#ifdef BSP_USING_QSPI_FLASH
-#define SPI_FLASH_PARTITION            {FAL_PART_MAGIC_WROD, "filesystem", "W25Q128", 9 * 1024 * 1024, 16 * 1024 * 1024, 0},
-#else
-#define SPI_FLASH_PARTITION 
-#endif
-
-/* partition table */
-#define FAL_PART_TABLE                                               \
-{                                                                    \
-    ONCHIP_FLASH_PATITION                                            \
-    SPI_FLASH_PARTITION                                              \
-}
-#endif /* FAL_PART_HAS_TABLE_CFG */
-
-#endif /* _FAL_CFG_H_ */

+ 14 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/wifi/SConscript

@@ -0,0 +1,14 @@
+
+from building import *
+import rtconfig
+
+cwd = GetCurrentDir()
+
+src = []
+
+src += Glob('*.c')
+CPPPATH = [cwd]
+
+group = DefineGroup('wifi', src, depend = ['BSP_USING_WIFI'], CPPPATH = CPPPATH)
+
+Return('group')

+ 250 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/wifi/wifi_config.c

@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-09-04     ZeroFree     first implementation
+ * 2019-06-14     armink       add easyflash v4.0 support
+ */
+
+#include <rtthread.h>
+
+#ifdef BSP_USING_WIFI
+
+#include <wlan_mgnt.h>
+#include <wlan_cfg.h>
+#include <wlan_prot.h>
+
+#include <easyflash.h>
+#include <fal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if (EF_SW_VERSION_NUM < 0x40000)
+
+static char *str_base64_encode_len(const void *src, char *out, int input_length);
+static int   str_base64_decode(const char *data, int input_length, char *decoded_data);
+
+static const unsigned char base64_table[65] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static const char base64_decode_table[256] =
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
+    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+    0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+    0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static char *str_base64_encode_len(const void *src, char *out, int len)
+{
+    unsigned char *pos;
+    const unsigned char *end, *in;
+    size_t olen;
+
+    olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
+    olen += olen / 72; /* line feeds */
+    olen++; /* nul termination */
+
+    end = (const unsigned char *)src + len;
+    in = (const unsigned char *)src;
+    pos = (unsigned char *)out;
+    while (end - in >= 3)
+    {
+        *pos++ = base64_table[in[0] >> 2];
+        *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
+        *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
+        *pos++ = base64_table[in[2] & 0x3f];
+        in += 3;
+    }
+
+    if (end - in)
+    {
+        *pos++ = base64_table[in[0] >> 2];
+
+        if (end - in == 1)
+        {
+            *pos++ = base64_table[(in[0] & 0x03) << 4];
+            *pos++ = '=';
+        }
+        else
+        {
+            *pos++ = base64_table[((in[0] & 0x03) << 4) |
+                                                  (in[1] >> 4)];
+            *pos++ = base64_table[(in[1] & 0x0f) << 2];
+        }
+        *pos++ = '=';
+    }
+
+    *pos = '\0';
+    return (char *)out;
+}
+
+/*
+ * return: length, 0 is error.
+ */
+static int str_base64_decode(const char *data, int input_length, char *decoded_data)
+{
+    int out_len;
+    int i, j;
+
+    if (input_length % 4 != 0) return 0;
+
+    out_len = input_length / 4 * 3;
+
+    if (data[input_length - 1] == '=') out_len--;
+    if (data[input_length - 2] == '=') out_len--;
+
+    for (i = 0, j = 0; i < input_length;)
+    {
+        uint32_t sextet_a = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
+        uint32_t sextet_b = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
+        uint32_t sextet_c = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
+        uint32_t sextet_d = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]];
+
+        uint32_t triple = (sextet_a << 3 * 6)
+                          + (sextet_b << 2 * 6)
+                          + (sextet_c << 1 * 6)
+                          + (sextet_d << 0 * 6);
+
+        if (j < out_len) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
+        if (j < out_len) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
+        if (j < out_len) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
+    }
+
+    return out_len;
+}
+
+static int read_cfg(void *buff, int len)
+{
+    char *wlan_cfg_info = RT_NULL;
+
+    wlan_cfg_info = ef_get_env("wlan_cfg_info");
+    if (wlan_cfg_info != RT_NULL)
+    {
+        str_base64_decode(wlan_cfg_info, rt_strlen(wlan_cfg_info), buff);
+        return len;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+static int get_len(void)
+{
+    int len;
+    char *wlan_cfg_len = RT_NULL;
+
+    wlan_cfg_len = ef_get_env("wlan_cfg_len");
+    if (wlan_cfg_len == RT_NULL)
+    {
+        len = 0;
+    }
+    else
+    {
+        len = atoi(wlan_cfg_len);
+    }
+
+    return len;
+}
+
+static int write_cfg(void *buff, int len)
+{
+    char wlan_cfg_len[12] = {0};
+    char *base64_buf = RT_NULL;
+
+    base64_buf = rt_malloc(len * 4 / 3 + 4); /* 3-byte blocks to 4-byte, and the end. */
+    if (base64_buf == RT_NULL)
+    {
+        return -RT_ENOMEM;
+    }
+    rt_memset(base64_buf, 0, len);
+
+    /* interger to string */
+    sprintf(wlan_cfg_len, "%d", len);
+    /* set and store the wlan config lengths to Env */
+    ef_set_env("wlan_cfg_len", wlan_cfg_len);
+    str_base64_encode_len(buff, base64_buf, len);
+    /* set and store the wlan config information to Env */
+    ef_set_env("wlan_cfg_info", base64_buf);
+    ef_save_env();
+    rt_free(base64_buf);
+
+    return len;
+}
+
+#else
+
+static int read_cfg(void *buff, int len)
+{
+    size_t saved_len;
+
+    ef_get_env_blob("wlan_cfg_info", buff, len, &saved_len);
+    if (saved_len == 0)
+    {
+        return 0;
+    }
+    
+    return len;
+}
+
+static int get_len(void)
+{
+    int len;
+    size_t saved_len;
+
+    ef_get_env_blob("wlan_cfg_len", &len, sizeof(len), &saved_len);
+    if (saved_len == 0)
+    {
+        return 0;
+    }
+
+    return len;
+}
+
+static int write_cfg(void *buff, int len)
+{
+    /* set and store the wlan config lengths to Env */
+    ef_set_env_blob("wlan_cfg_len", &len, sizeof(len));
+
+    /* set and store the wlan config information to Env */
+    ef_set_env_blob("wlan_cfg_info", buff, len);
+
+    return len;
+}
+
+#endif /* (EF_SW_VERSION_NUM < 0x40000) */
+
+static const struct rt_wlan_cfg_ops ops =
+{
+    read_cfg,
+    get_len,
+    write_cfg
+};
+
+void wlan_autoconnect_init(void)
+{
+    fal_init();
+    easyflash_init();
+
+    rt_wlan_cfg_set_ops(&ops);
+    rt_wlan_cfg_cache_refresh();
+}
+
+#endif

+ 13 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/wifi/wifi_config.h

@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-09-04     ZeroFree     first implementation
+ */
+
+#include <rtthread.h>
+
+void wlan_autoconnect_init(void);

+ 14 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/wlan/SConscript

@@ -0,0 +1,14 @@
+
+from building import *
+import rtconfig
+
+cwd = GetCurrentDir()
+
+src = []
+
+src += Glob('*.c')
+CPPPATH = [cwd]
+
+group = DefineGroup('Drivers', src, depend = ['BSP_USING_WIFI'], CPPPATH = CPPPATH)
+
+Return('group')

+ 155 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/wlan/drv_wlan.c

@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-08-30     ZeroFree     the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <wlan_mgnt.h>
+#include <wlan_prot.h>
+#include <wlan_cfg.h>
+#include <fal.h>
+
+#include "drv_wlan.h"
+#include "drv_gpio.h"
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME    "WLAN"
+#define DBG_COLOR
+#define DBG_LEVEL           DBG_LOG
+#include <rtdbg.h>
+
+#ifdef BSP_USING_WIFI
+
+#define WIFI_IMAGE_PARTITION_NAME       "wifi_image"
+#define WIFI_INIT_THREAD_STACK_SIZE      (1024 * 4)
+#define WIFI_INIT_THREAD_PRIORITY        (RT_THREAD_PRIORITY_MAX/2)
+#define WIFI_INIT_WAIT_TIME              (rt_tick_from_millisecond(100))
+#define WIFI_IRQ_PIN                     GET_PIN(C, 5)
+
+extern int wifi_hw_init(void);
+extern void wwd_thread_notify_irq(void);
+
+static const struct fal_partition *partition = RT_NULL;
+static rt_uint32_t init_flag = 0;
+
+struct rt_wlan_device *bcm_hw_wlan_dev_alloc(void)
+{
+    struct rt_wlan_device *wlan;
+
+    wlan = rt_malloc(sizeof(struct rt_wlan_device));
+
+    return wlan;
+}
+
+#ifdef RT_USING_PM
+void wiced_platform_keep_awake(void)
+{
+    rt_pm_request(PM_SLEEP_MODE_NONE);
+}
+
+void wiced_platform_let_sleep(void)
+{
+    rt_pm_release(PM_SLEEP_MODE_NONE);
+}
+#endif
+
+/**
+ * return:1 initialize done
+ *        0 not initialize
+ */
+int rt_hw_wlan_get_initialize_status(void)
+{
+    return init_flag;
+}
+
+/**
+ * wait milliseconds for wifi low level initialize complete
+ *
+ * time_ms: timeout in milliseconds
+ */
+int rt_hw_wlan_wait_init_done(rt_uint32_t time_ms)
+{
+    rt_uint32_t time_cnt = 0;
+
+    /* wait wifi low level initialize complete */
+    while (time_cnt <= (time_ms / 100))
+    {
+        time_cnt++;
+        rt_thread_mdelay(100);
+        if (rt_hw_wlan_get_initialize_status() == 1)
+        {
+            break;
+        }
+    }
+
+    if (time_cnt > (time_ms / 100))
+    {
+        return -RT_ETIMEOUT;
+    }
+
+    return RT_EOK;
+}
+
+static void _wiced_irq_handler(void *param)
+{
+    wwd_thread_notify_irq();
+}
+
+static void wifi_init_thread_entry(void *parameter)
+{
+    /* set wifi irq handle, must be initialized first */
+    rt_pin_mode(WIFI_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
+    rt_pin_attach_irq(WIFI_IRQ_PIN, PIN_IRQ_MODE_RISING_FALLING, _wiced_irq_handler, RT_NULL);
+    rt_pin_irq_enable(WIFI_IRQ_PIN, PIN_IRQ_ENABLE);
+
+    /* initialize low level wifi(ap6181) library */
+    wifi_hw_init();
+
+    /* waiting for sdio bus stability */
+    rt_thread_delay(WIFI_INIT_WAIT_TIME);
+
+    /* set wifi work mode */
+    rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
+
+    init_flag = 1;
+}
+
+int rt_hw_wlan_init(void)
+{
+    if (init_flag == 1)
+    {
+        return RT_EOK;
+    }
+
+#ifdef BSP_USING_WIFI_THREAD_INIT
+    rt_thread_t tid = RT_NULL;
+
+    tid = rt_thread_create("wifi_init", wifi_init_thread_entry, RT_NULL, WIFI_INIT_THREAD_STACK_SIZE, WIFI_INIT_THREAD_PRIORITY, 20);
+    if (tid)
+    {
+        rt_thread_startup(tid);
+    }
+    else
+    {
+        LOG_E("Create wifi initialization thread fail!");
+        return -RT_ERROR;
+    }
+#else
+    wifi_init_thread_entry(RT_NULL);
+    init_flag = 1;
+#endif
+
+    return RT_EOK;
+}
+
+#ifdef BSP_USING_WIFI_AUTO_INIT
+    INIT_APP_EXPORT(rt_hw_wlan_init);
+#endif
+
+#endif

+ 20 - 0
bsp/stm32/stm32l475-atk-pandora/board/ports/wlan/drv_wlan.h

@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-08-30     ZeroFree     the first version
+ */
+
+#ifndef __DRV_WLAN_H__
+#define __DRV_WLAN_H__
+
+#include <rtthread.h>
+
+int rt_hw_wlan_init(void);
+int rt_hw_wlan_get_initialize_status(void);
+int rt_hw_wlan_wait_init_done(rt_uint32_t time_ms);
+
+#endif