📄 8938.c
字号:
/****************************************************************************
【说明】SPI2CAN
****************************************************************************/
#include <windows.h>
#include <types.h>
#include <oalintr.h>
U8 in_buff[6];
U8 out_buff[4];
U8 CanID[4];
static void Delay(USHORT count)
{
volatile int i, j = 0;
volatile static int loop = 400000000/100000;
for(;count > 0;count--){
for(i=0;i < loop; i++) { j++; }
}
}
void GPIOInit(void)
{
rGPEUP |= (7 << 11);
rGPECON &= (~ (0x3F << 22));
rGPECON |= (0x2A << 22);
rGPGCON &= (~ (0x3 << 4));
rGPGCON |= (1 << 4);
rGPGUP |= (1 << 2);
}
void SPIInit(int begin)
{
if(begin)
{
MCP2510_CS_H;
rSPPRE = 0xff;
rSPCON |= 0x18;
}
else rSPCON = 0;
}
U8 Spi_Write( U8 Data )
{
rSPTDAT = Data;
while(! (rSPSTA & 1));
return (U8) rSPRDAT;
}
void MCP2510_Write( U8 address, U8 value)
{
MCP2510_CS_L;
Spi_Write(MCP2510INSTR_WRITE);
Spi_Write(address);
Spi_Write(value);
MCP2510_CS_H;
}
U8 MCP2510_Read( U8 address )
{
U8 result;
MCP2510_CS_L;
Spi_Write(MCP2510INSTR_READ);
Spi_Write(address);
result = Spi_Write(0xFF);
MCP2510_CS_H;
return result;
}
void MCP2510_WriteBits( U8 address, U8 data, U8 mask )
{
MCP2510_CS_L;
Spi_Write(MCP2510INSTR_BITMDFY);
Spi_Write(address);
Spi_Write(mask);
Spi_Write(data);
MCP2510_CS_H;
}
void MCP2510_Swrite( U8 address, U8* pdata, U8 nlength)
{
MCP2510_CS_L;
Spi_Write(MCP2510INSTR_WRITE);
Spi_Write((unsigned char)address);
while(nlength--)
{
Spi_Write(*pdata++);
}
MCP2510_CS_H ;
}
void MCP2510_SRead( U8 address, U8* pdata, U8 nlength )
{
MCP2510_CS_L;
Spi_Write(MCP2510INSTR_READ);
Spi_Write(address);
while(nlength--)
{
* pdata++ = Spi_Write(0xFF);
}
MCP2510_CS_H;
}
void MCP2510_Reset()
{
MCP2510_CS_L;
Spi_Write( MCP2510INSTR_RESET );
MCP2510_CS_H ;
}
U8 MCP2510_ReadStatus()
{
U8 result;
MCP2510_CS_L;
Spi_Write(MCP2510INSTR_RDSTAT);
result = Spi_Write(0xFF) ;
Spi_Write( 0 ) ;
MCP2510_CS_H ;
return result;
}
void MCP2510_SetBandRate(CanBandRate bandrate)
{
U8 value=0;
U8 ReadBackCNT = 0;
MCP2510_Write(MCP2510REG_CANCTRL, MODE_CONFIG);
if( ReadBackCNT == 8 )
{
MCP2510_Reset();
MCP2510_Write(MCP2510REG_CANCTRL, MODE_CONFIG);
Delay( 150 );
value = ( MCP2510_Read(MCP2510REG_CANCTRL) & 0xe0 );
}
switch(bandrate){
case BandRate_100kbps:
MCP2510_Write(CNF1, SJW1|BRP5);
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG3);
MCP2510_Write(CNF3, SEG4);
break;
case BandRate_125kbps:
MCP2510_Write(CNF1, SJW1|BRP4);
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG5<<3)|SEG3);
MCP2510_Write(CNF3, SEG3);
break;
case BandRate_250kbps:
MCP2510_Write(CNF1, SJW1|BRP2);
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG3);
MCP2510_Write(CNF3, SEG4);
break;
case BandRate_500kbps:
MCP2510_Write(CNF1, SJW1|BRP1);
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG3);
MCP2510_Write(CNF3, SEG4);
break;
case BandRate_1Mbps:
MCP2510_Write(CNF1, SJW1|BRP1);
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG2<<3)|SEG1);
MCP2510_Write(CNF3, SEG2);
break;
default:
break;
}
}
int MCP2510_Read_Can_ID( U8 address, U32* can_id)
{
U32 tbufdata;
unsigned char* p=(unsigned char*)&tbufdata;
MCP2510_SRead(address, p, 4);
*can_id = (tbufdata<<3)|((tbufdata>>13)&0x7);
*can_id &= 0x7ff;
if ( (p[MCP2510REG_SIDL] & TXB_EXIDE_M) == TXB_EXIDE_M )
{
*can_id = (*can_id<<2) | (p[MCP2510REG_SIDL] & 0x03);
*can_id <<= 16;
*can_id |= (tbufdata>>24) | ((tbufdata>>8)& 0x0ff0);
return TRUE;
}
return FALSE;
}
void MCP2510_Write_Can_ID(U8 address, U32 can_id, int IsExt)
{
U32 tbufdata;
if (IsExt){
can_id&=0x1fffffff;
tbufdata=(can_id >>21) | ((can_id>>5) & 0xe000) | ((can_id>>8) & 0x300) | ((can_id<<8) & 0xff0000) | ((can_id<<24) & 0xff000000) | (0x800);
}
else{
can_id&=0x7ff;
tbufdata= (can_id>>3) | ((can_id&0x7)<<13);
}
MCP2510_Swrite(address, (unsigned char*)&tbufdata, 4);
}
int MCP2510_Read_Can(U8 nbuffer, int* rxRTR, U32* can_id, U8* data , U8* dlc)
{
U8 mcp_addr = (nbuffer<<4) + 0x31;
U8 ctrl;
int IsExt;
IsExt=MCP2510_Read_Can_ID( mcp_addr, can_id);
ctrl=MCP2510_Read(mcp_addr-1);
*dlc=MCP2510_Read( mcp_addr+4);
if ((ctrl & 0x08)) {
*rxRTR = TRUE;
}
else{
*rxRTR = FALSE;
}
*dlc &= DLC_MASK;
MCP2510_SRead(mcp_addr+5, data, *dlc);
return IsExt;
}
int Can_Poll()
{
if( MCP2510_ReadStatus()&RX0INT )
{
return 0;
}
}
int Can_Read(int n, U32* id, U8 *pdata, U8 *dlc, int* rxRTR, int *isExt)
{
U8 byte;
byte = MCP2510_Read(CANINTF);
if(n==0)
{
if(byte & RX0INT)
{
*isExt=MCP2510_Read_Can(n+3, rxRTR, id, pdata, dlc);
MCP2510_WriteBits(CANINTF, (U8)(~(RX0INT)), RX0INT);
return TRUE ;
}
return FALSE;
}
else if(n ==1 )
{
if(byte & RX1INT)
{
*isExt=MCP2510_Read_Can(n+4, rxRTR, id, pdata, dlc);
MCP2510_WriteBits(CANINTF, (U8)(~(RX1INT)), RX1INT);
return TRUE ;
}
return FALSE;
}
return FALSE;
}
void MCP2510_Write_Can( U8 nbuffer, int IsExt, U32 can_id, int rxRTR, U8* data,U8 dlc )
{
U8 mcp_addr = (nbuffer<<4) + 0x31;
MCP2510_Swrite(mcp_addr+5, data, dlc );
MCP2510_Write_Can_ID( mcp_addr, can_id,IsExt);
if (rxRTR)
dlc |= RTR_MASK;
MCP2510_Write((mcp_addr+4), dlc);
}
void Can_Write(U32 id, U8 *pdata, unsigned char dlc, int IsExt, int rxRTR)
{
unsigned char err ;
static int ntxbuffer=0;
MCP2510_Write_Can(ntxbuffer, IsExt, id, rxRTR, pdata, dlc);
switch(ntxbuffer){
case 0:
MCP2510_WriteBits(TXB0CTRL, (TXB_TXREQ_M|TXB_TXP10_M), 0xff) ;
do { err = MCP2510_Read(TXB0CTRL) ; }
while( (err &0x08)==0x08 ) ;
ntxbuffer=1;
break;
case 1:
MCP2510_WriteBits(TXB1CTRL, (TXB_TXREQ_M|TXB_TXP10_M), 0xff) ;
do { err = MCP2510_Read(TXB1CTRL) ; }
while( (err &0x08)==0x08 ) ;
ntxbuffer=2;
break;
case 2:
MCP2510_WriteBits(TXB2CTRL, (TXB_TXREQ_M|TXB_TXP10_M), 0xff) ;
do { err = MCP2510_Read(TXB2CTRL) ; }
while( (err &0x08)==0x08 ) ;
ntxbuffer=0;
break;
}
}
void Can_Setup(void)
{
MCP2510_WriteBits(RXB0CTRL, RXB_RX_ANY, 0xFF);
}
void Init_MCP2510(CanBandRate bandrate)
{
SPIInit(1);
MCP2510_Reset();
MCP2510_Write(CANINTE, NO_IE);
MCP2510_SetBandRate(bandrate);
MCP2510_Write(MCP2510REG_CANCTRL, MODE_NORMAL| CLKEN | CLK8);
}
/****************************************************************************
【说明】流接口驱动程序
****************************************************************************/
BOOL WINAPI CAN_DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
DWORD CAN_Open( DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode)
{
switch(dwShareMode) {
case 0:
Init_MCP2510(BandRate_10kbps); break;
case 1:
Init_MCP2510(BandRate_100kbps); break;
case 2:
Init_MCP2510(BandRate_125kbps); break;
case 3:
Init_MCP2510(BandRate_250kbps); break;
case 4:
Init_MCP2510(BandRate_500kbps); break;
case 5:
Init_MCP2510(BandRate_1Mbps); break;
case 6:
Init_MCP2510(BandRate_833kbps); break;
default:
break;
}
Can_Setup();
return 1;
}
BOOL CAN_Close(DWORD dwData)
{
SPIInit(0);
return TRUE;
}
DWORD CAN_Init(DWORD Index)
{
GPIOInit();
int i;
U32 id;
unsigned char dlc;
int rxRTR, isExt;
int temp;
U8 data_read[32];
while(1)
{
i = Can_Poll();
if((i==0)|(i==1))
{
Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt);
RETAILMSG(TRUE, (TEXT("can_data %u\r\n"), data_read));
}
}
return 1;
}
BOOL CAN_Deinit(DWORD dwData)
{
return TRUE;
}
DWORD CAN_Read(DWORD hOpenContext,LPVOID pBuffer ,DWORD count)
{
int i;
U32 id;
unsigned char dlc;
int rxRTR, isExt;
int temp;
U8 data_read[32];
if(count==9)
{
memcpy(CanID,pBuffer,4);
count=8;
Read:
i = Can_Poll();
if((i==0)|(i==1))
{
memset( data_read,0,sizeof(data_read) ) ;
temp = Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt);
out_buff[0] = ((id>>24)&0xff);
out_buff[1] = ((id>>16)&0xff);
out_buff[2] = ((id>>8)&0xff);
out_buff[3] = ((id)&0xff);
if((out_buff[2]!=CanID[2]) || (out_buff[3]!=CanID[3]))
{
goto Read;
}
else{
memcpy(pBuffer,data_read,count);
}
}
else{
return 0;
}
}
else if(count!=9)
{
i = Can_Poll();
if((i==0)|(i==1))
{
memset(data_read,0,sizeof(data_read) ) ;
temp = Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt);
memcpy(pBuffer,data_read,count);
out_buff[0] = ((id>>24)&0xff);
out_buff[1] = ((id>>16)&0xff);
out_buff[2] = ((id>>8)&0xff);
out_buff[3] = ((id)&0xff);
}
else
{
return 0;
}
}
return count ;
}
DWORD CAN_Write(DWORD hOpenContext,LPCVOID pSourceBytes,DWORD NumberOfBytes)
{
unsigned char *pTmp ;
U32 ID_data = 0x0;
int rxRTR, Ext,i, isExt;
U32 id;
unsigned char dlc;
U8 data_read[32];
i = Can_Poll();
if((i==0)|(i==1))
{
Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt);
}
pTmp = (unsigned char *)pSourceBytes ;
ID_data = in_buff[5]|(in_buff[4]<<8)|(in_buff[3]<<16)|(in_buff[2]<<24);
Ext = in_buff[0];
rxRTR = in_buff[1];
Can_Write( ID_data, (unsigned char *)pTmp, NumberOfBytes, Ext, rxRTR);
return 1;
}
DWORD CAN_Seek(DWORD hOpenContext, long Amount,WORD Type)
{
return 1;
}
BOOL CAN_IOControl(DWORD dwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
if(dwCode==0)
{
switch(dwLenIn) {
case 0:
in_buff[0] = 0;
in_buff[1] = 0;break;
case 1:
in_buff[0] = 0;
in_buff[1] = 1;break;
case 2:
in_buff[0] = 1;
in_buff[1] = 0;break;
case 3:
in_buff[0] = 1;
in_buff[1] = 1;break;
default:
break;
}
in_buff[2] = pBufIn[0];
in_buff[3] = pBufIn[1];
in_buff[4] = pBufIn[2];
in_buff[5] = pBufIn[3];
}
else
{
pBufOut[0] = out_buff[0];
pBufOut[1] = out_buff[1];
pBufOut[2] = out_buff[2];
pBufOut[3] = out_buff[3];
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -