int main(void) { uart_init (); stdout = &uart_stdout; printf ("Initializing...\n"); can_init (0x10); uint8_t count = 0; sei(); printf ("Initialized\n"); while(1) { can_frame_t frame; frame.identifier = 0x00; frame.size = count%8; for(uint8_t i = 0; i < frame.size; i++) { frame.data[i] = ~(128-i)+count; } uint8_t s = can_send_frame(&frame); printf("Sent data %d %s\r",count, (s?"SUCCESS":"FAIL")); can_frame_t recieved; _delay_ms(100); uint8_t status = mcp2515_read_status(); printf(" Status = 0x%x\r", status); s = can_recieve_frame(&recieved); printf(" Receieved data: L1: %d L2: %d %s\r", frame.size, recieved.size, (s?"SUCCESS":"FAIL")); _delay_ms(100); if(frame.size == recieved.size) { printf(" Identical length\r"); uint8_t passed = 1; for(uint8_t i = 0; i < recieved.size; i++) { if(frame.data[i] != recieved.data[i]) { passed = 0; continue; } } if(passed) { printf(" AND identical data\r"); } else { printf(" FAIL! NOT identical data\r"); } } else { printf(" FAIL! NOT identical length\r"); } status = mcp2515_read_status(); printf(" Status = 0x%x\r", status); _delay_ms(500); count++; } }
bool mcp2515_check_free_buffer(void) { uint8_t status = mcp2515_read_status(SPI_READ_STATUS); if ((status & 0x54) == 0x54) return false; // all buffers used else return true; }
// ---------------------------------------------------------------------------- uint8_t mcp2515_get_message(tCAN *message) { // read status uint8_t status = mcp2515_read_status(SPI_RX_STATUS); uint8_t addr; uint8_t t; if (bit_is_set(status,6)) { // message in buffer 0 addr = SPI_READ_RX; } else if (bit_is_set(status,7)) { // message in buffer 1 addr = SPI_READ_RX | 0x04; } else { // Error: no message available return 0; } RESET(MCP2515_CS); spi_putc(addr); // read id message->raw_data[0] = spi_putc(0xff); message->raw_data[1] = spi_putc(0xff); message->raw_data[2] = spi_putc(0xff); message->raw_data[3] = spi_putc(0xff); message->raw_data[4] = spi_putc(0xff); message->id = (uint16_t)message->raw_data[0] << 3; message->id |= message->raw_data[1] >> 5; // read DLC uint8_t length = message->raw_data[4] & 0x0f; message->header.length = length; message->header.rtr = (bit_is_set(status, 3)) ? 1 : 0; // read data for (t=0;t<length;t++) { message->data[t] = spi_putc(0xff); message->raw_data[t + 5] = message->data[t]; } SET(MCP2515_CS); // clear interrupt flag if (bit_is_set(status, 6)) { mcp2515_bit_modify(CANINTF, (1<<RX0IF), 0); } else { mcp2515_bit_modify(CANINTF, (1<<RX1IF), 0); } return (status & 0x07) + 1; }
void mcp2515_init(){ char status; spi_init(); mcp2515_reset(); status = mcp2515_read_status(); if ((status & MODE_MASK) != MODE_CONFIG) { printf("MCP2515 is not in config mode!\n"); } }
bool mcp2515_check_message(void) { #if defined(MCP2515_INT) return ((!IS_SET(MCP2515_INT)) ? true : false); #else #ifdef RXnBF_FUNKTION if (!IS_SET(MCP2515_RX0BF) || !IS_SET(MCP2515_RX1BF)) return true; else return false; #else return ((mcp2515_read_status(SPI_RX_STATUS) & 0xC0) ? true : false); #endif #endif }
//Returns 1 if message was sedt, otherwise 0 uint8_t CAN_message_send(CAN_message const * const msg){ //Finds an available register //reg0, 0x30: status bit nr 2 //reg1, 0x40: status bit nr 4 //reg2, 0x50: status bit nr 6 uint8_t status = mcp2515_read_status(); if(status | (1 << 2)){ CAN_message_send_to_reg(msg, MCP_TXB0CTRL); } else if(status | (1<<4)){ CAN_message_send_to_reg(msg, MCP_TXB1CTRL); } else if(status | (1<<6)){ CAN_message_send_to_reg(msg, MCP_TXB2CTRL); } else{ return 0; } return 1; }
// ---------------------------------------------------------------------------- uint8_t mcp2515_send_message(tCAN *message) { uint8_t status = mcp2515_read_status(SPI_READ_STATUS); /* Statusbyte: * * Bit Function * 2 TXB0CNTRL.TXREQ * 4 TXB1CNTRL.TXREQ * 6 TXB2CNTRL.TXREQ */ uint8_t address; uint8_t t; // SET(LED2_HIGH); if (bit_is_clear(status, 2)) { address = 0x00; } else if (bit_is_clear(status, 4)) { address = 0x02; } else if (bit_is_clear(status, 6)) { address = 0x04; } else { // all buffer used => could not send message return 0; } RESET(MCP2515_CS); 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<<RTR) | length); } else { // set message length spi_putc(length); // data for (t=0;t<length;t++) { spi_putc(message->data[t]); } } SET(MCP2515_CS); _delay_us(1); // send message RESET(MCP2515_CS); address = (address == 0) ? 1 : address; spi_putc(SPI_RTS | address); SET(MCP2515_CS); return address; }
uint8_t mcp2515_buffers_status(void) { return mcp2515_read_status(SPI_READ_STATUS); }
// ---------------------------------------------------------------------------- uint8_t mcp2515_send_message(const can_t *msg) { // Status des MCP2515 auslesen uint8_t status = mcp2515_read_status(SPI_READ_STATUS); /* Statusbyte: * * Bit Funktion * 2 TXB0CNTRL.TXREQ * 4 TXB1CNTRL.TXREQ * 6 TXB2CNTRL.TXREQ */ uint8_t address; if (_bit_is_clear(status, 2)) { address = 0x00; } else { // Alle Puffer sind belegt, // Nachricht kann nicht verschickt werden return 0; } RESET(MCP2515_CS); spi_putc(SPI_WRITE_TX | address); #if SUPPORT_EXTENDED_CANID mcp2515_write_id(&msg->id, msg->flags.extended); #else mcp2515_write_id(&msg->id); #endif uint8_t length = msg->length & 0x0f; // Ist die Nachricht ein "Remote Transmit Request" ? if (msg->flags.rtr) { // Ein RTR hat zwar eine Laenge, // enthaelt aber keine Daten // Nachrichten Laenge + RTR einstellen spi_putc((1<<RTR) | length); } else { // Nachrichten Laenge einstellen spi_putc(length); // Daten for (uint8_t i=0;i<length;i++) { spi_putc(msg->data[i]); } } SET(MCP2515_CS); _delay_us(1); // CAN Nachricht verschicken // die letzten drei Bit im RTS Kommando geben an welcher // Puffer gesendet werden soll. RESET(MCP2515_CS); address = (address == 0) ? 1 : address; spi_putc(SPI_RTS | address); SET(MCP2515_CS); CAN_INDICATE_TX_TRAFFIC_FUNCTION; return address; }
uint8_t mcp2515_get_message(can_t *msg) { uint8_t addr; #ifdef RXnBF_FUNKTION if (!IS_SET(MCP2515_RX0BF)) addr = SPI_READ_RX; else if (!IS_SET(MCP2515_RX1BF)) addr = SPI_READ_RX | 0x04; else return 0; #else // read status uint8_t status = mcp2515_read_status(SPI_RX_STATUS); if (_bit_is_set(status,6)) { // message in buffer 0 addr = SPI_READ_RX; } else if (_bit_is_set(status,7)) { // message in buffer 1 addr = SPI_READ_RX | 0x04; } else { // Error: no message available return 0; } #endif RESET(MCP2515_CS); spi_putc(addr); // CAN ID auslesen und ueberpruefen uint8_t tmp = mcp2515_read_id(&msg->id); #if SUPPORT_EXTENDED_CANID msg->flags.extended = tmp & 0x01; #else if (tmp & 0x01) { // Nachrichten mit extended ID verwerfen SET(MCP2515_CS); #ifdef RXnBF_FUNKTION if (!IS_SET(MCP2515_RX0BF)) #else if (_bit_is_set(status, 6)) #endif mcp2515_bit_modify(CANINTF, (1<<RX0IF), 0); else mcp2515_bit_modify(CANINTF, (1<<RX1IF), 0); return 0; } #endif // read DLC uint8_t length = spi_putc(0xff); #ifdef RXnBF_FUNKTION if (!(tmp & 0x01)) msg->flags.rtr = (tmp & 0x02) ? 1 : 0; else msg->flags.rtr = (length & (1<<RTR)) ? 1 : 0; #else msg->flags.rtr = (_bit_is_set(status, 3)) ? 1 : 0; #endif length &= 0x0f; msg->length = length; // read data for (uint8_t i=0;i<length;i++) { msg->data[i] = spi_putc(0xff); } SET(MCP2515_CS); // clear interrupt flag #ifdef RXnBF_FUNKTION if (!IS_SET(MCP2515_RX0BF)) #else if (_bit_is_set(status, 6)) #endif mcp2515_bit_modify(CANINTF, (1<<RX0IF), 0); else mcp2515_bit_modify(CANINTF, (1<<RX1IF), 0); CAN_INDICATE_RX_TRAFFIC_FUNCTION; #ifdef RXnBF_FUNKTION return 1; #else return (status & 0x07) + 1; #endif }