/* ---------------------------------------------------------------------------------- CAN.cpp CONTROLLER AREA NETWORK (CAN 2.0A STANDARD ID) CAN BUS library for Wiring/Arduino - Version 1.1 ADAPTED FROM http://www.kreatives-chaos.com By IGOR REAL (16 - 05 - 2011) ---------------------------------------------------------------------------------- */ /* Name: Parameters(type): Description: Example: */ #include "Arduino.h" #include "CAN_.h" #define DEBUGMODE 0 /****************************************************************************** * Variables ******************************************************************************/ CANClass CAN; CANClass::msgCAN CAN_TxMsg; CANClass::msgCAN CAN_RxMsg; /****************************************************************************** * Constructors ******************************************************************************/ /****************************************************************************** * PUBLIC METHODS ******************************************************************************/ void CANClass::begin(uint16_t speed) { #if (DEBUGMODE==1) Serial.begin(115200); Serial.println("-- Constructor Can(uint16_t speed) --"); #endif pinMode(MCP2515_CS, OUTPUT); digitalWrite(MCP2515_CS, HIGH); RESET(P_SCK); RESET(P_MOSI); RESET(P_MISO); SET_OUTPUT(P_SCK); SET_OUTPUT(P_MOSI); SET_INPUT(P_MISO); SET_INPUT(MCP2515_INT); SET(MCP2515_INT); // activamos el SPI de Arduino como Master y Fosc/2=8 MHz SPCR = (1<Si buffer 0 lleno,envia a buffer 1 mcp2515_write_register(RXB0CTRL,(1< could not send message return 0xFF; } digitalWrite(MCP2515_CS, LOW); spi_putc(SPI_WRITE_TX | address); spi_putc(message->id >> 3); spi_putc(message->id << 5); spi_putc(0); spi_putc(0); uint8_t length = message->header.length & 0x0f; if (message->header.rtr) { // a rtr-frame has a length, but contains no data spi_putc((1<data[t]); } } digitalWrite(MCP2515_CS, HIGH); _delay_us(1); // send message digitalWrite(MCP2515_CS, LOW); address = (address == 0) ? 1 : address; spi_putc(SPI_RTS | address); digitalWrite(MCP2515_CS, HIGH); #if (DEBUGMODE==1) Serial.println("-- END uint8_t CANClass::send(msgCAN *message) --"); #endif return address; } // ---------------------------------------------------------------------------- /* Name:ReadFromDevice(message) Parameters(type): message(*msgCAN): Menssage passed by reference to be filled with the new message coming fron the 2515 drvier Description: Receives by parameter a struct msgCAN Returns(uint8_t): last 3 bits of 2515's status. More in the Example: if(CAN.ReadFromDevice(&message)) { } */ uint8_t CANClass::ReadFromDevice(msgCAN *message) { #if (DEBUGMODE==1) Serial.begin(115200); Serial.println("-- START uint8_t ReadFromDevice(msgCAN *message) --"); #endif static uint8_t previousBuffer; // read status uint8_t status = mcp2515_read_status(SPI_RX_STATUS); uint8_t addr; uint8_t t; #if (DEBUGMODE==1) Serial.print("MCP2515 Status="); Serial.println(status,BIN); Serial.print("Mask to check Buffer="); Serial.println( ((status & 0b11000000)>>6)&0b00000011,BIN); #endif if ( (((status & 0b11000000)>>6)&0b00000011) >2 ) { addr=SPI_READ_RX | (previousBuffer++ & 0x01)<<2; #if (DEBUGMODE==1) Serial.println("Dos buffer con datos"); Serial.print("addr="); Serial.println(addr,HEX); Serial.print("previousBuffer="); Serial.println(previousBuffer,DEC); #endif } else if (bit_is_set(status,6)) { // message in buffer 0 addr = SPI_READ_RX; #if (DEBUGMODE==1) Serial.println("Read From Buffer 0"); Serial.print("addr="); Serial.println(addr,HEX); #endif } else if (bit_is_set(status,7)) { // message in buffer 1 addr = SPI_READ_RX | 0x04; #if (DEBUGMODE==1) Serial.println("Read From Buffer 1"); Serial.print("addr="); Serial.println(addr,HEX); #endif } else { // Error: no message available return 0; } digitalWrite(MCP2515_CS, LOW); spi_putc(addr); // read id message->id = (uint16_t) spi_putc(0xff) << 3; message->id |= spi_putc(0xff) >> 5; spi_putc(0xff); spi_putc(0xff); // read DLC uint8_t length = spi_putc(0xff) & 0x0f; message->header.length = length; message->header.rtr = (bit_is_set(status, 3)) ? 1 : 0; // read data for (t=0;tdata[t] = spi_putc(0xff); } digitalWrite(MCP2515_CS, HIGH); // clear interrupt flag if (bit_is_set(status, 6)) { mcp2515_bit_modify(CANINTF, (1< Filter 0-1 & Mask 0 mcp2515_write_register( RXF0SIDH, (uint8_t)(Filters[0]>>3) ); mcp2515_write_register( RXF0SIDL, (uint8_t)(Filters[0]<<5) ); mcp2515_write_register( RXF1SIDH, (uint8_t)(Filters[1]>>3) ); mcp2515_write_register( RXF1SIDL, (uint8_t)(Filters[1]<<5) ); //Mask 0 mcp2515_write_register( RXM0SIDH, (uint8_t)(Masks[0]>>3) ); mcp2515_write_register( RXM0SIDL, (uint8_t)(Masks[0]<<5) ); //--------------------------------------------------------------- //Buffer RXB1 => Filter 2-5 & Mask 1 mcp2515_write_register( RXF2SIDH, (uint8_t)(Filters[2]>>3) ); mcp2515_write_register( RXF2SIDL, (uint8_t)(Filters[2]<<5) ); mcp2515_write_register( RXF3SIDH, (uint8_t)(Filters[3]>>3) ); mcp2515_write_register( RXF3SIDL, (uint8_t)(Filters[3]<<5) ); mcp2515_write_register( RXF4SIDH, (uint8_t)(Filters[4]>>3) ); mcp2515_write_register( RXF4SIDL, (uint8_t)(Filters[4]<<5) ); mcp2515_write_register( RXF5SIDH, (uint8_t)(Filters[5]>>3) ); mcp2515_write_register( RXF5SIDL, (uint8_t)(Filters[5]<<5) ); // Mask1 mcp2515_write_register( RXM1SIDH, (uint8_t)(Masks[1]>>3) ); mcp2515_write_register( RXM1SIDL, (uint8_t)(Masks[1]<<5) ); //Buffer configuration //Bufer 0 mcp2515_write_register(RXB0CTRL,(0<0 : How many Description: Returns how many messages are available in the circular buffer Example: if(CAN.available() > 0) { } */ uint8_t CANClass::available(void) { return ((RX_CAN_BUFFER_SIZE+_CAN_RX_BUFFER.head-_CAN_RX_BUFFER.tail)%RX_CAN_BUFFER_SIZE); } // ---------------------------------------------------------------------------- /* Name:read(message) Parameters(type): message(*msgCAN): Message passed by reference t be filled with a stored msg Description: it pops a message from the circular buffer Example: read(&CAN_TxMsg); if(CAN_TxMsg.id > 0) { } */ void CANClass::read(msgCAN *message) { if (_CAN_RX_BUFFER.head==_CAN_RX_BUFFER.tail) { //Significa que no hay dato message->id=0; }else{ *message=_CAN_RX_BUFFER.buffer[_CAN_RX_BUFFER.tail]; _CAN_RX_BUFFER.tail=(_CAN_RX_BUFFER.tail+1)%RX_CAN_BUFFER_SIZE; } } // ----------------------------------------------------------------------------