目前共有7篇帖子。
【程序】Marvell 88W8686 WiFi模塊的固件下載代碼
1樓 巨大八爪鱼 2017-7-6 22:27
【main.c】
#include <stdio.h>
#include <stm32f10x.h>
#include <string.h>
#include "WiFi.h"

// 延時n毫秒
void delay(uint16_t n)
{
    TIM6->ARR = 10 * n - 1; // nms
    TIM6->PSC = 7199; // 72MHz/7200=10kHz
    TIM6->CR1 = TIM_CR1_URS | TIM_CR1_OPM; // UG不置位UIF, 非循環模式
    TIM6->EGR = TIM_EGR_UG; // 保存設置
    TIM6->CR1 |= TIM_CR1_CEN; // 開始計時
    while ((TIM6->SR & TIM_SR_UIF) == 0); // 等待計時完畢
    TIM6->SR &= ~TIM_SR_UIF; // 清除溢出標誌
}

int fputc(int ch, FILE *fp)
{
    if (fp == stdout)
    {
        if (ch == '\n')
        {
            while ((USART1->SR & USART_SR_TXE) == 0);
            USART1->DR = '\r';
        }
        while ((USART1->SR & USART_SR_TXE) == 0);
        USART1->DR = ch;
    }
    return ch;
}

void dump_data(uint8_t *data, uint16_t len)
{
    uint32_t crc;
    CRC->CR = CRC_CR_RESET;
    while (len--)
    {
        CRC->DR = *data;
        printf("%02X", *data++);
    }
    crc = CRC->DR;
   
    for (len = 0; len < 4; len++)
    {
        printf("%02X", crc & 0xff);
        crc >>= 8;
    }
    printf("\n");
}

int main(void)
{
    volatile uint32_t sta;
   
    RCC->AHBENR = RCC_AHBENR_CRCEN | RCC_AHBENR_SDIOEN;
    RCC->APB1ENR = RCC_APB1ENR_TIM6EN;
    RCC->APB2ENR = RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_USART1EN;
   
    GPIOA->CRH = 0x000004b0;
    GPIOB->CRH = 0x00030000; // PB12為外接的WiFi模塊電源開關, PB12=0時打開WiFi模塊
    GPIOC->CRH = 0x000bbbbb;
    GPIOD->CRL = 0x00000b00;
   
    USART1->BRR = 0x271; // 波特率: 115200
    USART1->CR1 = USART_CR1_UE | USART_CR1_TE;
   
    WiFi_Init();
    WiFi_DownloadFirmware();
   
    while (1)
    {
        sta = SDIO->STA;
        printf("SDIO->STA=0x%08x\n", sta);
        while (sta == SDIO->STA);
    }
}
2樓 巨大八爪鱼 2017-7-6 22:28
【WiFi.h】
#define _BV(n) (1u << (n))

#define CMD52_WRITE _BV(31)
#define CMD52_READAFTERWRITE _BV(27)

#define CMD53_WRITE _BV(31)
#define CMD53_BLOCKMODE _BV(27)
#define CMD53_INCREMENTING _BV(26)

// 16.5 SDIO Card Metaformat
#define CISTPL_NULL 0x00 // Null tuple
#define CISTPL_VERS_1 0x15 // Level 1 version/product-information
#define CISTPL_MANFID 0x20 // Manufacturer Identification String Tuple
#define CISTPL_FUNCID 0x21 // Function Identification Tuple
#define CISTPL_FUNCE 0x22 // Function Extensions
#define CISTPL_END 0xff // The End-of-chain Tuple

#define WIFI_SQREADBASEADDR0 0x10
#define WIFI_SQREADBASEADDR1 0x11
#define WIFI_SQREADBASEADDR2 0x12
#define WIFI_SQREADBASEADDR3 0x13

#define WIFI_CARDSTATUS 0x20 // Card Status
#define WIFI_CARDSTATUS_IOREADY _BV(3) // I/O Ready Indicator
#define WIFI_CARDSTATUS_CISCARDRDY _BV(2) // Card Information Structure Card Ready
#define WIFI_CARDSTATUS_UPLDCARDRDY _BV(1) // Upload Card Ready
#define WIFI_CARDSTATUS_DNLDCARDRDY _BV(0) // Download Card Ready

#define WiFi_GetBlockSize() _BV((SDIO->DCTRL & SDIO_DCTRL_DBLOCKSIZE) >> 4)

void WiFi_CheckCmdTimeout(void);
void WiFi_DownloadFirmware(void);
void WiFi_Init(void);
uint8_t WiFi_Read(uint8_t func, uint32_t addr);
void WiFi_ReadData(uint8_t func, uint32_t addr, uint8_t *data, uint16_t count, uint32_t flags);
void WiFi_SendCMD52(uint8_t func, uint32_t addr, uint8_t data, uint32_t flags);
void WiFi_SendCMD53(uint8_t func, uint32_t addr, uint16_t count, uint32_t flags);
void WiFi_SetBlockSize(uint8_t func);
void WiFi_ShowCIS(uint8_t func);
void WiFi_ShowShortResponse(void);
void WiFi_Wait(void);
uint8_t WiFi_Write(uint8_t func, uint32_t addr, uint8_t value);
void WiFi_WriteData(uint8_t func, uint32_t addr, const uint8_t *data, uint16_t count, uint32_t flags);
4樓 巨大八爪鱼 2017-7-6 22:29
【程序運行結果】
Initialization begins...
Command response received: CMD63, RESP_90ff8000
Command response received: CMD63, RESP_90300000
Number of I/O Functions: 1
Memory Present: 0
Relative card address: 0x0001
Card selected! status=0x00001e00
Pointer to Function 0 Card Information Structure (CIS): 0x00008000
[CIS Tuple 0x15] addr=0x00008000 size=31
01004D617276656C6C003830322E3131205344494F2049443A2030420000FFECE43609
Marvell
802.11 SDIO ID: 0B
[CIS Tuple 0x20] addr=0x00008021 size=4
DF020391B20F4143
SDIO Card manufacturer code: 0x02df
manufacturer information (Part Number and/or Revision): 0x9103
[CIS Tuple 0x21] addr=0x00008027 size=2
0C00DC3F1908
Card function code: 0x0c
System initialization bit mask: 0x00
[CIS Tuple 0x22] addr=0x0000802b size=4
00000132BB1390C1
maximum block size: 256
maximum transfer rate code: 0x32
Pointer to Function 1 Card Information Structure (CIS): 0x00008080
[CIS Tuple 0x21] addr=0x00008080 size=2
0C00DC3F1908
Card function code: 0x0c
System initialization bit mask: 0x00
[CIS Tuple 0x22] addr=0x00008084 size=28
010110000000000000000000000100000000000000000000000000004431F2BF
maximum block size: 256
Required: 16 bytes, Remaining: 122916 bytes
Required: 512 bytes, Remaining: 122900 bytes
Required: 16 bytes, Remaining: 122388 bytes
Required: 512 bytes, Remaining: 122372 bytes
Required: 16 bytes, Remaining: 121860 bytes
Required: 512 bytes, Remaining: 121844 bytes
Required: 16 bytes, Remaining: 121332 bytes
Required: 512 bytes, Remaining: 121316 bytes
Required: 16 bytes, Remaining: 120804 bytes
Required: 512 bytes, Remaining: 120788 bytes
Required: 16 bytes, Remaining: 120276 bytes
Required: 512 bytes, Remaining: 120260 bytes
Required: 16 bytes, Remaining: 119748 bytes
Required: 512 bytes, Remaining: 119732 bytes
Required: 16 bytes, Remaining: 119220 bytes
Required: 512 bytes, Remaining: 119204 bytes
Required: 16 bytes, Remaining: 118692 bytes
Required: 512 bytes, Remaining: 118676 bytes
Required: 16 bytes, Remaining: 118164 bytes
Required: 512 bytes, Remaining: 118148 bytes
Required: 16 bytes, Remaining: 117636 bytes
Required: 512 bytes, Remaining: 117620 bytes
Required: 16 bytes, Remaining: 117108 bytes
Required: 512 bytes, Remaining: 117092 bytes
Required: 16 bytes, Remaining: 116580 bytes
Required: 512 bytes, Remaining: 116564 bytes
Required: 16 bytes, Remaining: 116052 bytes
Required: 512 bytes, Remaining: 116036 bytes
Required: 16 bytes, Remaining: 115524 bytes
Required: 512 bytes, Remaining: 115508 bytes
Required: 16 bytes, Remaining: 114996 bytes
Required: 512 bytes, Remaining: 114980 bytes
Required: 16 bytes, Remaining: 114468 bytes
Required: 512 bytes, Remaining: 114452 bytes
Required: 16 bytes, Remaining: 113940 bytes
Required: 512 bytes, Remaining: 113924 bytes
Required: 16 bytes, Remaining: 113412 bytes
Required: 512 bytes, Remaining: 113396 bytes
Required: 16 bytes, Remaining: 112884 bytes
Required: 512 bytes, Remaining: 112868 bytes
Required: 16 bytes, Remaining: 112356 bytes
Required: 512 bytes, Remaining: 112340 bytes
Required: 16 bytes, Remaining: 111828 bytes
Required: 512 bytes, Remaining: 111812 bytes
Required: 16 bytes, Remaining: 111300 bytes
Required: 512 bytes, Remaining: 111284 bytes
Required: 16 bytes, Remaining: 110772 bytes
Required: 512 bytes, Remaining: 110756 bytes
Required: 16 bytes, Remaining: 110244 bytes
Required: 512 bytes, Remaining: 110228 bytes
Required: 16 bytes, Remaining: 109716 bytes
Required: 512 bytes, Remaining: 109700 bytes
Required: 16 bytes, Remaining: 109188 bytes
Required: 512 bytes, Remaining: 109172 bytes
Required: 16 bytes, Remaining: 108660 bytes
Required: 512 bytes, Remaining: 108644 bytes
Required: 16 bytes, Remaining: 108132 bytes
Required: 512 bytes, Remaining: 108116 bytes
Required: 16 bytes, Remaining: 107604 bytes
Required: 512 bytes, Remaining: 107588 bytes
Required: 16 bytes, Remaining: 107076 bytes
Required: 512 bytes, Remaining: 107060 bytes
Required: 16 bytes, Remaining: 106548 bytes
Required: 512 bytes, Remaining: 106532 bytes
Required: 16 bytes, Remaining: 106020 bytes
Required: 512 bytes, Remaining: 106004 bytes
Required: 16 bytes, Remaining: 105492 bytes
Required: 512 bytes, Remaining: 105476 bytes
Required: 16 bytes, Remaining: 104964 bytes
Required: 512 bytes, Remaining: 104948 bytes
Required: 16 bytes, Remaining: 104436 bytes
Required: 512 bytes, Remaining: 104420 bytes
Required: 16 bytes, Remaining: 103908 bytes
Required: 512 bytes, Remaining: 103892 bytes
Required: 16 bytes, Remaining: 103380 bytes
Required: 512 bytes, Remaining: 103364 bytes
Required: 16 bytes, Remaining: 102852 bytes
Required: 512 bytes, Remaining: 102836 bytes
Required: 16 bytes, Remaining: 102324 bytes
Required: 512 bytes, Remaining: 102308 bytes
Required: 16 bytes, Remaining: 101796 bytes
Required: 512 bytes, Remaining: 101780 bytes
Required: 16 bytes, Remaining: 101268 bytes
Required: 512 bytes, Remaining: 101252 bytes
Required: 16 bytes, Remaining: 100740 bytes
Required: 512 bytes, Remaining: 100724 bytes
Required: 16 bytes, Remaining: 100212 bytes
Required: 512 bytes, Remaining: 100196 bytes
Required: 16 bytes, Remaining: 99684 bytes
Required: 512 bytes, Remaining: 99668 bytes
Required: 16 bytes, Remaining: 99156 bytes
Required: 512 bytes, Remaining: 99140 bytes
Required: 16 bytes, Remaining: 98628 bytes
Required: 196 bytes, Remaining: 98612 bytes
Required: 16 bytes, Remaining: 98416 bytes
Required: 512 bytes, Remaining: 98400 bytes
Required: 16 bytes, Remaining: 97888 bytes
Required: 512 bytes, Remaining: 97872 bytes
Required: 16 bytes, Remaining: 97360 bytes
Required: 512 bytes, Remaining: 97344 bytes
Required: 16 bytes, Remaining: 96832 bytes
Required: 512 bytes, Remaining: 96816 bytes
Required: 16 bytes, Remaining: 96304 bytes
Required: 512 bytes, Remaining: 96288 bytes
Required: 16 bytes, Remaining: 95776 bytes
Required: 512 bytes, Remaining: 95760 bytes
Required: 16 bytes, Remaining: 95248 bytes
Required: 512 bytes, Remaining: 95232 bytes
Required: 16 bytes, Remaining: 94720 bytes
Required: 512 bytes, Remaining: 94704 bytes
Required: 16 bytes, Remaining: 94192 bytes
Required: 512 bytes, Remaining: 94176 bytes
Required: 16 bytes, Remaining: 93664 bytes
Required: 512 bytes, Remaining: 93648 bytes
Required: 16 bytes, Remaining: 93136 bytes
Required: 512 bytes, Remaining: 93120 bytes
Required: 16 bytes, Remaining: 92608 bytes
Required: 512 bytes, Remaining: 92592 bytes
Required: 16 bytes, Remaining: 92080 bytes
Required: 512 bytes, Remaining: 92064 bytes
Required: 16 bytes, Remaining: 91552 bytes
Required: 512 bytes, Remaining: 91536 bytes
Required: 16 bytes, Remaining: 91024 bytes
Required: 512 bytes, Remaining: 91008 bytes
Required: 16 bytes, Remaining: 90496 bytes
Required: 512 bytes, Remaining: 90480 bytes
Required: 16 bytes, Remaining: 89968 bytes
Required: 512 bytes, Remaining: 89952 bytes
Required: 16 bytes, Remaining: 89440 bytes
Required: 512 bytes, Remaining: 89424 bytes
Required: 16 bytes, Remaining: 88912 bytes
Required: 512 bytes, Remaining: 88896 bytes
Required: 16 bytes, Remaining: 88384 bytes
Required: 512 bytes, Remaining: 88368 bytes
Required: 16 bytes, Remaining: 87856 bytes
Required: 512 bytes, Remaining: 87840 bytes
Required: 16 bytes, Remaining: 87328 bytes
Required: 512 bytes, Remaining: 87312 bytes
Required: 16 bytes, Remaining: 86800 bytes
Required: 512 bytes, Remaining: 86784 bytes
Required: 16 bytes, Remaining: 86272 bytes
Required: 512 bytes, Remaining: 86256 bytes
Required: 16 bytes, Remaining: 85744 bytes
Required: 512 bytes, Remaining: 85728 bytes
Required: 16 bytes, Remaining: 85216 bytes
Required: 512 bytes, Remaining: 85200 bytes
Required: 16 bytes, Remaining: 84688 bytes
Required: 512 bytes, Remaining: 84672 bytes
Required: 16 bytes, Remaining: 84160 bytes
Required: 512 bytes, Remaining: 84144 bytes
Required: 16 bytes, Remaining: 83632 bytes
Required: 512 bytes, Remaining: 83616 bytes
Required: 16 bytes, Remaining: 83104 bytes
Required: 512 bytes, Remaining: 83088 bytes
Required: 16 bytes, Remaining: 82576 bytes
Required: 512 bytes, Remaining: 82560 bytes
Required: 16 bytes, Remaining: 82048 bytes
Required: 512 bytes, Remaining: 82032 bytes
Required: 16 bytes, Remaining: 81520 bytes
Required: 512 bytes, Remaining: 81504 bytes
Required: 16 bytes, Remaining: 80992 bytes
Required: 512 bytes, Remaining: 80976 bytes
Required: 16 bytes, Remaining: 80464 bytes
Required: 512 bytes, Remaining: 80448 bytes
Required: 16 bytes, Remaining: 79936 bytes
Required: 512 bytes, Remaining: 79920 bytes
Required: 16 bytes, Remaining: 79408 bytes
Required: 512 bytes, Remaining: 79392 bytes
Required: 16 bytes, Remaining: 78880 bytes
Required: 512 bytes, Remaining: 78864 bytes
Required: 16 bytes, Remaining: 78352 bytes
Required: 512 bytes, Remaining: 78336 bytes
Required: 16 bytes, Remaining: 77824 bytes
Required: 512 bytes, Remaining: 77808 bytes
Required: 16 bytes, Remaining: 77296 bytes
Required: 512 bytes, Remaining: 77280 bytes
Required: 16 bytes, Remaining: 76768 bytes
Required: 512 bytes, Remaining: 76752 bytes
Required: 16 bytes, Remaining: 76240 bytes
Required: 512 bytes, Remaining: 76224 bytes
Required: 16 bytes, Remaining: 75712 bytes
Required: 512 bytes, Remaining: 75696 bytes
Required: 16 bytes, Remaining: 75184 bytes
Required: 512 bytes, Remaining: 75168 bytes
Required: 16 bytes, Remaining: 74656 bytes
Required: 512 bytes, Remaining: 74640 bytes
Required: 16 bytes, Remaining: 74128 bytes
Required: 512 bytes, Remaining: 74112 bytes
Required: 16 bytes, Remaining: 73600 bytes
Required: 512 bytes, Remaining: 73584 bytes
Required: 16 bytes, Remaining: 73072 bytes
Required: 512 bytes, Remaining: 73056 bytes
Required: 16 bytes, Remaining: 72544 bytes
Required: 512 bytes, Remaining: 72528 bytes
Required: 16 bytes, Remaining: 72016 bytes
Required: 512 bytes, Remaining: 72000 bytes
Required: 16 bytes, Remaining: 71488 bytes
Required: 512 bytes, Remaining: 71472 bytes
Required: 16 bytes, Remaining: 70960 bytes
Required: 512 bytes, Remaining: 70944 bytes
Required: 16 bytes, Remaining: 70432 bytes
Required: 512 bytes, Remaining: 70416 bytes
Required: 16 bytes, Remaining: 69904 bytes
Required: 512 bytes, Remaining: 69888 bytes
Required: 16 bytes, Remaining: 69376 bytes
Required: 512 bytes, Remaining: 69360 bytes
Required: 16 bytes, Remaining: 68848 bytes
Required: 512 bytes, Remaining: 68832 bytes
Required: 16 bytes, Remaining: 68320 bytes
Required: 512 bytes, Remaining: 68304 bytes
Required: 16 bytes, Remaining: 67792 bytes
Required: 512 bytes, Remaining: 67776 bytes
Required: 16 bytes, Remaining: 67264 bytes
Required: 512 bytes, Remaining: 67248 bytes
Required: 16 bytes, Remaining: 66736 bytes
Required: 512 bytes, Remaining: 66720 bytes
Required: 16 bytes, Remaining: 66208 bytes
Required: 512 bytes, Remaining: 66192 bytes
Required: 16 bytes, Remaining: 65680 bytes
Required: 512 bytes, Remaining: 65664 bytes
Required: 16 bytes, Remaining: 65152 bytes
Required: 512 bytes, Remaining: 65136 bytes
Required: 16 bytes, Remaining: 64624 bytes
Required: 512 bytes, Remaining: 64608 bytes
Required: 16 bytes, Remaining: 64096 bytes
Required: 512 bytes, Remaining: 64080 bytes
Required: 16 bytes, Remaining: 63568 bytes
Required: 512 bytes, Remaining: 63552 bytes
Required: 16 bytes, Remaining: 63040 bytes
Required: 512 bytes, Remaining: 63024 bytes
Required: 16 bytes, Remaining: 62512 bytes
Required: 512 bytes, Remaining: 62496 bytes
Required: 16 bytes, Remaining: 61984 bytes
Required: 512 bytes, Remaining: 61968 bytes
Required: 16 bytes, Remaining: 61456 bytes
Required: 512 bytes, Remaining: 61440 bytes
Required: 16 bytes, Remaining: 60928 bytes
Required: 512 bytes, Remaining: 60912 bytes
Required: 16 bytes, Remaining: 60400 bytes
Required: 512 bytes, Remaining: 60384 bytes
Required: 16 bytes, Remaining: 59872 bytes
Required: 512 bytes, Remaining: 59856 bytes
Required: 16 bytes, Remaining: 59344 bytes
Required: 512 bytes, Remaining: 59328 bytes
Required: 16 bytes, Remaining: 58816 bytes
Required: 512 bytes, Remaining: 58800 bytes
Required: 16 bytes, Remaining: 58288 bytes
Required: 512 bytes, Remaining: 58272 bytes
Required: 16 bytes, Remaining: 57760 bytes
Required: 512 bytes, Remaining: 57744 bytes
Required: 16 bytes, Remaining: 57232 bytes
Required: 512 bytes, Remaining: 57216 bytes
Required: 16 bytes, Remaining: 56704 bytes
Required: 512 bytes, Remaining: 56688 bytes
Required: 16 bytes, Remaining: 56176 bytes
Required: 512 bytes, Remaining: 56160 bytes
Required: 16 bytes, Remaining: 55648 bytes
Required: 512 bytes, Remaining: 55632 bytes
Required: 16 bytes, Remaining: 55120 bytes
Required: 512 bytes, Remaining: 55104 bytes
Required: 16 bytes, Remaining: 54592 bytes
Required: 512 bytes, Remaining: 54576 bytes
Required: 16 bytes, Remaining: 54064 bytes
Required: 512 bytes, Remaining: 54048 bytes
Required: 16 bytes, Remaining: 53536 bytes
Required: 512 bytes, Remaining: 53520 bytes
Required: 16 bytes, Remaining: 53008 bytes
Required: 512 bytes, Remaining: 52992 bytes
Required: 16 bytes, Remaining: 52480 bytes
Required: 512 bytes, Remaining: 52464 bytes
Required: 16 bytes, Remaining: 51952 bytes
Required: 512 bytes, Remaining: 51936 bytes
Required: 16 bytes, Remaining: 51424 bytes
Required: 512 bytes, Remaining: 51408 bytes
Required: 16 bytes, Remaining: 50896 bytes
Required: 512 bytes, Remaining: 50880 bytes
Required: 16 bytes, Remaining: 50368 bytes
Required: 512 bytes, Remaining: 50352 bytes
Required: 16 bytes, Remaining: 49840 bytes
Required: 512 bytes, Remaining: 49824 bytes
Required: 16 bytes, Remaining: 49312 bytes
Required: 512 bytes, Remaining: 49296 bytes
Required: 16 bytes, Remaining: 48784 bytes
Required: 512 bytes, Remaining: 48768 bytes
Required: 16 bytes, Remaining: 48256 bytes
Required: 512 bytes, Remaining: 48240 bytes
Required: 16 bytes, Remaining: 47728 bytes
Required: 512 bytes, Remaining: 47712 bytes
Required: 16 bytes, Remaining: 47200 bytes
Required: 512 bytes, Remaining: 47184 bytes
Required: 16 bytes, Remaining: 46672 bytes
Required: 512 bytes, Remaining: 46656 bytes
Required: 16 bytes, Remaining: 46144 bytes
Required: 512 bytes, Remaining: 46128 bytes
Required: 16 bytes, Remaining: 45616 bytes
Required: 512 bytes, Remaining: 45600 bytes
Required: 16 bytes, Remaining: 45088 bytes
Required: 512 bytes, Remaining: 45072 bytes
Required: 16 bytes, Remaining: 44560 bytes
Required: 512 bytes, Remaining: 44544 bytes
Required: 16 bytes, Remaining: 44032 bytes
Required: 512 bytes, Remaining: 44016 bytes
Required: 16 bytes, Remaining: 43504 bytes
Required: 512 bytes, Remaining: 43488 bytes
Required: 16 bytes, Remaining: 42976 bytes
Required: 512 bytes, Remaining: 42960 bytes
Required: 16 bytes, Remaining: 42448 bytes
Required: 512 bytes, Remaining: 42432 bytes
Required: 16 bytes, Remaining: 41920 bytes
Required: 512 bytes, Remaining: 41904 bytes
Required: 16 bytes, Remaining: 41392 bytes
Required: 512 bytes, Remaining: 41376 bytes
Required: 16 bytes, Remaining: 40864 bytes
Required: 512 bytes, Remaining: 40848 bytes
Required: 16 bytes, Remaining: 40336 bytes
Required: 512 bytes, Remaining: 40320 bytes
Required: 16 bytes, Remaining: 39808 bytes
Required: 512 bytes, Remaining: 39792 bytes
Required: 16 bytes, Remaining: 39280 bytes
Required: 512 bytes, Remaining: 39264 bytes
Required: 16 bytes, Remaining: 38752 bytes
Required: 512 bytes, Remaining: 38736 bytes
Required: 16 bytes, Remaining: 38224 bytes
Required: 512 bytes, Remaining: 38208 bytes
Required: 16 bytes, Remaining: 37696 bytes
Required: 512 bytes, Remaining: 37680 bytes
Required: 16 bytes, Remaining: 37168 bytes
Required: 512 bytes, Remaining: 37152 bytes
Required: 16 bytes, Remaining: 36640 bytes
Required: 512 bytes, Remaining: 36624 bytes
Required: 16 bytes, Remaining: 36112 bytes
Required: 512 bytes, Remaining: 36096 bytes
Required: 16 bytes, Remaining: 35584 bytes
Required: 512 bytes, Remaining: 35568 bytes
Required: 16 bytes, Remaining: 35056 bytes
Required: 512 bytes, Remaining: 35040 bytes
Required: 16 bytes, Remaining: 34528 bytes
Required: 512 bytes, Remaining: 34512 bytes
Required: 16 bytes, Remaining: 34000 bytes
Required: 512 bytes, Remaining: 33984 bytes
Required: 16 bytes, Remaining: 33472 bytes
Required: 512 bytes, Remaining: 33456 bytes
Required: 16 bytes, Remaining: 32944 bytes
Required: 512 bytes, Remaining: 32928 bytes
Required: 16 bytes, Remaining: 32416 bytes
Required: 512 bytes, Remaining: 32400 bytes
Required: 16 bytes, Remaining: 31888 bytes
Required: 512 bytes, Remaining: 31872 bytes
Required: 16 bytes, Remaining: 31360 bytes
Required: 512 bytes, Remaining: 31344 bytes
Required: 16 bytes, Remaining: 30832 bytes
Required: 512 bytes, Remaining: 30816 bytes
Required: 16 bytes, Remaining: 30304 bytes
Required: 512 bytes, Remaining: 30288 bytes
Required: 16 bytes, Remaining: 29776 bytes
Required: 512 bytes, Remaining: 29760 bytes
Required: 16 bytes, Remaining: 29248 bytes
Required: 512 bytes, Remaining: 29232 bytes
Required: 16 bytes, Remaining: 28720 bytes
Required: 512 bytes, Remaining: 28704 bytes
Required: 16 bytes, Remaining: 28192 bytes
Required: 512 bytes, Remaining: 28176 bytes
Required: 16 bytes, Remaining: 27664 bytes
Required: 512 bytes, Remaining: 27648 bytes
Required: 16 bytes, Remaining: 27136 bytes
Required: 512 bytes, Remaining: 27120 bytes
Required: 16 bytes, Remaining: 26608 bytes
Required: 512 bytes, Remaining: 26592 bytes
Required: 16 bytes, Remaining: 26080 bytes
Required: 512 bytes, Remaining: 26064 bytes
Required: 16 bytes, Remaining: 25552 bytes
Required: 512 bytes, Remaining: 25536 bytes
Required: 16 bytes, Remaining: 25024 bytes
Required: 512 bytes, Remaining: 25008 bytes
Required: 16 bytes, Remaining: 24496 bytes
Required: 512 bytes, Remaining: 24480 bytes
Required: 16 bytes, Remaining: 23968 bytes
Required: 512 bytes, Remaining: 23952 bytes
Required: 16 bytes, Remaining: 23440 bytes
Required: 512 bytes, Remaining: 23424 bytes
Required: 16 bytes, Remaining: 22912 bytes
Required: 512 bytes, Remaining: 22896 bytes
Required: 16 bytes, Remaining: 22384 bytes
Required: 512 bytes, Remaining: 22368 bytes
Required: 16 bytes, Remaining: 21856 bytes
Required: 512 bytes, Remaining: 21840 bytes
Required: 16 bytes, Remaining: 21328 bytes
Required: 512 bytes, Remaining: 21312 bytes
Required: 16 bytes, Remaining: 20800 bytes
Required: 512 bytes, Remaining: 20784 bytes
Required: 16 bytes, Remaining: 20272 bytes
Required: 512 bytes, Remaining: 20256 bytes
Required: 16 bytes, Remaining: 19744 bytes
Required: 512 bytes, Remaining: 19728 bytes
Required: 16 bytes, Remaining: 19216 bytes
Required: 512 bytes, Remaining: 19200 bytes
Required: 16 bytes, Remaining: 18688 bytes
Required: 512 bytes, Remaining: 18672 bytes
Required: 16 bytes, Remaining: 18160 bytes
Required: 512 bytes, Remaining: 18144 bytes
Required: 16 bytes, Remaining: 17632 bytes
Required: 512 bytes, Remaining: 17616 bytes
Required: 16 bytes, Remaining: 17104 bytes
Required: 512 bytes, Remaining: 17088 bytes
Required: 16 bytes, Remaining: 16576 bytes
Required: 512 bytes, Remaining: 16560 bytes
Required: 16 bytes, Remaining: 16048 bytes
Required: 512 bytes, Remaining: 16032 bytes
Required: 16 bytes, Remaining: 15520 bytes
Required: 512 bytes, Remaining: 15504 bytes
Required: 16 bytes, Remaining: 14992 bytes
Required: 512 bytes, Remaining: 14976 bytes
Required: 16 bytes, Remaining: 14464 bytes
Required: 512 bytes, Remaining: 14448 bytes
Required: 16 bytes, Remaining: 13936 bytes
Required: 512 bytes, Remaining: 13920 bytes
Required: 16 bytes, Remaining: 13408 bytes
Required: 512 bytes, Remaining: 13392 bytes
Required: 16 bytes, Remaining: 12880 bytes
Required: 512 bytes, Remaining: 12864 bytes
Required: 16 bytes, Remaining: 12352 bytes
Required: 512 bytes, Remaining: 12336 bytes
Required: 16 bytes, Remaining: 11824 bytes
Required: 512 bytes, Remaining: 11808 bytes
Required: 16 bytes, Remaining: 11296 bytes
Required: 512 bytes, Remaining: 11280 bytes
Required: 16 bytes, Remaining: 10768 bytes
Required: 512 bytes, Remaining: 10752 bytes
Required: 16 bytes, Remaining: 10240 bytes
Required: 512 bytes, Remaining: 10224 bytes
Required: 16 bytes, Remaining: 9712 bytes
Required: 512 bytes, Remaining: 9696 bytes
Required: 16 bytes, Remaining: 9184 bytes
Required: 512 bytes, Remaining: 9168 bytes
Required: 16 bytes, Remaining: 8656 bytes
Required: 512 bytes, Remaining: 8640 bytes
Required: 16 bytes, Remaining: 8128 bytes
Required: 512 bytes, Remaining: 8112 bytes
Required: 16 bytes, Remaining: 7600 bytes
Required: 512 bytes, Remaining: 7584 bytes
Required: 16 bytes, Remaining: 7072 bytes
Required: 512 bytes, Remaining: 7056 bytes
Required: 16 bytes, Remaining: 6544 bytes
Required: 512 bytes, Remaining: 6528 bytes
Required: 16 bytes, Remaining: 6016 bytes
Required: 512 bytes, Remaining: 6000 bytes
Required: 16 bytes, Remaining: 5488 bytes
Required: 512 bytes, Remaining: 5472 bytes
Required: 16 bytes, Remaining: 4960 bytes
Required: 512 bytes, Remaining: 4944 bytes
Required: 16 bytes, Remaining: 4432 bytes
Required: 512 bytes, Remaining: 4416 bytes
Required: 16 bytes, Remaining: 3904 bytes
Required: 512 bytes, Remaining: 3888 bytes
Required: 16 bytes, Remaining: 3376 bytes
Required: 512 bytes, Remaining: 3360 bytes
Required: 16 bytes, Remaining: 2848 bytes
Required: 512 bytes, Remaining: 2832 bytes
Required: 16 bytes, Remaining: 2320 bytes
Required: 512 bytes, Remaining: 2304 bytes
Required: 16 bytes, Remaining: 1792 bytes
Required: 512 bytes, Remaining: 1776 bytes
Required: 16 bytes, Remaining: 1264 bytes
Required: 512 bytes, Remaining: 1248 bytes
Required: 16 bytes, Remaining: 736 bytes
Required: 512 bytes, Remaining: 720 bytes
Required: 16 bytes, Remaining: 208 bytes
Required: 176 bytes, Remaining: 192 bytes
Required: 16 bytes, Remaining: 16 bytes
Firmware is successfully downloaded!
SDIO->STA=0x00000000
5樓 巨大八爪鱼 2017-7-6 22:31
兩個固件文件(*.bin)可在marvell的官方網站上下載到。
【獲取固件數組的PC端程序】
#include <stdio.h>
#include <Windows.h>

#define FOLDER "E:\\Users\\Octopus\\Downloads\\SD-8686-LINUX26-SYSKT-9.70.3.p24-26409.P45-GPL\\SD-8686-FEDORA26FC6-SYSKT-GPL-9.70.3.p24-26409.P45\\FwImage"
#define LINELEN 24

void create(char *binfile, char *cfile, char *varname)
{
    char str[100];
    DWORD size = 0;
    FILE *fp, *fp2;
    FILETIME last_write_time;
    HANDLE hFile;
    int linecnt = 0;
    SYSTEMTIME st_local, st_utc;
    unsigned char data;

    hFile = CreateFileA(binfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, (DWORD)NULL, NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        size = GetFileSize(hFile, NULL);
        GetFileTime(hFile, NULL, NULL, &last_write_time);
        FileTimeToSystemTime(&last_write_time, &st_utc);
        SystemTimeToTzSpecificLocalTime(NULL, &st_utc, &st_local);
        CloseHandle(hFile);
    }

    fopen_s(&fp, binfile, "rb");
    if (fp == NULL)
    {
        printf("Cannot open %s!\n", binfile);
        return;
    }
    fopen_s(&fp2, cfile, "w");
    if (fp2 == NULL)
    {
        fclose(fp);
        printf("Cannot open %s!\n", cfile);
        return;
    }

    GetDateFormatA(LOCALE_USER_DEFAULT, (DWORD)NULL, &st_local, NULL, str, sizeof(str));
    fprintf(fp2, "// From: %s\n// Last Modified: %s ", binfile, str);
    GetTimeFormatA(LOCALE_USER_DEFAULT, (DWORD)NULL, &st_local, NULL, str, sizeof(str));
    fprintf(fp2, "%s\n", str);

    fprintf(fp2, "const unsigned char %s[%d] = {", varname, size);
    while (data = fgetc(fp), !feof(fp))
    {
        if (linecnt == 0)
            fputs("\n\t", fp2);
        fprintf(fp2, "0x%02x, ", data);
        linecnt = (linecnt + 1) % LINELEN;
    }

    fseek(fp2, -2, SEEK_CUR);
    fputs("\n};\n", fp2);

    fclose(fp);
    fclose(fp2);
}

int main(void)
{
    SetCurrentDirectoryA(FOLDER); // 設置當前目錄
    create("helper_sd.bin", "helper_sd.c", "firmware_helper_sd");
    create("sd8686.bin", "sd8686.c", "firmware_sd8686");
    return 0;
}
6樓 巨大八爪鱼 2017-7-7 18:25
代碼更新
【WiFi.c】
#include <stdio.h>
#include <stm32f10x.h>
#include <string.h>
#include "WiFi.h"

extern const unsigned char firmware_helper_sd[2516];
extern const unsigned char firmware_sd8686[122916];

uint16_t rca;

void delay(uint16_t n);
void dump_data(uint8_t *data, uint16_t len);

// 檢查命令是否收到了回應, 若沒收到則重發命令
void WiFi_CheckCmdTimeout(void)
{
    while (SDIO->STA & SDIO_STA_CTIMEOUT)
    {
        SDIO->ICR = SDIO_ICR_CTIMEOUTC; // 清除標誌
        SDIO->CMD = SDIO->CMD; // 重發
        printf("Timeout! Resend CMD%d\n", SDIO->CMD & SDIO_CMD_CMDINDEX);
        while (SDIO->STA & SDIO_STA_CMDACT);
    }
}

// marvell-88w8686-固件下載程序說明.doc
void WiFi_DownloadFirmware(void)
{
    uint8_t helper_buf[64];
    const uint8_t *data;
    uint16_t size;
    uint32_t addr, len;
   
    // 塊大小設為32
    SDIO->DCTRL &= ~SDIO_DCTRL_DTEN;
    SDIO->DCTRL = (SDIO->DCTRL & ~SDIO_DCTRL_DBLOCKSIZE) | SDIO_DCTRL_DBLOCKSIZE_2 | SDIO_DCTRL_DBLOCKSIZE_0;
    WiFi_SetBlockSize(1); // 應用到Function 1
   
    // 下載helper
    addr = WiFi_Read(1, 0x00) | (WiFi_Read(1, 0x01) << 8) | (WiFi_Read(1, 0x02) << 16);
    data = firmware_helper_sd;
    len = sizeof(firmware_helper_sd);
    while (len)
    {
        // 每次下載64位元組, 其中前4位元組為本次下載的數據量
        size = (len > 60) ? 60 : len;
        *(uint32_t *)helper_buf = size;
        memcpy(helper_buf + 4, data, size);
       
        WiFi_Wait();
        WiFi_WriteData(1, addr, helper_buf, 2, CMD53_BLOCKMODE);
        len -= size;
        data += size;
    }
    *(uint32_t *)helper_buf = 0;
    WiFi_WriteData(1, addr, helper_buf, 2, CMD53_BLOCKMODE); // 以空數據包結束
   
    // 下載固件
    data = firmware_sd8686;
    len = sizeof(firmware_sd8686);
    while (len)
    {
        WiFi_Wait();
        while ((size = WiFi_Read(1, WIFI_SQREADBASEADDR0) | (WiFi_Read(1, WIFI_SQREADBASEADDR1) << 8)) == 0); // 獲取本次下載的位元組數
        printf("Required: %d bytes, Remaining: %d bytes\n", size, len);
        if (size & 1)
        {
            printf("Error: an odd size is invalid!\n"); // 若size為奇數(如17)則認為出錯
            return;
        }
        if (size > len)
            size = len;
       
        if (size % 32 == 0)
            WiFi_WriteData(1, addr, data, size / 32, CMD53_BLOCKMODE); // 若size為數據塊大小的整數倍, 則採用數據塊方式下載
        else
            WiFi_WriteData(1, addr, data, size, 0); // 否則採用位元組流方式下載

        if (SDIO->STA)
        {
            // STA不為0則表明有錯誤
            printf("Data transfer error! SDIO->STA=0x%08x\n", SDIO->STA);
            return;
        }
       
        len -= size;
        data += size;
    }
   
    // 等待Firmware啟動
    while (WiFi_Read(1, 0x34) != 0xdc ||  WiFi_Read(1, 0x35) != 0xfe);
    printf("Firmware is successfully downloaded!\n");
}

// SDIO Simplified Specification Version 3.00
// 3. SDIO Card Initialization
void WiFi_Init(void)
{
    uint8_t i, func_cnt;
    printf("Initialization begins...\n");
    SDIO->POWER = SDIO_POWER_PWRCTRL;
    SDIO->CLKCR = SDIO_CLKCR_CLKEN | 178; // 初始化時最高允許的頻率: 72MHz/(178+2)=400kHz
    delay(5); // 延時可防止CMD5重發
   
    // 不需要發送CMD0, 因為SD I/O card的初始化命令是CMD52
    // An I/O only card or the I/O portion of a combo card is NOT reset by CMD0. (See 4.4 Reset for SDIO)
   
    /* 發送CMD5: IO_SEND_OP_COND */
    SDIO->CMD = SDIO_CMD_CPSMEN | SDIO_CMD_WAITRESP_0 | 5;
    while (SDIO->STA & SDIO_STA_CMDACT);
    WiFi_CheckCmdTimeout(); // 為了保險起見還是要檢查一下是否要重發命令
    if (SDIO->STA & SDIO_STA_CMDREND)
    {
        SDIO->ICR = SDIO_ICR_CMDRENDC;
        WiFi_ShowShortResponse();
    }
   
    /* 設置參數VDD Voltage Window: 3.2~3.4V, 並再次發送CMD5 */
    SDIO->ARG = 0x300000;
    SDIO->CMD = SDIO->CMD;
    while (SDIO->STA & SDIO_STA_CMDACT);
    if (SDIO->STA & SDIO_STA_CMDREND)
    {
        SDIO->ICR = SDIO_ICR_CMDRENDC;
        WiFi_ShowShortResponse();
        if (SDIO->RESP1 & _BV(31))
        {
            // Card is ready to operate after initialization
            func_cnt = (SDIO->RESP1 >> 28) & 7;
            printf("Number of I/O Functions: %d\n", func_cnt);
            printf("Memory Present: %d\n", (SDIO->RESP1 & _BV(27)) != 0);
        }
    }
   
    /* 獲取WiFi模塊地址 (CMD3: SEND_RELATIVE_ADDR, Ask the card to publish a new relative address (RCA)) */
    SDIO->ARG = 0;
    SDIO->CMD = SDIO_CMD_CPSMEN | SDIO_CMD_WAITRESP_0 | 3;
    while (SDIO->STA & SDIO_STA_CMDACT);
    if (SDIO->STA & SDIO_STA_CMDREND)
    {
        SDIO->ICR = SDIO_ICR_CMDRENDC;
        rca = SDIO->RESP1 >> 16;
        printf("Relative card address: 0x%04x\n", rca);
    }
   
    /* 選中WiFi模塊 (CMD7: SELECT/DESELECT_CARD) */
    SDIO->ARG = rca << 16;
    SDIO->CMD = SDIO_CMD_CPSMEN | SDIO_CMD_WAITRESP_0 | 7;
    while (SDIO->STA & SDIO_STA_CMDACT);
    if (SDIO->STA & SDIO_STA_CMDREND)
    {
        SDIO->ICR = SDIO_ICR_CMDRENDC;
        printf("Card selected! status=0x%08x\n", SDIO->RESP1);
    }
   
    // 提高時鐘頻率
    SDIO->CLKCR = (SDIO->CLKCR & ~SDIO_CLKCR_CLKDIV) | 70; // 72MHz/(70+2)=1MHz
    SDIO->DTIMER = 1000000; // 當頻率為1MHz時, 超時時間為1秒
    //SDIO->CLKCR = (SDIO->CLKCR & ~SDIO_CLKCR_CLKDIV) | 1; // 72MHz/(1+2)=24MHz
   
    /* 選擇總線寬度 (Wide Bus Selection) */
    // For an SDIO card a write to the CCCR using CMD52 is used to select bus width. (See 4.5 Bus Width)
    // CMD52: IO_RW_DIRECT, CCCR: Card Common Control Registers
    WiFi_Write(0, 0x07, WiFi_Read(0, 0x07) | 0x02); // Bus Width: 4-bit bus
    SDIO->CLKCR |= SDIO_CLKCR_WIDBUS_0;
   
    // 設置數據塊大小為256位元組
    SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3;
    WiFi_SetBlockSize(0); // 應用到Function 0
   
    // 初始化Function 1
    WiFi_Write(0, 0x02, 0x02); // IOE1=1 (Enable Function)
    while ((WiFi_Read(0, 3) & 0x02) == 0); // 等到IOR1=1 (I/O Function Ready)
   
    // 顯示CIS信息
    for (i = 0; i <= func_cnt; i++)
        WiFi_ShowCIS(i);
}

// 讀寄存器
uint8_t WiFi_Read(uint8_t func, uint32_t addr)
{
    WiFi_SendCMD52(func, addr, NULL, NULL);
    if (SDIO->STA & SDIO_STA_CMDREND)
    {
        SDIO->ICR = SDIO_ICR_CMDRENDC;
        return SDIO->RESP1 & 0xff;
    }
    else
    {
        printf("WiFi_Read failed, SDIO->STA=0x%08x!\n", SDIO->STA);
        return 0;
    }
}

// 讀數據
void WiFi_ReadData(uint8_t func, uint32_t addr, uint8_t *data, uint16_t count, uint32_t flags)
{
    uint32_t len;
    if (flags & CMD53_BLOCKMODE)
    {
        len = count * WiFi_GetBlockSize(); // count表示數據塊數
        SDIO->DCTRL &= ~SDIO_DCTRL_DTMODE; // Block模式
    }
    else
    {
        len = count; // count表示位元組數
        SDIO->DCTRL |= SDIO_DCTRL_DTMODE; // Multibyte模式
    }
    SDIO->DLEN = len;
    SDIO->DCTRL |= SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTEN; // 設置傳輸方向為從卡到主機
   
    WiFi_SendCMD53(func, addr, count, flags);
    while (len)
    {
        if (SDIO->STA & SDIO_STA_RXDAVL)
        {
            if (len >= 4)
            {
                *(uint32_t *)data = SDIO->FIFO;
                data += 4;
                len -= 4;
            }
            else
            {
                count = len; // 剩餘位元組數
                len = SDIO->FIFO; // 剩餘數據
                memcpy(data, &len, count);
                len = 0;
            }
        }
       
        if (SDIO->STA & SDIO_STA_DTIMEOUT)
        {
            printf("Data Timeout!\n");
            SDIO->DCTRL &= ~SDIO_DCTRL_DTEN;
            return;
        }
        else if (SDIO->STA & SDIO_STA_DCRCFAIL)
        {
            printf("Data CRC check failed! %d bytes are lost\n", len);
            SDIO->ICR = SDIO_ICR_DCRCFAILC;
            SDIO->DCTRL &= ~SDIO_DCTRL_DTEN;
            return;
        }
    }
   
    while (SDIO->STA & (SDIO_STA_CMDACT | SDIO_STA_RXACT));
    SDIO->DCTRL &= ~SDIO_DCTRL_DTEN;
   
    SDIO->ICR = SDIO_STA_DATAEND | SDIO_ICR_CMDRENDC;
    if (flags & CMD53_BLOCKMODE)
        SDIO->ICR = SDIO_ICR_DBCKENDC;
   
    // 通過判斷SDIO->STA是否等於0可知傳輸是否成功
}

void WiFi_SendCMD52(uint8_t func, uint32_t addr, uint8_t data, uint32_t flags)
{
    SDIO->ARG = (func << 28) | (addr << 9) | data | flags;
    SDIO->CMD = SDIO_CMD_CPSMEN | SDIO_CMD_WAITRESP_0 | 52;
    while (SDIO->STA & SDIO_STA_CMDACT);
}

void WiFi_SendCMD53(uint8_t func, uint32_t addr, uint16_t count, uint32_t flags)
{
    SDIO->ARG = (func << 28) | (addr << 9) | count | flags;
    SDIO->CMD = SDIO_CMD_CPSMEN | SDIO_CMD_WAITRESP_0 | 53;
}

void WiFi_SetBlockSize(uint8_t func)
{
    // Part E1: 6.9 Card Common Control Registers (CCCR), 6.10 Function Basic Registers (FBR)
    uint16_t size = WiFi_GetBlockSize();
    WiFi_Write(0, (func << 8) | 0x10, size & 0xff);
    WiFi_Write(0, (func << 8) | 0x11, size >> 8);
}

void WiFi_ShowCIS(uint8_t func)
{
    uint8_t data[255];
    uint8_t i, len;
    uint8_t tpl_code, tpl_link; // 16.2 Basic Tuple Format and Tuple Chain Structure
    uint32_t cis_ptr;
   
    // 獲取CIS的地址
    cis_ptr = (func << 8) | 0x9;
    cis_ptr    = WiFi_Read(0, cis_ptr) | (WiFi_Read(0, cis_ptr + 1) << 8) | (WiFi_Read(0, cis_ptr + 2) << 16);
    printf("Pointer to Function %d Card Information Structure (CIS): 0x%08x\n", func, cis_ptr);
   
    // 遍歷CIS, 直到尾節點
    while ((tpl_code = WiFi_Read(0, cis_ptr++)) != CISTPL_END)
    {
        if (tpl_code == CISTPL_NULL)
            continue;
       
        tpl_link = WiFi_Read(0, cis_ptr++); // 本結點數據的大小
        for (i = 0; i < tpl_link; i++)
            data[i] = WiFi_Read(0, cis_ptr + i);
       
        printf("[CIS Tuple 0x%02x] addr=0x%08x size=%d\n", tpl_code, cis_ptr - 2, tpl_link);
        dump_data(data, tpl_link);
        switch (tpl_code)
        {
        case CISTPL_VERS_1:
            i = 2;
            while (data[i] != 0xff)
            {
                len = strlen((char *)&data[i]);
                if (len != 0)
                    printf("%s\n", data + i);
                i += len + 1;
            }
            break;
        case CISTPL_MANFID:
            // 16.6 CISTPL_MANFID: Manufacturer Identification String Tuple
            printf("SDIO Card manufacturer code: 0x%04x\n", *(uint16_t *)data); // TPLMID_MANF
            printf("manufacturer information (Part Number and/or Revision): 0x%04x\n", *(uint16_t *)(data + 2)); // TPLMID_CARD
            break;
        case CISTPL_FUNCID:
            // 16.7.1 CISTPL_FUNCID: Function Identification Tuple
            printf("Card function code: 0x%02x\n", data[0]); // TPLFID_FUNCTION
            printf("System initialization bit mask: 0x%02x\n", data[1]); // TPLFID_SYSINIT
            break;
        case CISTPL_FUNCE:
            // 16.7.2 CISTPL_FUNCE: Function Extension Tuple
            if (data[0] == 0)
            {
                // 16.7.3 CISTPL_FUNCE Tuple for Function 0 (Extended Data 00h)
                printf("maximum block size: %d\n", *(uint16_t *)(data + 1));
                printf("maximum transfer rate code: 0x%02x\n", data[3]);
            }
            else
            {
                // 16.7.4 CISTPL_FUNCE Tuple for Function 1-7 (Extended Data 01h)
                printf("maximum block size: %d\n", *(uint16_t *)(data + 0x0c)); // TPLFE_MAX_BLK_SIZE
            }
        }
       
        cis_ptr += tpl_link;
        if (tpl_link == 0xff)
            break; // 當TPL_LINK為0xff時說明當前結點為尾節點
    }
}

void WiFi_ShowShortResponse(void)
{
    printf("Command response received: CMD%d, RESP_%08x\n", SDIO->RESPCMD, SDIO->RESP1);
}

void WiFi_Wait(void)
{
    uint8_t status;
    do
    {
        status = WiFi_Read(1, WIFI_CARDSTATUS);
    } while ((status & WIFI_CARDSTATUS_IOREADY) == 0 || (status & WIFI_CARDSTATUS_DNLDCARDRDY) == 0);
}

// 寫寄存器, 返回寫入後寄存器的實際內容
uint8_t WiFi_Write(uint8_t func, uint32_t addr, uint8_t value)
{
    WiFi_SendCMD52(func, addr, value, CMD52_WRITE | CMD52_READAFTERWRITE);
    if (SDIO->STA & SDIO_STA_CMDREND)
    {
        SDIO->ICR = SDIO_ICR_CMDRENDC;
        return SDIO->RESP1 & 0xff;
    }
    else
    {
        printf("WiFi_Write failed, SDIO->STA=0x%08x!\n", SDIO->STA);
        return 0;
    }
}

// 寫數據
void WiFi_WriteData(uint8_t func, uint32_t addr, const uint8_t *data, uint16_t count, uint32_t flags)
{
    uint32_t len;
    if (flags & CMD53_BLOCKMODE)
    {
        len = count * WiFi_GetBlockSize();
        SDIO->DCTRL &= ~SDIO_DCTRL_DTMODE;
    }
    else
    {
        len = count;
        SDIO->DCTRL |= SDIO_DCTRL_DTMODE;
    }
    SDIO->DLEN = len;
    SDIO->DCTRL &= ~SDIO_DCTRL_DTDIR; // 設置傳輸方向: 從主機到外設
   
    WiFi_SendCMD53(func, addr, count, flags | CMD53_WRITE);
    while (SDIO->STA & SDIO_STA_CMDACT);
    if ((SDIO->STA & SDIO_STA_CMDREND) == 0)
        return;
    SDIO->ICR = SDIO_ICR_CMDRENDC;
   
    SDIO->DCTRL |= SDIO_DCTRL_DTEN; // 開始發送數據
    while (len)
    {
        if (len >= 4)
        {
            SDIO->FIFO = *(uint32_t *)data;
            data += 4;
            len -= 4;
        }
        else
        {
            count = len; // count變量用於存放剩餘位元組數
            len = 0; // 用於裝載剩餘的數據(len是32位的變量)
            memcpy(&len, data, count);
            SDIO->FIFO = len; // 發送剩餘的數據, 高位用0填充
            len = 0; // 清零, 用於退出循環
        }
        while (SDIO->STA & SDIO_STA_TXFIFOF); // 如果FIFO已滿則等待
    }
   
    while (SDIO->STA & SDIO_STA_TXACT);
    SDIO->DCTRL &= ~SDIO_DCTRL_DTEN; // 數據傳輸完畢後DTEN應及時清零, 防止後續對DCTRL寄存器操作後誤啟動數據傳輸導致超時或CRC校驗錯誤
   
    SDIO->ICR = SDIO_ICR_DATAENDC;
    if (flags & CMD53_BLOCKMODE)
        SDIO->ICR = SDIO_ICR_DBCKENDC;
}
7樓 巨大八爪鱼 2017-7-8 21:18
其實,對於固件下載的具體步驟、方法,Marvell是有詳細的文檔說明的(屬於機密文檔,官方網站上無法下載到,但能夠從淘寶賣家那裡獲得)
(1)WLAN Subsystem Host Driver, Firmware, Interface Firmware Specification v10.0
(2)WLAN Subsystem Linux Driver Porting Guide
(3)88W8686 Host Interface Registers
8樓 巨大八爪鱼 2017-7-8 21:19

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2024 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。