📄 s3c2410_can.cpp
字号:
//
// 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 + -