⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2410_can.cpp

📁 ce下S3C2410的SPI口转CAN的驱动
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Functions:
SPI_Init
SPI_Open
SPI_Close
SPI_Deinit
SPI_Read
SPI_Write
SPI_Seek
SPI_PowerUp
SPI_PowerDown
SPI_IOControl
DllEntry
SpiEventHandler
SpiDispatchThread
spiGetDroppedByteNumber
WaitCommEvent
EvaluateEventFlag
ProcessExiting


Notes: 


--*/
#include <windows.h>
#include <types.h>
#include <ceddk.h>
//#include <memory.h>
#include <linklist.h>
#include <nkintr.h>
//#include <excpt.h>
#include <hwcomapi.h>
#include <pegdser.h>
#include <devload.h>
#include <pm.h>
//#include <windev.h>
//#include <notify.h>
#include <serdbg.h>
#include <Pkfuncs.h>
//#include <Winbase.h>

#include <S2410.h>

#include "mcp2510.h"
#include "s3c2410_can.h"

/*
#ifdef TARGET_NT
    #include <devemul.h>
    #include <nteser.h>
#endif

 Debug Zones.*/
 
#ifdef DEBUG

    #define DBG_INIT     0x0001
    #define DBG_OPEN     0x0002
    #define DBG_READ     0x0004
    #define DBG_WRITE    0x0008
    #define DBG_CLOSE    0x0010
    #define DBG_IOCTL    0x0020
    #define DBG_THREAD   0x0040
    #define DBG_EVENTS   0x0080
    #define DBG_CRITSEC  0x0100
    #define DBG_FLOW     0x0200
    #define DBG_IR       0x0400
    #define DBG_NOTHING  0x0800
    #define DBG_ALLOC    0x1000
    #define DBG_FUNCTION 0x2000
    #define DBG_WARNING  0x4000
    #define DBG_ERROR    0x8000

DBGPARAM dpCurSettings = {
    TEXT("Spi"), {
        TEXT("Init"),TEXT("Open"),TEXT("Read"),TEXT("Write"),
        TEXT("Close"),TEXT("Ioctl"),TEXT("Thread"),TEXT("Events"),
        TEXT("CritSec"),TEXT("FlowCtrl"),TEXT("Infrared"),TEXT("User Read"),
        TEXT("Alloc"),TEXT("Function"),TEXT("Warning"),TEXT("Error")},
    0}; 
#endif

/////////////////////////////////////////////////////////
/********************mcp2510-start********************/
/////////////////////////////////////////////////////////
/*-------------------设置波特率---------------*/
void CAN_SetBaudRate(U8 cnf1, U8 cnf2, U8 cnf3)
{   
    //Baudrate Sync Prop Phase1 Phase2 BRP CNF1 CNF2 CNF3
    //10Kpbs   
    //25Kpbs  
    //50Kpbs     1    9     5     5     7    
    //125Kpbs    1    7     4     4     3  0x03 0x9e 0x03 
    //250Kpbs    1    7     4     4     1  0x01 0x9e 0x03
    //500Kps     1    7     4     4     0  0x00 0x9e 0x03
    //800Kps     1    5     2     2     0  0x00 0x8c 0x01
    //1000Kps    1    3     2     2     0  0x00 0x8a 0x01
    //
    //( 6 <= Tq <= 25 ) 
    //Tq = 1/((Sync+Prop+Phasel+Phase2)*Baudrate)   
    //Tq = 2*(BRP+1)/Fosc
    //BRP = Fosc/(2*Baudrate*(Sync+Prop+Phasel+Phase2))
    //Fosc = 16*10e6     
      
    w_cmd0(CNF1, cnf1); //CNF1
    w_cmd0(CNF2, cnf2); //CNF2
    w_cmd0(CNF3, cnf3); //CNF3   
}
/*-------------------设置工作模式-------------*/
//0x00正常模式,0x80配置模式,0x40环回模式, 
//0x60监听模式, 0x20休眠模式
void CAN_SetWordMode(U8 workmode)
{
     U8  dat[1];
          
     bit_cmd(CANCTRL, 0xe0, workmode);
     r_cmd(CANSTAT, dat, 1);
     
     while(!((dat[0]&0xe0) == workmode))
     {
         r_cmd(CANSTAT, dat, 1);
         		 
         Sleep(1);
     }   
}
/*--------------------复位--------------------*/
void CAN_Reset(void)
{
    CAN_CS_L();

    CAN_CMD(CMD_RESET);
	CAN_WAITRB(); 
    
    CAN_CS_H();
}
/*--------------------读状态--------------------*/
void CAN_State(U8* data)
{   
    CAN_CS_L();
    
    CAN_CMD(CMD_STATE);   
    CAN_WAITRB();
    
    CAN_DATA_W(0);
    CAN_WAITRB();
        
    data[0] = CAN_DATA_R();
    
    CAN_CS_H();
}
/*--------------------开始发送指令-------------------------*/
void t_cmd(U8 cmd)
{
    CAN_CS_L();
    
    CAN_CMD(cmd);
    
    CAN_WAITRB();
    
    CAN_CS_H();
}
/*--------------------读数据指令---------------------------*/
void r_cmd(U8 add, U8* data, U8 d_long)
{
    U8 ii;
    
    CAN_CS_L();
    
    CAN_CMD(CMD_READ);   
    CAN_WAITRB();

    CAN_ADDR(add);
    CAN_WAITRB();
    
    for (ii=0;ii<d_long;ii++)
    {
        CAN_DATA_W(0);
        CAN_WAITRB();
        
        data[ii]=CAN_DATA_R();
    }
    
    CAN_CS_H();
}

/*--------------------写数据指令---------------------------*/
void w_cmd0(U8 add, U8 data)
{   
    CAN_CS_L();
    
    CAN_CMD(CMD_WRITE);
    CAN_WAITRB();
    
    CAN_ADDR(add);
    CAN_WAITRB();
        
    CAN_DATA_W(data);
    CAN_WAITRB();
    
    CAN_CS_H();
}

void w_cmd(U8 add, U8* data, U8 d_long)
{
    U8   ii;
    
    CAN_CS_L();
    
    CAN_CMD(CMD_WRITE);
    CAN_WAITRB();
    
    CAN_ADDR(add);
    CAN_WAITRB();
    
    for (ii=0;ii<d_long;ii++)
    {
        CAN_DATA_W(data[ii]);
        CAN_WAITRB();
    }
    
    CAN_CS_H();
}

/*-------------------位修复------------------*/
void bit_cmd(U8 add, U8 mask, U8 data)
{
    CAN_CS_L();
    
    CAN_CMD(CMD_BIT);
    CAN_WAITRB();
    
    CAN_ADDR(add);
    CAN_WAITRB();
    
    CAN_DATA_W(mask);
    CAN_WAITRB();
    
    CAN_DATA_W(data);
    CAN_WAITRB();
    
    CAN_CS_H();
}

/*------------------CAN初始化---------------------*/
void CAN_Init(void)
{      
    U8  index=0, dat[30]={0}; 
    
    //进入配置模式
    CAN_SetWordMode(CONFIG_MODE);
    bit_cmd(CANCTRL, 0x1f, 0x00);
       
    CAN_SetBaudRate(0x03, 0x9e, 0x03); //125kpbs
      
    //中断
    w_cmd0(CANINTE, 0x00); //中断禁止
    w_cmd0(CANINTF, 0x00); //清中断标志
    
    //发送
    w_cmd0(TXRTSCTRL, 0x07); //芯片发送引脚使能设置
    bit_cmd(TXB0CTRL, 0x03, 0x03);//TXB0 higher
    bit_cmd(TXB1CTRL, 0x03, 0x02);//TXB1 middle
    bit_cmd(TXB2CTRL, 0x03, 0x01);//TXB2 lower
    
    //滤波(数据帧)和屏蔽(接受所有报文)
    w_cmd(RXF0SIDH, dat, 28);
    w_cmd(RXM0SIDH, dat, 8);
    
    //接受
    //0x60关闭屏蔽和滤波,接受所有报文
    //0x00正常屏蔽滤波
    w_cmd0(RXB0CTRL, 0x64); //若RXB0满,滚存至RXB1
    w_cmd0(RXB1CTRL, 0x60);
    
    w_cmd0(BFPCTRL, 0x00); //接收引脚控制使能
    
    //进入正常模式
    CAN_SetWordMode(NORMAL_MODE);
    
    w_cmd0(CANINTE, 0xff); //中断使能
}

//We use only TXB0 to send data .
U32 CAN_Send(U8* data, U32 datalength)
{     
    U8  dat[1];
        
    //read TXREQ
    CAN_State(dat);
    
    if(dat[0] & TXREQ0)
    {
//		RETAILMSG(1, (TEXT("TXREQ0 bus busy!\n"))); 
		return 0;
    }	

	U8  perbyte=8;  
    U32 NumberOfBytes=0;
    U32 i, k;
    U32 maxnums=datalength/8;
    U32 lastnums=datalength%8;
//	U8  TXBD[3] = {TXB0D0, TXB1D0, TXB2D0};
//	U8  TXBDLC[3] = {TXB0DLC, TXB1DLC, TXB2DLC};
  
    //标准标识符 or 扩展标识符
    //数据帧 or 远程帧
    //标准标识符+扩展标识符+数据帧+数据长度8
	U8 cmd[6]={0xaa,0xaa,0xaa,0xaa,0x08};
    w_cmd(TXB0SIDH, cmd, 5);
//	w_cmd(TXB1SIDH, cmd, 5);
//	w_cmd(TXB2SIDH, cmd, 5);

//    bit_cmd(TXB0DLC, 0x0f, perbyte);
        
    for(k=0; k<maxnums; k++)
    {
SENDDATA0:                
        //数据   
        w_cmd(TXB0D0, data+NumberOfBytes, perbyte);
       
        //start TXB0
        t_cmd(CMD_TXB0);
        
        for (i=0; i<600000; i++)
		{
			CAN_State(dat);

			if( !(dat[0]&TXREQ0) )
			     break;
		}
		if ( i == 600000 )
		{
//			RETAILMSG(1, (TEXT("Tx abort!\n")));
			return NumberOfBytes;
		}
		
		NumberOfBytes += perbyte;			
    }
    
    if( lastnums )
    {
		//更改要发送的数据长度
        perbyte = lastnums;       
        bit_cmd(TXB0DLC, 0x0f, perbyte);
        
        lastnums = 0;//exit
        
        goto  SENDDATA0;
    }

    return NumberOfBytes;
}
/*
U32 CAN_Rece(U8 index)
{
    U8  length;
    U8  dat0[20]={0};
    U8  selreg[2]={RXB0CTRL,RXB1CTRL};
  
    r_cmd(selreg[index], dat0, 14);

    length = 6+(dat0[5]&0x0f);
    
    return length;
}*/
/////////////////////////////////////////////////////
///////////////////  end   //////////////////////////
/////////////////////////////////////////////////////
PRIVATE PVOID
SER_RegAlloc(PVOID addr, INT sz)
{
	PVOID reg;

	reg = (PVOID)VirtualAlloc(0, sz, MEM_RESERVE, PAGE_NOACCESS);

	if (reg)
	{
		if (!VirtualCopy(reg, addr, sz, PAGE_READWRITE | PAGE_NOCACHE )) 
		{
			VirtualFree(reg, 0, MEM_RELEASE);
			reg = NULL;
		}
	}

	return reg;
}

PRIVATE BOOL
SPI_VirtualAlloc(VOID)
{
	BOOL r = FALSE;

//    RETAILMSG(DEBUGMODE,(TEXT("::: SPI_VirtualAlloc()\r\n")));

	do
	{
		v_pIOPregs = (volatile IOPreg *)SER_RegAlloc((PVOID)IOP_BASE, sizeof(IOPreg));
		if (v_pIOPregs == NULL) 
		{
			ERRORMSG(1,(TEXT("For IOPreg: VirtualAlloc failed!\r\n")));
			break;
		}
	
		v_pSPI0regs = (volatile SSPreg *)SER_RegAlloc((PVOID)SSP_BASE, sizeof(SSPreg));
		if (v_pSPI0regs == NULL) 
		{
	    	ERRORMSG(1,(TEXT("For SPI0reg: VirtualAlloc failed!\r\n")));
		    break;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -