STM32F103RCT6 升級FPGA(EP2C8Q208)


1 基本說明

EP2C8Q208封裝為208個引腳枢赔,也就是52*4的封裝格式鉴吹。

FPGA啟動方式有三種:jtag驰坊,AS和PS嗡载。使用STM32F103RCT6啟動FPGA窑多,使用的是PS方式。

AS全稱為active serial洼滚,DCLK可以運行在40MHz的頻率上埂息。
PS全稱為passive serial,
JTAG全稱為Joint Test Action Group。

FPGA啟動千康,可以接受的文件有.rbf享幽,.hex和.ttf格式。

使用PS啟動方式拾弃,硬件連接圖可以如下所示:

PS啟動

MSEL等硬件連接需要按照如下所示:

MSEL啟動模式

在開始傳輸時值桩,要將nCONFIG引腳輸出一個從低到高的電平。在nSTATUS為高電平的時候豪椿,單片機類控制芯片需要在DATA[0]上一直放置數(shù)據(jù)奔坟。

寫一下每個引腳以及應(yīng)有的含義:

引腳 輸入輸出 功能
nCONFIG 輸出 開始配置
nSTATUS 輸入 升級響應(yīng)標(biāo)記位以及出錯標(biāo)志
CONFIG_DONE 輸入 升級完成標(biāo)志位
DCLK 輸出 升級數(shù)據(jù)時鐘
DATA[0] 輸出 升級數(shù)據(jù)

在黑金開發(fā)板上設(shè)置為PS模式的時候,需要做到:

引腳名稱 引腳號 FPGA接線
MSEL1 125 GND搭盾,已經(jīng)為低電平
MSEL0 126 拉高咳秉,在第三面的22號腳上
nCONFIG 26 可以接在R3上或者AS的J1的5號引腳上
nSTATUS 121 接在R4上
CONFIG_DONE 123 接在J1上的3號引腳上
DCLK 21 接在J1上的1號引腳上
DATA[0] 20 接在J1上的7號引腳上
INIT_DONE 107 只能飛線接上去

2 數(shù)據(jù)組織格式

發(fā)送數(shù)據(jù)格式為LSB,也就是說首先發(fā)送低位鸯隅。舉個例子:

02 1B EE 01 FA
0100-0000 1101-1000 0111-0111 1000-0000 0101-1111

數(shù)據(jù)在DCLK的上升沿鎖存澜建。FPGA在CONFIG_DONE為高電平的時候進(jìn)入初始化狀態(tài)。

注意要將DCLK的速率設(shè)置在系統(tǒng)的運行頻率以下蝌以。

如果FPGA接收了所有的數(shù)據(jù)炕舵,但是CONFIG_DONE或者INIT_DONE并沒有變?yōu)楦唠娖健纹瑱C等控制類芯片需要重新配置FPGA饼灿。

控制時序圖如下所示:

PS模式時序圖
PS模式時間參數(shù)1
PS模式時間參數(shù)2

3 控制流程

下面說說使用PS方式給FPGA升級程序的流程:

1 . 在上電后幕侠,先將nCONFIG和DCLK設(shè)置為高電平帝美,時間在100ms碍彭,然后將nCONFIG設(shè)置為低電平,時間在2us悼潭。
2 . 檢測nSTATUS庇忌,如果為0,表示FPGA已經(jīng)響應(yīng)配置舰褪,可以進(jìn)行配置了皆疹。否則就是報錯了,正常情況下占拍,在nCONFIG=0后1us之內(nèi)略就,nSTATUS就會為0。
3 . nCONFIG為1晃酒,等待nSTATUS為高表牢,如果超過5us,則說明有錯誤贝次,跳出到步驟1崔兴。
4 . 發(fā)送數(shù)據(jù),并且設(shè)置DCLK=1,然后延時敲茄。
5 . DCLK=0位谋,檢測nSTATUS,如果為0堰燎,則說明有錯誤掏父,則需要重新開始傳送數(shù)據(jù)。
6 . 再次發(fā)送數(shù)據(jù)秆剪,循環(huán)4损同,5兩步步驟,一直等到數(shù)據(jù)發(fā)送完成鸟款。
7 . 數(shù)據(jù)發(fā)送完成之后膏燃,nCONFIG將會置1。若數(shù)據(jù)發(fā)送完成后何什,數(shù)據(jù)不為1组哩,則說明數(shù)據(jù)發(fā)送有誤,需要重新開始配置处渣。
8 . 配置完成之后伶贰,需要等待40個DCLK周期,等待FPGA初始化完成罐栈。不過最好是檢測狀態(tài)黍衙,如果INIT_DONE不為高,說明有誤荠诬,需要跳到步驟1琅翻。

具體可參考下面的圖示:

FPGA程序升級步驟

上圖要注意幾點:
1.FPGA上電啟動過程會持續(xù)100ms。
2.配置過程有三階段:復(fù)位柑贞,配置和初始化方椎。
3.nCONFIG或者nSTATUS引腳電平為低,F(xiàn)PGA會在復(fù)位的狀態(tài)钧嘶。
4.要判斷CONFIG_DONE和INIT_DONE引腳電平棠众,超時則表示錯誤。

4 出錯處理

在配置的時候有决,如果出錯闸拿,nSTATUS引腳會變低,形成內(nèi)部自己復(fù)位书幕。我們在做PS升級FPGA程序的時候新荤,需要將Auto-restart configuration after error選項關(guān)閉,實現(xiàn)自己控制按咒。

5 程序

實驗可以這樣做:STM32開發(fā)板上有ENC28J60網(wǎng)絡(luò)芯片或者其他的網(wǎng)絡(luò)芯片迟隅,使用TFTP下載FPGA生成了的實驗性.rbf文件但骨,將該文件下載到STM32的SPI FLASH上,然后智袭,使用上面1~4部分說明的內(nèi)容奔缠,給FPGA升級程序,現(xiàn)在貼出關(guān)于升級FPGA的實驗性代碼吼野,注意校哎,要多做出錯處理。

#include "stm32_fpga.h"
#include <stm32f10x.h>

#define nSTATUS_rcc                    RCC_APB2Periph_GPIOA
#define nSTATUS_gpio                   GPIOA
#define nSTATUS_pin                    (GPIO_Pin_2)

#define CONFIG_DONE_rcc                RCC_APB2Periph_GPIOA
#define CONFIG_DONE_gpio               GPIOA
#define CONFIG_DONE_pin                (GPIO_Pin_3)

#define nCONFIG_rcc                    RCC_APB2Periph_GPIOA
#define nCONFIG_gpio                   GPIOA
#define nCONFIG_pin                    (GPIO_Pin_1)

#define DCLK_rcc                            RCC_APB2Periph_GPIOB
#define DCLK_gpio                           GPIOB
#define DCLK_pin                            (GPIO_Pin_0)

#define DATA_rcc                            RCC_APB2Periph_GPIOB
#define DATA_gpio                           GPIOB
#define DATA_pin                            (GPIO_Pin_1)

#define FPGA_IO_SET    1
#define FPGA_IO_RESET  0

static void stm32_fpga_delay_us(unsigned int u_delay);

void set_nCONFIG_io_output(unsigned char val);
void set_DCLK_io_output(unsigned char val);
void set_DATA_io_output(unsigned char val);

/*
*           copyright wit_yuan  2017-07-19  
*
*            PA1-----LED1----nCONFIG          
*            PA2-----LED2----nSTATUS         
*            PA3-----LED3----CONFIG_DONE     
*            PB0-----LED4----DCLK            
*            PB1-----LED5----DATA[0]          
*/
void STM32_FPGA_IO_Init( void )
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
 RCC_APB2PeriphClockCmd(nSTATUS_rcc|CONFIG_DONE_rcc|nCONFIG_rcc|DCLK_rcc|DATA_rcc,ENABLE);

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin   = nSTATUS_pin;
    GPIO_Init(nSTATUS_gpio, &GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin   = CONFIG_DONE_pin;
    GPIO_Init(CONFIG_DONE_gpio, &GPIO_InitStructure);
    
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin   = nCONFIG_pin;
        GPIO_Init(nCONFIG_gpio, &GPIO_InitStructure);
    
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin   = DCLK_pin;
        GPIO_Init(DCLK_gpio, &GPIO_InitStructure);  

        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin   = DATA_pin;
        GPIO_Init(DATA_gpio, &GPIO_InitStructure);

        set_nCONFIG_io_output(FPGA_IO_SET);
        set_DCLK_io_output(FPGA_IO_RESET);  
        set_DATA_io_output(FPGA_IO_RESET);  
}

/*
*       copyright wit_yuan 2017-07-19
*
*/
void set_nCONFIG_io_output(unsigned char val){
    switch(val){
        case 0:
                GPIO_ResetBits(nCONFIG_gpio, nCONFIG_pin);
        break;
        case 1:
                GPIO_SetBits(nCONFIG_gpio, nCONFIG_pin);
        break;
    }
}

/*
*       copyright wit_yuan 2017-07-19 
*
*   
*/
void set_DCLK_io_output(unsigned char val){
    switch(val){
        case 0:
                GPIO_ResetBits(DCLK_gpio, DCLK_pin);
        break;
        case 1:
                GPIO_SetBits(DCLK_gpio, DCLK_pin);
        break;
    }
}

/*
*       copyright wit_yuan 2017-07-19
*
*/
void set_DATA_io_output(unsigned char val){
    switch(val){
        case 0:
                GPIO_ResetBits(DATA_gpio, DATA_pin);
        break;
        case 1:
                GPIO_SetBits(DATA_gpio, DATA_pin);
        break;
    }
}

unsigned char get_nSTATUS_io_input( void )
{
    return GPIO_ReadInputDataBit(nSTATUS_gpio, nSTATUS_pin);
}

unsigned char get_CONFIG_DONE_io_input( void )
{
    return GPIO_ReadInputDataBit(CONFIG_DONE_gpio, CONFIG_DONE_pin);
}

static void stm32_fpga_delay_us(unsigned int u_delay)
{
    int i = 0,j=0; 
    for( i = 0 ;  i < 3 ; i++){
        for(j=0;j<u_delay;j++){
            ;
        }
    }
}

unsigned char stm32_send_start_to_fpga( void )
{
        stm32_fpga_delay_us(1000000);
    
        if(get_nSTATUS_io_input() == 0)
        {
            rt_kprintf(" status first low \r\n");
        }           
    
        set_nCONFIG_io_output(FPGA_IO_SET);
        set_DCLK_io_output(FPGA_IO_RESET);  
        set_DATA_io_output(FPGA_IO_RESET);
    
        stm32_fpga_delay_us(10);
    
        /*nCONFIG=0*/
        set_nCONFIG_io_output(FPGA_IO_RESET);
        set_DCLK_io_output(FPGA_IO_RESET);
    
        stm32_fpga_delay_us(2);
        
        set_nCONFIG_io_output(FPGA_IO_SET);
    
        if(get_nSTATUS_io_input() == 0)
        {
            
            rt_kprintf(" fpga reacked \r\n");
            stm32_fpga_delay_us(1000);
            if(get_nSTATUS_io_input()==0)
            {
                
            }
            else
            {
                    rt_kprintf(" status high is right \r\n");   
            }
        }
        else
        {   
            return 1;
        }
        
        rt_kprintf(" fpga config start \r\n");
        
        stm32_fpga_delay_us(5); 

        return 0;
}

/*
*       copyright wit_yuan 2017-07-19 
*
*
*/
unsigned char stm32_send_byte_to_fpga( unsigned char data )
{
    int i = 0;
    unsigned char tmp;
    
    tmp = data;
    for(i = 0 ; i < 8 ; i ++){
        if(tmp & (1<<i)){
                set_DATA_io_output(FPGA_IO_SET);    
        }
        else
        {
                set_DATA_io_output(FPGA_IO_RESET);  
        }
        
        stm32_fpga_delay_us(1);
        
        set_DCLK_io_output(FPGA_IO_SET);
        
        stm32_fpga_delay_us(1);
        set_DCLK_io_output(FPGA_IO_RESET);
        
        /*?ì2anSTATUS£?è?1??a0£?±íê?óD′í?ó*/
        if(get_nSTATUS_io_input()==0){
            return 1;
        }
        
        stm32_fpga_delay_us(1);
    }
    return 0;
}

unsigned char stm32_get_fpga_config_done_flag(   )
{
        if(get_CONFIG_DONE_io_input()==1){
                rt_kprintf(" config done \r\n");
        }
        return get_CONFIG_DONE_io_input();
        //stm32_fpga_delay_us(100000);
}

提供給外部接口的有三個函數(shù):

1.stm32_send_start_to_fpga()瞳步,作用是傳輸起始信號
2.stm32_send_byte_to_fpga()闷哆,作用是傳輸數(shù)據(jù)
3.stm32_get_fpga_config_done_flag(),作用是讀取配置完成的標(biāo)志单起,還需要加上INIT_DONE標(biāo)志

這個程序抱怔,經(jīng)過測算,一個74K的程序嘀倒,需要6s的時間屈留。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市测蘑,隨后出現(xiàn)的幾起案子灌危,更是在濱河造成了極大的恐慌,老刑警劉巖碳胳,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勇蝙,死亡現(xiàn)場離奇詭異,居然都是意外死亡挨约,警方通過查閱死者的電腦和手機味混,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烫罩,“玉大人惜傲,你說我怎么就攤上這事”丛埽” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵时甚,是天一觀的道長骄呼。 經(jīng)常有香客問我吕漂,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任隘梨,我火速辦了婚禮,結(jié)果婚禮上究抓,老公的妹妹穿的比我還像新娘屋灌。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布质欲。 她就那樣靜靜地躺著树埠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嘶伟。 梳的紋絲不亂的頭發(fā)上怎憋,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音九昧,去河邊找鬼绊袋。 笑死,一個胖子當(dāng)著我的面吹牛铸鹰,可吹牛的內(nèi)容都是我干的癌别。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蹋笼,長吁一口氣:“原來是場噩夢啊……” “哼规个!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起姓建,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤诞仓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后速兔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墅拭,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年涣狗,在試婚紗的時候發(fā)現(xiàn)自己被綠了谍婉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡镀钓,死狀恐怖穗熬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丁溅,我是刑警寧澤唤蔗,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站窟赏,受9級特大地震影響妓柜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涯穷,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一棍掐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拷况,春花似錦作煌、人聲如沸掘殴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奏寨。三九已至,卻和暖如春努酸,著一層夾襖步出監(jiān)牢的瞬間服爷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工获诈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留仍源,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓舔涎,卻偏偏與公主長得像笼踩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子亡嫌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容