![《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第1頁(yè)](http://file4.renrendoc.com/view8/M01/0A/22/wKhkGWbPG5yASR5EAADJSAAiVrE242.jpg)
![《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第2頁(yè)](http://file4.renrendoc.com/view8/M01/0A/22/wKhkGWbPG5yASR5EAADJSAAiVrE2422.jpg)
![《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第3頁(yè)](http://file4.renrendoc.com/view8/M01/0A/22/wKhkGWbPG5yASR5EAADJSAAiVrE2423.jpg)
![《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第4頁(yè)](http://file4.renrendoc.com/view8/M01/0A/22/wKhkGWbPG5yASR5EAADJSAAiVrE2424.jpg)
![《基于S3C2440的嵌入式Linux開發(fā)實(shí)例》課件第7章_第5頁(yè)](http://file4.renrendoc.com/view8/M01/0A/22/wKhkGWbPG5yASR5EAADJSAAiVrE2425.jpg)
版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 宿舍樓房出租合同
- 商標(biāo)轉(zhuǎn)讓合同樣本
- 房地產(chǎn)交易經(jīng)紀(jì)合同
- 股份質(zhì)押合同
- 個(gè)人抵押借款合同
- 商品房裝修工程合同范本
- STEAM理念下初中數(shù)學(xué)項(xiàng)目式學(xué)習(xí)的設(shè)計(jì)研究
- 面向小行星探測(cè)的著陸器附著鉆進(jìn)錨固力學(xué)特性研究
- 2025年安陽(yáng)道路貨運(yùn)駕駛員從業(yè)資格證考試題庫(kù)完整
- 高速光通信系統(tǒng)中信號(hào)識(shí)別方法研究
- 《教科版》二年級(jí)科學(xué)下冊(cè)全冊(cè)課件(完整版)
- (2024年)《處方管理辦法》培訓(xùn)課件
- 人工智能在化工生產(chǎn)安全中的應(yīng)用
- 2023年6月浙江高考政治試卷真題解讀及答案解析(課件)
- 銷售部廉政培訓(xùn)課件
- 三年級(jí)計(jì)算題三位數(shù)乘一位數(shù)練習(xí)300題帶答案
- 商務(wù)服務(wù)業(yè)的市場(chǎng)細(xì)分和定位策略
- 財(cái)政學(xué)論文我國(guó)財(cái)政支出存在的問(wèn)題及改革建議
- 2022年湖南高速鐵路職業(yè)技術(shù)學(xué)院?jiǎn)握袛?shù)學(xué)模擬試題及答案解析
- 小學(xué)生必備古詩(shī)
- 人教版英語(yǔ)八年級(jí)上冊(cè)單詞默寫表
評(píng)論
0/150
提交評(píng)論