/*********************************************************************
* FileName: can2515.c
* Processor: STM32F429
* Compiler: CCG
* Company: Ruselprom-electroprivod,
*
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* zWitCh 01.08.2014
********************************************************************/
#include "can2515.h"
/*********************************************************************
* 砍頡順� 鳩皓粵�� 縈褒褓錚 羸磋
* 段褒憂曉鈇瘟 頜� 頡憐孃 http://www.intrepidcs.com/support/mbtime.htm
* 1Mb/s, 800kB/s, 500kB/s, 250kB/s, 125kB/s, 50kB/s, 20kB/s, 10kB/s
* 姻蜻慮獎皖態 頡 順菔樽 糟�: http://www.can-cia.org/fileadmin/cia/files/icc/9/koppe.pdf
* 秒蝗瘟� 篦憫鞅曉鈇璃� : (CAN2510_REG_CNF2|0x40)
*
********************************************************************/
const uint8_t can2515_cnf[] = { 0x00, 0x98, 0x01, /* 1Mb/s semple point 75% */
0x00, 0xA8, 0x01, /* 800kb/s semple point 80% */
0x00, 0xBC, 0x01, /* 500kb/s semple point 87.5% */
0x01, 0xBC, 0x01, /* 250kb/s semple point 87.5% */
0x03, 0xBC, 0x01, /* 125kb/s semple point 87.5% */
0x09, 0xBC, 0x01, /* 50kb/s semple point 87.5% */
0x18, 0xBC, 0x01, /* 20kb/s semple point 87.5% */
0x31, 0xBC, 0x01 /* 10kb/s semple point 87.5% */
};
void CAN2510Reset(void){
}
void CAN2510Enable(void){
//GPIO_ResetBits(GPIOB, GPIO_Pin_12);
GPIOB->BSRRH = GPIO_Pin_12;
}
void CAN2510Disable(void){
//GPIO_SetBits(GPIOB, GPIO_Pin_12);
GPIOB->BSRRL = GPIO_Pin_12;
}
void WriteSPI(unsigned char byte){
static uint8_t var;
while(SPI2->SR & SPI_I2S_FLAG_BSY);
//SPI_I2S_SendData(SPI2, byte);
var = SPI2->DR;
SPI2->DR = byte;
//while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0);
//SPI_I2S_ReceiveData(SPI2);
var = SPI2->DR;
}
void sWriteSPI(unsigned char byte){
SPI2->DR = byte;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == 0);
}
unsigned char ReadSPI(void){
static uint8_t var;
//while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
while(SPI2->SR & SPI_I2S_FLAG_BSY);
if(SPI2->SR & SPI_I2S_FLAG_RXNE)
var = SPI2->DR;
//SPI_I2S_SendData(SPI2, 0xFF);
SPI2->DR = 0xFF;
//while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == 0);
//return SPI_I2S_ReceiveData(SPI2);
return SPI2->DR;
}
/*****************************************************************************/
/* */
/* Modifies the specifed bits in a register to the new values */
/* */
/*****************************************************************************/
void CAN2515BitModify( unsigned char addr,
unsigned char mask,
unsigned char value )
{
CAN2510Enable(); // Enable SPI Communication to MCP2510
sWriteSPI(CAN2510_CMD_BITMOD); // Send code for bit modify command
sWriteSPI(addr); // Send address of register to modify
sWriteSPI(mask); // Send mask of bits to modify in the register
WriteSPI(value); // Send new data to be loaded into specified bits
CAN2510Disable(); // Disable SPI Communication to MCP2510
}
/*********************************************************************
* Overview:
*
*
********************************************************************/
unsigned char CAN2515ErrorState( void )
{
/*************************************************************************/
/* Determine the error state of the CAN Bus */
/* - Error Active */
/* - Error Active with EWARN set */
/* - Error Passive */
/* - Bus Off */
/*************************************************************************/
CAN2510_REG_EFLGbits_type BufferEFLG; // BufferEFLG type so can access bits
BufferEFLG.byte = CAN2515ByteRead( CAN2510_REG_EFLG ); // Read the EFLG register
// so that status can
// be determined
if( BufferEFLG.TXBO == 1 ) // TEC > 256?
return( CAN2510_BUS_OFF ); // Yes, the transmitter
// is Bus Off
else if( (BufferEFLG.TXEP == 1) ) // TEC > 127?
return( CAN2510_ERROR_PASSIVE_TX ); // Yes, In Error Passive
// mode
else if( (BufferEFLG.RXEP == 1) ) // REC > 127?
return( CAN2510_ERROR_PASSIVE_RX ); // Yes, In Error Passive
// mode
else if( (BufferEFLG.TXWARN == 1) ) // TEC > 95?
return( CAN2510_ERROR_ACTIVE_WITH_TXWARN ); // Yes, In Error Active mode
// with an TX Error Warning
else if( (BufferEFLG.RXWARN == 1) ) // REC > 95?
return( CAN2510_ERROR_ACTIVE_WITH_RXWARN ); // Yes, In Error Active mode
// with an RX Error Warning
else //
return( CAN2510_ERROR_ACTIVE ); // In Error Active mode
}
/*********************************************************************
* Overview:
*
*
********************************************************************/
static void CAN2515SetSpeed( unsigned char speed )
{
CAN2515ByteWrite( CAN2510_REG_CNF1, can2515_cnf[speed] );
CAN2515ByteWrite( CAN2510_REG_CNF2, can2515_cnf[speed+1] );
CAN2515ByteWrite( CAN2510_REG_CNF3, can2515_cnf[speed+2] );
}
/*********************************************************************
* Overview:
*
*
********************************************************************/
static void CAN2515BitTimeInit( unsigned long BitTimeConfig )
{
static unsigned char databyte;
static unsigned char WriteData;
/********************************************************************/
/* */
/* Set synchronization jump width and baud rate prescaler */
/* Set Propagation Segment and Phase 1 Segment widths */
/* Specify the number of times to sample and the source */
/* of the Phase 2 Segment time */
/* Set synchronization jump width and baud rate prescaler */
/* */
/* The CNF1, CNF2, and CNF3 registers can only be modified by the */
/* bit modify command */
/* */
/********************************************************************/
databyte = (unsigned char) (BitTimeConfig); // All bits used
WriteData = ~databyte; // Complement the value
CAN2515ByteWrite( CAN2510_REG_CNF1, WriteData );
databyte = (unsigned char) (BitTimeConfig >> 8 ); // All bit
评论3