• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    基于Linux的ARM與FPGA SPI接口驅(qū)動設(shè)計

    2014-01-01 00:00:00陳少華
    計算機光盤軟件與應(yīng)用 2014年6期

    摘 要:本文結(jié)合具體的FPGA與ARM接口電路介紹了SPI接口驅(qū)動程序設(shè)計,并給出了部分程序的核心代碼。本驅(qū)動編寫的思路嚴格按照Linux下字符設(shè)備驅(qū)動程序的要求,并重點介紹了中斷掛載及內(nèi)存映射等關(guān)鍵技術(shù),對其他SPI外設(shè)的驅(qū)動程序設(shè)計有較強的參考意義。

    關(guān)鍵詞:linux;SPI;驅(qū)動

    中圖分類號:TP336

    在某項目的單板設(shè)計中,集成了Altera公司的STRATIX II EP2S180 FPGA和三星公司的S3C2440A ARM9處理器,F(xiàn)PGA用于處理原始數(shù)據(jù),ARM用于配置FPGA參數(shù)并接收FPGA處理后數(shù)據(jù),之間采用SPI串行接口通信。

    SPI接口驅(qū)動基于Linux系統(tǒng)開發(fā),Linux內(nèi)核中雖已集成了SPI驅(qū)動,但接口復雜且冗長,不適宜本項目采用,因此重新設(shè)計了SPI驅(qū)動。

    1 接口電路設(shè)計

    ARM工作在SPI主模式,F(xiàn)PGA工作在SPI從模式,F(xiàn)PGA與ARM間接口電路如圖1所示。

    圖1 接口電路

    ARM使用SPI0控制器,EINT13作為中斷輸入,GPG6用于復位FPGA中斷。

    ARM通過SPIMOSI0接口對FPGA進行參數(shù)配置,而后啟動FPGA進行數(shù)據(jù)處理。FPGA處理完數(shù)據(jù)后通過EINT13對ARM發(fā)送上升沿中斷,觸發(fā)ARM讀取FPGA數(shù)據(jù)。ARM讀取完畢后,通過INT_ACK信號線發(fā)上升沿信號對FPGA進行中斷清除。

    2 SPI驅(qū)動程序設(shè)計

    SPI為串行接口,其驅(qū)動在Linux中沿用字符設(shè)備驅(qū)動格式,字符設(shè)備驅(qū)動接口函數(shù)數(shù)據(jù)結(jié)構(gòu)如下:

    static struct file_operations dev_fops = {

    .owner = THIS_MODULE,

    .open = s3c24xx_SPI_open,

    .release = s3c24xx_SPI_close,

    .read = s3c24xx_SPI_read,

    };

    驅(qū)動程序需要實現(xiàn)s3c24xx_SPI_open、s3c24xx_SPI_close、s3c24xx_SPI_read等幾個關(guān)鍵函數(shù)。

    s3c24xx_SPI_open函數(shù)用于初始化SPI控制器并對FPGA發(fā)送初始化配置參數(shù)并掛載中斷處理函數(shù)。

    s3c24xx_SPI_close函數(shù)用于關(guān)閉FPGA設(shè)備。

    s3c24xx_SPI_read用于讀取FPGA數(shù)據(jù),該函數(shù)通過調(diào)用wait_event_interruptible工作在阻塞模式,由中斷處理函數(shù)負責喚醒 。

    中斷描述結(jié)構(gòu)如下:

    struct spi_irq_desc {

    int irq;

    int pin;

    int pin_setting;

    int number;

    char *name;

    };

    static struct spi_irq_desc spi_irqs [] = {

    {IRQ_EINT13, S3C2410_GPG(5),S3C2410_GPG5_EINT13,2,“SPIINT”},

    };

    在s3c24xx_SPI_open函數(shù)中掛載中斷處理函數(shù)spi_interrupt,具體如下:

    request_irq(spi_irqs[i].irq, spi_interrupt, IRQ_TYPE_EDGE_RISING,

    spi_irqs[i].name,(void *)spi_irqs[i]);

    request_irq將EINT13的處理函數(shù)設(shè)定為spi_interrupt,需要重點注意的是操作系統(tǒng)自動將EINT13引腳配置為中斷模式,并設(shè)置為上升沿觸發(fā),無需用戶再進行GPIO配置。

    在中斷處理函數(shù)中,涉及到對SPI的發(fā)送寄存器和接收寄存器的讀寫操作。在Linux環(huán)境中,由于采用了MMU及虛擬內(nèi)存設(shè)計,無法直接讀寫外部寄存器,需將其映射到內(nèi)存空間,而后采用iowrite32完成讀寫。

    以對SPICON0寄存器寫入0x18示例如下,該寄存器地址為0x59000000:

    spicon0_phys = 0x59000000;

    spi0_virt =(unsigned long)ioremap(spi0_phys, 0x20);

    va_s3c2440_SPI_SPCON0 = (unsigned long *)(spi0_virt + 0x00);

    iowrite32(0x18,va_s3c2440_SPI_SPCON0);

    在spi_interrupt函數(shù)中實現(xiàn)SPI接口讀取,spi字長為8位,spi的接口配置為時鐘上升沿發(fā)送,下降沿讀取。

    因此為讀取FPGA需要對發(fā)送寄存器SPTDAT0先寫一個字節(jié),而后判斷狀態(tài)寄存器SPSTA0是否完成發(fā)送,如果完成則讀取接收寄存器SPRDAT0,從FPGA讀取一個字節(jié),以后循環(huán)讀取定長字節(jié),即可完成對FPGA數(shù)據(jù)的讀取。

    而后對GPG6依次寫0、1、0,之間加入1us延時,即可產(chǎn)生上升沿中斷以復位FPGA中斷。

    對FPGA的讀定長數(shù)據(jù)操作示例如下:

    int s3c2440SPIRead(char* buffer, int nbyte)

    {

    char* pChar = buffer;

    int ix = nbyte;

    for(; nbyte > 0; nbyte--)

    {

    *(volatile char*)va_s3c2440_SPI_SPTDAT0=0x55;

    /*等待傳輸完成*/

    while(?。?((volatile char*)va_s3c2440_SPI_SPSTA0) 0x1));

    *pChar=*(volatile char*)(va_s3c2440_SPI_SPRDAT0);

    pChar++;

    }

    return(ix);

    }

    為避免編譯器將va_s3c2440_SPI_SPTDAT0地址列入CACHE空間,必須對va_s3c2440_SPI_SPTDAT0進行volatile char*強制類型轉(zhuǎn)換,否則將讀到過期數(shù)據(jù)。

    中斷處理函數(shù)完成讀數(shù)據(jù)后調(diào)用wake_up_interruptible(spi_waitq)喚醒阻塞的讀操作s3c24xx_SPI_read,該函數(shù)調(diào)用copy_to_user函數(shù)將數(shù)據(jù)復制到用戶空間。

    3 結(jié)束語

    該接口程序已成功應(yīng)用于某工程項目,本文是基于調(diào)試經(jīng)驗,重點介紹了SPI接口程序框架及內(nèi)存映射和中斷掛載等關(guān)鍵技術(shù),可以作為開發(fā)類似驅(qū)動的參考。

    參考文獻:

    [1]韋東山.嵌入式Linux應(yīng)用開發(fā)[M].北京:人民郵電出版社,2010.

    作者單位:中國船舶重工集團公司第七二二研究所,武漢 430079

    昌黎县| 额尔古纳市| 潼南县| 从江县| 新晃| 贡山| 嘉义县| 宜兰市| 呼伦贝尔市| 金溪县| 全椒县| 宿松县| 莆田市| 绩溪县| 辉县市| 松溪县| 灌阳县| 鄂州市| 瑞昌市| 孟州市| 石台县| 巴林右旗| 岑巩县| 出国| 三亚市| 深圳市| 厦门市| 罗源县| 瑞昌市| 长沙县| 武邑县| 上蔡县| 北海市| 曲阜市| 隆化县| 阿拉善右旗| 海宁市| 镇平县| 安国市| 屯门区| 阳信县|