《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第1頁(yè)
《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第2頁(yè)
《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第3頁(yè)
《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第4頁(yè)
《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第5頁(yè)
已閱讀5頁(yè),還剩96頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

7.1S3C2440SPI接口及CAN總線基礎(chǔ)

7.2SPI寄存器7.3SPI接口CAN協(xié)議驅(qū)動(dòng)函數(shù)分析7.1.1SPI接口基礎(chǔ)

SPI(SerialPeripheralInterface,串行外設(shè)接口)總線系統(tǒng)是一種同步串行外設(shè)接口,它可以使MCU與各種外圍設(shè)備通過(guò)串行方式進(jìn)行通信交換信息,如外圍設(shè)備FLASH、RAM、網(wǎng)絡(luò)控制器、LCD顯示驅(qū)動(dòng)器、A/D轉(zhuǎn)換器和MCU等。7.1S3C2440SPI接口及CAN總線基礎(chǔ)

SPI接口是以主從方式工作的,這種模式通常有一個(gè)主器件和一個(gè)或多個(gè)從器件,其接口包括以下四種信號(hào):

(1)?MOSI:主器件數(shù)據(jù)輸出,從器件數(shù)據(jù)輸入。

(2)?MISO:主器件數(shù)據(jù)輸入,從器件數(shù)據(jù)輸出。

(3)?SCK:時(shí)鐘信號(hào),由主器件產(chǎn)生。

(4)?/SS:從器件使能信號(hào),由主器件控制。

S3C2440SPI接口特性如下:

支持2個(gè)通道SPI;與SPI接口協(xié)議V2.11兼容;8位用于發(fā)送的移位寄存器;8位用于接收的移位寄存器;8位預(yù)分頻邏輯;查詢、中斷和DMA傳送模式。

SPI接口結(jié)構(gòu)圖如圖7-1所示。圖7-1SPI接口結(jié)構(gòu)圖

1.編程步驟

編程步驟如下:

(1)如果ENSCK和SPCONn中的MSTR位都被置位,向SPDATn寄存器寫入一個(gè)字節(jié)的數(shù)據(jù),就啟動(dòng)一次發(fā)送,也可以使用典型的編程步驟來(lái)操作SPI卡。

(2)設(shè)置波特率預(yù)分頻寄存器(SPPREn)。

(3)設(shè)置SPCONn配置SPI模塊。

(4)向SPIDATn中寫入10次0xFF來(lái)初始化MMC或SD卡。

(5)把一個(gè)GPIO(當(dāng)作nSS)清零來(lái)激活MMC或SD卡。

(6)發(fā)送數(shù)據(jù)→核查發(fā)送準(zhǔn)備好標(biāo)志(REDY?=?1),然后向SPDATn中寫數(shù)據(jù)。

(7)接收數(shù)據(jù)(1),禁止SPCONn的TAGD位,正常模式→向SPDAT中寫0Xff,確定REDY被置位后,從讀緩沖區(qū)中讀出數(shù)據(jù)。

(8)接收數(shù)據(jù)(2),使能SPCONn的TAGD位,自動(dòng)發(fā)送虛擬數(shù)據(jù)模式→確定REDY被置位后,從讀緩沖區(qū)中讀出數(shù)據(jù),然后自動(dòng)開始數(shù)據(jù)傳輸。

(9)置位GPIO引腳(當(dāng)作nSS的那個(gè)引腳),停止MMC或SD卡。

2.SPI從設(shè)備FormatB接收數(shù)據(jù)模式

如果SPI從設(shè)備接收模式激活,并且SPI格式被選為B,當(dāng)SPI操作將會(huì)失敗時(shí),內(nèi)部的READY信號(hào)在SPI_CNT減為0前變成高電平。因此,DMA模式的DATA_READ信號(hào)在最后一位被鎖存之前置位。SPI從設(shè)備FormatB接收數(shù)據(jù)模式如圖7-2所示。圖7-2數(shù)據(jù)傳輸格式

3.三種SPI通信模式

SPI通信模式有以下三種:

(1)?DMA模式:該模式不能用于從設(shè)備FormatB格式。

(2)查詢模式:如果接收從設(shè)備采用FormatB格式,則DATA_READ信號(hào)應(yīng)該比SPICLK延遲一個(gè)相位。

(3)中斷模式:如果接收從設(shè)備采用FormatB格式,有FIR和IRQ兩種模式,中斷請(qǐng)求的過(guò)程采用的模式由中斷源決定。7.1.2CAN總線基礎(chǔ)

1.?CAN總線基本概念

CAN(ControllerAreaNetwork)屬于現(xiàn)場(chǎng)總線的范疇,是一種有效支持分布式控制或?qū)崟r(shí)控制的串行通信網(wǎng)絡(luò),是ISO國(guó)際標(biāo)準(zhǔn)化的串行通信協(xié)議。

2.?CAN總線技術(shù)基礎(chǔ)

1)位仲裁

要對(duì)數(shù)據(jù)進(jìn)行實(shí)時(shí)處理,就必須將數(shù)據(jù)快速傳送,這就要求數(shù)據(jù)的物理傳輸通路有較高的速度。在幾個(gè)站同時(shí)需要發(fā)送數(shù)據(jù)時(shí),要求快速地進(jìn)行總線分配。實(shí)時(shí)處理通過(guò)網(wǎng)絡(luò)交換的緊急數(shù)據(jù)有較大的不同。

2)?CAN與其他通信方案的比較

在實(shí)踐中,有兩種重要的總線分配方法:按時(shí)間表分配和按需要分配。

CAN實(shí)現(xiàn)總線分配的方法,可保證當(dāng)不同的站申請(qǐng)總線存取時(shí),明確地進(jìn)行總線分配。這種位仲裁的方法可以解決當(dāng)兩個(gè)站同時(shí)發(fā)送數(shù)據(jù)時(shí)產(chǎn)生的碰撞問(wèn)題。

3)?CAN的報(bào)文格式

在總線中傳送的報(bào)文,每幀由7部分組成。

4)?CAN總線基本特點(diǎn)

CAN總線的基本特點(diǎn)如下:

●棄用傳統(tǒng)的站地址編碼,代之以對(duì)通信數(shù)據(jù)塊進(jìn)行編碼,可以多主方式工作;

●采用非破壞性仲裁技術(shù),當(dāng)兩個(gè)節(jié)點(diǎn)同時(shí)向網(wǎng)絡(luò)上傳送數(shù)據(jù)時(shí),優(yōu)先級(jí)低的節(jié)點(diǎn)主動(dòng)停止數(shù)據(jù)發(fā)送,而優(yōu)先級(jí)高的節(jié)點(diǎn)可不受影響繼續(xù)傳輸數(shù)據(jù),有效避免了總線沖突;●采用短幀結(jié)構(gòu),每一幀的有效字節(jié)數(shù)為8個(gè),數(shù)據(jù)傳輸時(shí)間短,受干擾的概率低,重新發(fā)送的時(shí)間短;

●每幀數(shù)據(jù)都有CRC校驗(yàn)及其他檢錯(cuò)措施,保證了數(shù)據(jù)傳輸?shù)母呖煽啃?,適于在高干擾環(huán)境下使用;

●節(jié)點(diǎn)在錯(cuò)誤嚴(yán)重的情況下,具有自動(dòng)關(guān)閉總線的功能,切斷它與總線的聯(lián)系,可使總線上其他操作不受影響;

●可以點(diǎn)對(duì)點(diǎn),一對(duì)多及廣播集中方式傳送和接收數(shù)據(jù)。7.1.3SPI接口CAN協(xié)議實(shí)現(xiàn)硬件電路

MCP2510是美國(guó)微芯科技(MICROCHIP)生產(chǎn)的一款CAN總線協(xié)議控制器,完全支持CAN總線V2.0A/B技術(shù)規(guī)范。

基于MCP2510芯片的CAN總線協(xié)議控制硬件電路如圖7-3所示。圖7-3基于MCP2510芯片的CAN總線協(xié)議控制硬件電路7.2.1SPI寄存器基礎(chǔ)(SPCONn)

1.?SPI接口控制寄存器

SPI接口控制寄存器的各位定義如表7-1和表7-2所示。7.2SPI寄存器表7-1SPI接口控制寄存器表7-2SPI接口控制寄存器位定義2.?SPI狀態(tài)寄存器(SPSTAn)

SPI狀態(tài)寄存器的各位定義如表7-3和表7-4所示。

3.?SPI引腳控制寄存器(SPPINn)

SPI引腳控制寄存器的各位定義如表7-5和表7-6所示。表7-3SPI狀態(tài)寄存器表7-4SPI狀態(tài)寄存器位定義表7-5SPI引腳控制寄存器表7-6SPI引腳控制寄存器位定義4.?SPI波特率預(yù)分頻寄存器(SPIPREn)

SPI波特率預(yù)分頻寄存器的各位定義如表7-7和表7-8所示。

5.?SPI發(fā)送數(shù)據(jù)寄存器(SPTDATEn)

SPI發(fā)送數(shù)據(jù)寄存器的各位定義如表7-9和表7-10所示。表7-7SPI波特率預(yù)分頻寄存器表7-8SPI波特率預(yù)分頻寄存器位定義表7-9SPI發(fā)送數(shù)據(jù)寄存器表7-10SPI發(fā)送數(shù)據(jù)寄存器位定義6.?SPI接收數(shù)據(jù)寄存器(SPRDATEn)

SPI接收數(shù)據(jù)寄存器的各位定義如表7-11和表7-12所示。表7-11SPI接收數(shù)據(jù)寄存器表7-12SPI接收數(shù)據(jù)寄存器位定義7.2.2SPI寄存器地址和相關(guān)功能

S3C2440SPI控制器相關(guān)寄存器地址及初始值定義如下:

#defineCHIP_SELECT_nSS0 0xFFFFFFFB

#defineCHIP_DESELECT_nSS0 0x00000004

#defineSPI_INTERNAL_CLOCK_ENABLE(1<<18)//EnableCPUclocktoSPIcontroller

//GPIO配置Masks

#defineCLEAR_GPG2_MASK 0xFFFFFFCF

#defineENABLE_GPG2_OUTPUT 0x00000010

#defineENABLE_GPG2_PULLUP 0x0000FFFB#defineENABLE_SPICLK0 0x08000000

#defineENABLE_SPIMSIO 0x02800000 //SPI輸出和輸入

#defineDISABLE_SPICLK_SPIMSIO_PULLUP 0x00003800

#defineTEST 0x00003800

#defineSPI_MODE_POLLING 0x00000000 //Datatransfermodes

#defineSPI_MODE_DMA 0x00000040

#defineSPI_MODE_INTERRUPT 0x00000020

#defineSPI_CLOCK_ENABLE 0x00000010 //EnableSPIclock(inmastermode)#defineSPI_SELECT_MASTER 0x00000008 //Selectmastermode

#defineSPI_CLOCK_POLARITY_HIGH0x00000000 //Determinesactiveclocktype(highorlow)

#defineSPI_CLOCK_POLARITY_LOW 0x00000004

#defineSPI_CLOCK_PHASE_FORMAT_A 0x00000000 //Determinestransferformat(AorB)

#defineSPI_CLOCK_PHASE_FORMAT_B 0x00000002

#defineSPI_TX_AUTO_GARBAGE

0x00000001 //Usedwhenonlyreceivingdata

#defineSPI_DATA_COLLISION 0x00000004//IndicatesI/Otimingerror(seedatasheet)#defineSPI_MULTI_MASTER_ERROR 0x00000002

//Indicatesbothsender/recieverconfiguredasMaster

#defineSPI_TRANSFER_READY 0x00000001//IndicatesSPIisreadytotransfer/receive

#defineSPI_MULTI_MASTER_ERROR_ENABLE 0x00000006

//Enablescheckingformulti-mastererror

#defineSPI_MASTER_OUT_KEEP0x00000003//DeterminesMOSIdriveorrelease(seedatasheet)

#defineCLK_RATE_FULL 0x00 //FullMasterclock

#defineCLK_RATE_HALF 0x01 //1/2Masterclock#defineCLK_RATE_FOUR 0x02 //1/4Masterclock

#defineCLK_RATE_EIGHT 0x03 //1/8Masterclock

#defineCLK_RATE_SIXTEEN 0x04 //1/16Masterclock

#defineCLK_RATE_THIRTY2 0x05 //1/32Masterclock

#defineCLK_RATE_SIXTY4 0x06 //1/64Masterclock

#defineCLK_RATE_SLOW 0x07 基于SPI接口的CAN總線協(xié)議控制驅(qū)動(dòng)程序結(jié)構(gòu)如圖7-4所示。7.3SPI接口CAN協(xié)議驅(qū)動(dòng)函數(shù)分析圖7-4SPI接口CAN協(xié)議驅(qū)動(dòng)架構(gòu)7.3.1SPI接口CAN協(xié)議驅(qū)動(dòng)數(shù)據(jù)結(jié)構(gòu)與相關(guān)變量

1.?MCP_device結(jié)構(gòu)體

MCP_device描述了CAN驅(qū)動(dòng)相關(guān)屬性,代碼描述如下:

structMCP_device

{

volatileunsignedlongRecvBuf;

volatileunsignedlongRecvHead;

volatileunsignedlongRecvTail;

volatileunsignedlongRecvNum;

wait_queue_head_tinq;//oruseasaglobalvariable

structsemaphoresem;//semaphoreusedformutex

unsignedintIrqNum;

unsignedintMinorNum;/*deviceminornumber*/

unsignedintBaudRate;

unsignedchar*SendBuf;

unsignedintSendNum;

volatileunsignedlongSendHead;

volatileunsignedlongSendTail;

};

2.驅(qū)動(dòng)文件操作遍歷Fops

Fops主要完成對(duì)CAN驅(qū)動(dòng)的字符類型驅(qū)動(dòng)的上層調(diào)用操作,代碼描述如下:

structfile_operationsFops=

{

.open=device_open, //open

.release=device_release, //release

.read=device_read,

.write=device_write

};7.3.2驅(qū)動(dòng)程序結(jié)構(gòu)與主要函數(shù)

1.模塊初始化函數(shù)mcpcan_init_module

mcpcan_init_module函數(shù)主要完成CAN驅(qū)動(dòng)的注冊(cè),代碼描述如下:

staticint_initmcpcan_init_module(void)

{

intres;

res=register_chrdev(MCP_major,“MCPCAN”,&Fops);

if(res<0){

printk(“deviceregisterfailedwith%d.\n”,res);

returnres;

}

if(MCP_major==0)MCP_major=res;

MCP_device_init();//mapspiregsforspi.c

spcon0=ioremap(0x59000000,4);

spsta0=ioremap(0x59000004,4);

sppin0=ioremap(0x59000008,4);

sppre0=ioremap(0x5900000c,4);

sptdat0=ioremap(0x59000010,4);

sprdat0=ioremap(0x59000014,4);

spcon1=ioremap(0x59000020,4);

spsta1=ioremap(0x59000024,4);

sppin1=ioremap(0x59000028,4);

sppre1=ioremap(0x5900002c,4);

sptdat1=ioremap(0x59000030,4);

sprdat1=ioremap(0x59000034,4);

return0;

}

2.驅(qū)動(dòng)卸載函數(shù)mcpcan_cleanup_module

mcpcan_cleanup_module函數(shù)主要完成驅(qū)動(dòng)的卸載,代碼描述如下:

staticvoid_exitmcpcan_cleanup_module(void)

{

inti;

unregister_chrdev(MCP_major,“MCPCAN”);

for(i=0;i<2;i++){

kfree((void*)Device[i]->RecvBuf);

kfree(Device[i]->SendBuf);

kfree(Device[i]);

}

}

3.驅(qū)動(dòng)設(shè)置初始化函數(shù)MCP_device_init

MCP_device_init函數(shù)主要用來(lái)對(duì)structMCP_device進(jìn)行初始化,代碼描述如下:

staticintMCP_device_init(void)

{

intres,i;

//printk(KERN_ERR“hello,enter%s\n”,__FUNCTION__);

for(i=0;i<MCP_NUM;i++)

{

Device[i]=kmalloc(sizeof(structMCP_device),GFP_KERNEL); //mallocthedevicestruct

if(Device[i]==NULL)

{

printk(KERN_ALERT“allocatedevicememoryfailed.\n”);

return(-ENOMEM);

}

memset((char*)Device[i],0,sizeof(structMCP_device));//Device[i]->RecvBuf=(unsignedchar*)get_free_page(GFP_KERNEL);//malloctherecvbuffer

Device[i]->RecvBuf=(unsignedlong)kmalloc(sizeof(structMCP_device)*100,GFP_KERNEL);

//malloctherecvbuffer

if(Device[i]->RecvBuf==0)

{

printk(KERN_ALERT“allocateRecvmemoryfailed.\n”);

return(-ENOMEM);

}

memset((char*)Device[i]->RecvBuf,0,sizeof(structMCP_device)*100);Device[i]->RecvHead=Device[i]->RecvBuf;

Device[i]->RecvTail=Device[i]->RecvBuf;

Device[i]->RecvNum=0;

//Device[i]->RecvQueue=NULL;

//Device[i]->SendBuf=(unsignedchar*)get_free_page(GFP_KERNEL);

//mallocthesendbuffer

Device[i]->SendBuf=kmalloc(sizeof(structMCP_device)*100,GFP_KERNEL);

//mallocthesendbufferif(Device[i]->SendBuf==NULL)

{

printk(KERN_ALERT“allocateSendmemoryfailed.\n”);

return(-ENOMEM);

}

memset((char*)Device[i]->SendBuf,0,sizeof(structMCP_device)*100);

Device[i]->MinorNum=i;

//Device[i]->FrameMode=1;

Device[i]->IrqNum=MCP_irq[i];

//Device[i]->BaudRate=MCP_baudrate[i];

init_waitqueue_head(&(Device[i]->inq));

//init_waitqueue_head(&(Device[i]->outq));

init_MUTEX(&(Device[i]->sem));

}

return0;

}

4.寄存器初始化函數(shù)MCP2510_Init

MCP2510_Init函數(shù)用來(lái)調(diào)用SPI接口的相關(guān)函數(shù),完成2510的初始化,代碼描述如下:

voidMCP2510_Init(intMinorNum)

{

SPI_Init();

/*復(fù)位控制器*/

CAN_SPI_CMD(SPI_CMD_RESET,ARG_UNUSED,ARG_UNUSED,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->CANCTRL)),

0xe0,0x80); //CONFIGMODE//直到進(jìn)入配置模式

while((CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->

CANSTAT)),ARG_UNUSED,ARG_UNUSED)>>5)!=0x04);

//開始配置

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->BFPCTRL)),

BFPCTRL_INIT_VAL,ARG_UNUSED);CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXRTSCTRL)),

TXRTSCTRL_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,

TOLONG(&(MCP2510_MAP->CNF3)),

CNF3_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->CNF2)),

CNF2_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->CNF1)),

CNF1_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->CANINTE)),

CANINTE_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->CANINTF)),

CANINTF_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->EFLG)),

EFLG_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB0CTRL)),

TXBnCTRL_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB1CTRL)),

TXBnCTRL_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB2CTRL)),

TXBnCTRL_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->RXB0CTRL)),

RXB1CTRL_INIT_VAL,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->RXB1CTRL)),

RXB1CTRL_INIT_VAL,ARG_UNUSED);//切換到一般模式和loopback模式

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->CANCTRL)),

0xe0,0x40);while!

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->CANCTRL)),

0xe0,0x00);

CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->CANSTAT)),

ARG_UNUSED,ARG_UNUSED);

5.?2510數(shù)據(jù)發(fā)送函數(shù)MCP2510_TX

MCP2510_TX函數(shù)主要完成2510的數(shù)據(jù)發(fā)送,代碼描述如下:

oidMCP2510_TX(intTxBuf,intIdType,unsignedintid,intDataLen,char*data)

{

inti,offset;

switch(TxBuf)

{

caseTXBUF0:

offset=0;

break;caseTXBUF1:

offset=0x10;

break;

caseTXBUF2:

offset=0x20;

break;

}

/*設(shè)置幀定義*/

if(IdType==STANDID)

{

//printk(KERN_ERR"STANDID,line%dpassed!\n",__LINE__);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB0SIDL))+offset,

(id&0x7)<<5,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB0SIDH))+offset,

(id>>3)&0xff,ARG_UNUSED);}

elseif(IdType==EXTID)

{

//printk(KERN_ERR“EXTID,line%dpassed!\n”,_LINE_);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB0EID0))+offset,

id&0xff,ARG_UNUSED);

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB0EID8))+offset,

(id>>8)&0xff,ARG_UNUSED);CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB0SIDL)),

((id>>16)&0x3)|0x08,ARG_UNUSED);

}

/*設(shè)置數(shù)據(jù)長(zhǎng)度*/

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB0DLC))

+offset,DataLen,ARG_UNUSED);

//fillthedata

if(DataLen>8)

DataLen=8;

for(i=0;i<DataLen;i++)

{

CAN_SPI_CMD(SPI_CMD_WRITE,TOLONG(&(MCP2510_MAP->TXB0D0))

+offset+i,data[i],ARG_UNUSED);

}

/*初始化傳輸*/

i=0;

while(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->TXB0CTRL))+offset,

ARG_UNUSED,ARG_UNUSED)&0x08)

{

i++;

if(i==1000)printk(“PleaseconnecttheCANPORTwithwire.”);

}

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->

TXB0CTRL))+offset,0x08,0x08);

}

6.?CAN數(shù)據(jù)接收函數(shù)

MCP2510_RX函數(shù)主要完成CAN的數(shù)據(jù)接收,代碼描述如下:

voidMCP2510_RX(intRxBuf,int*IdType,unsignedint*id,int*DataLen,char*data)

{

unsignedintflag;

intoffset,i;

//printk(KERN_ERR“hello,enter%s\n”,F(xiàn)UNCTION__);

switch(RxBuf)

{caseRXBUF0:

flag=0x1;

offset=0x00;

break;

caseRXBUF1:

flag=0x2;

offset=0x10;

break;

}/*等待數(shù)據(jù)幀的到來(lái)*/

while(!(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->CANINTF)),

ARG_UNUSED,ARG_UNUSED)&flag));

/*得到標(biāo)志*/

if(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->RXB0SIDL))+offset,

ARG_UNUSED,ARG_UNUSED)&0x08)

{//Extendedidentifier

if(IdType)

*IdType=EXTID;

if(id)

{*id=(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->RXB0SIDL))+offset,

ARG_UNUSED,ARG_UNUSED)&0x3)<<16;

*id|=(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->RXB0EID8))+offset,

ARG_UNUSED,ARG_UNUSED))<<8;

*id|=(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->RXB0EID0))+offset,

ARG_UNUSED,ARG_UNUSED));

}

}

else

{

//Standardidentifier

if(IdType)

*IdType=STANDID;

if(id)

{*id=(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->

RXB0SIDH))+offset,ARG_UNUSED,ARG_UNUSED))<<3;

*id|=(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->

RXB0SIDL))+offset,ARG_UNUSED,ARG_UNUSED))>>5;

}

}

/*得到數(shù)據(jù)幀的長(zhǎng)度*/

if(DataLen)*DataLen=(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->

RXB0DLC))+offset,ARG_UNUSED,ARG_UNUSED)&0xf);

/*得到數(shù)據(jù)*/

for(i=0;DataLen&&(i<*DataLen)&&data;i++)

{

data[i]=CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->

RXB0D0))+offset+i,ARG_UNUSED,ARG_UNUSED);

}

//clearthereceiveintflag

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->CANINTF)),flag,0x00);

}7.?CAN中斷處理函數(shù)mcpcan0_handler

mcpcan0_handler()函數(shù)主要完成CAN總線的中斷處理,代碼描述如下:

staticirqreturn_tmcpcan0_handler(intirq,void*dev_id,structpt_regs*reg)

{

structMCP_device*dev=dev_id;

structmcpcan_datadatagram;

intwritten;

charregvalue,regvalue2;

//structmcpcan_data*datagramptr;//printk(KERN_ERR“hello,finallyenter%s!!!!!!!!!!!!!!!!!!!!!!!!\n”,__FUNCTION__);

//printk(KERN_ERR“\rexternirq8handled\n”);

regvalue=CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->CANINTE)),

ARG_UNUSED,ARG_UNUSED);

//printk(“CANINTE=0x%02x\n”,regvalue);

regvalue=CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->CANINTF)),

ARG_UNUSED,ARG_UNUSED);//printk("CANINTF=0x%02x\n",regvalue);

if(regvalue&0x01)

{

datagram.BufNo=RXBUF0;

MCP2510_RX(datagram.BufNo,&(datagram.IdType),&(datagram.id),

&(datagram.DataLen),datagram.data);

//printk("RXBUF0\n");//printk("datagram.BufNo=%d\n",datagram.BufNo);

//printk("datagram.IdType=%d\n",datagram.IdType);

//printk("datagram.id=%d\n",datagram.id);

//printk("datagram.DataLen=%d\n",datagram.DataLen);

//printk("datagram.data=%s\n",datagram.data);/*Writea16byterecord.AssumeBUF_SIZEisamultipleof16*/

memcpy((void*)dev->RecvHead,&datagram,sizeof(structmcpcan_data));

//datagramptr=(structmcpcan_data*)dev->RecvHead;

//printk("RecvHead->BufNo=%d\n",datagramptr->BufNo);

//printk("RecvHead->IdType=%d\n",datagramptr->IdType);

//printk("RecvHead->id=%d\n",datagramptr->id);

//printk("RecvHead->DataLen=%d\n",datagramptr->DataLen);

//printk("RecvHead->data=%s\n",datagramptr->data);

incr_buffer_pointer(&(dev->RecvHead),sizeof(structmcpcan_data),dev->MinorNum);

wake_up_interruptible(&(dev->inq));/*awakeanyreadingprocess*/

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->CANINTF)),0x01,0x00);

//infactalreadyclearinterruptbitinRX

}

if(regvalue&0x02)

{

datagram.BufNo=RXBUF1;//thisfunctionshouldberewrittentoreceivedatagramfromRXB1??????????????????

MCP2510_RX(datagram.BufNo,&(datagram.IdType),&(datagram.id),

&(datagram.DataLen),datagram.data);

//printk("RXBUF1\n");

/*Writea16byterecord.AssumeBUF_SIZEisamultipleof16*/

memcpy((void*)dev->RecvHead,&datagram,sizeof(structmcpcan_data));incr_buffer_pointer(&(dev->RecvHead),sizeof(structmcpcan_data),dev->MinorNum);

wake_up_interruptible(&dev->inq);/*awakeanyreadingprocess*/

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->CANINTF)),

0x02,0x00);//infactalreadyclearinterruptbitinRX

}

if(regvalue&0xe0)

{printk("CANerrorwithCANINTF=0x%02x.\n",regvalue);

if(regvalue&0x80)printk("MERRF:messageerror.\n");

if(regvalue&0x40)printk("WAKIF:wakeupinterrupt.\n");

if(regvalue&0x20)printk("ERRIF:CANbuserrorinterrupt.\n");

regvalue2=CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->EFLG)),

ARG_UNUSED,ARG_UNUSED);printk(“EFLG=0x%02x.\n”,regvalue2);

regvalue2=CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->TEC)),

ARG_UNUSED,ARG_UNUSED);

printk(“TEC=0x%02x.\n”,regvalue2);

regvalue2=CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->REC)),

ARG_UNUSED,ARG_UNUSED);

printk(“REC=0x%02x.\n”,regvalue2);

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->CANINTF)),0xe0,0x00);

}if(CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->CANINTF)),

ARG_UNUSED,ARG_UNUSED)&0x1c)

{//didn'topenthe3sendinterrupts

CAN_SPI_CMD(SPI_CMD_BITMOD,TOLONG(&(MCP2510_MAP->CANINTF)),

0x1c,0x00); //clearTXbitsdirectly(itwillset1,butnoint)

}regvalue=CAN_SPI_CMD(SPI_CMD_READ,TOLONG(&(MCP2510_MAP->CANINTF)),

ARG_UNUSED,ARG_UNUSED);

//printk("afterinterruptprocessing,CANINTF=0x%02x\n",regvalue);

returnIRQ_HANDLED;//fla

}8.?SPI接口處理函數(shù)CAN_SPI_CMD

CAN_SPI_CMD函數(shù)主要完成基于SPI接口MCP2510數(shù)據(jù)的發(fā)送和接收,代碼描述如下:

unsignedcharCAN_SPI_CMD(unsignedcharcmd,unsignedlongaddr,unsignedchararg1,

unsignedchararg2)

{

unsignedcharret=0;

unsignedchardata=0; //Emptythespi'stransferandreceivebuffer

//SPI_TXFlush(CAN_SPI_MODULE);

//SPI_RXFlush(CAN_SPI_MODULE);

//StartSPIClock();

//printk("inCAN_SPI_CMD,line%dpassed!\n",__LINE__);

//*(unsignedint*)rGPGDAT=(*(unsignedint*)rGPGDAT)&CHIP_SELECT_nSS0;

writel(readl(rGPGDAT)&CHIP_SELECT_nSS0,rGPGDAT);//setcs:gpg2to0

//printk("inCAN_SPI_CMD,havesetcseffect!\n");switch(cmd)

{

caseSPI_CMD_READ:

//printk(“SPI_CMD_READ\n”

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論