/********************************************************************************************************* ** Function name: mcp2515_initCANBuffers ** Descriptions: init canbuffers *********************************************************************************************************/ void MCP_CAN::mcp2515_initCANBuffers(void) { INT8U i, a1, a2, a3; INT8U std = 0; INT8U ext = 1; INT32U ulMask = 0x00, ulFilt = 0x00; mcp2515_write_id(MCP_RXM0SIDH, ext, ulMask); /*Set both masks to 0 */ mcp2515_write_id(MCP_RXM1SIDH, ext, ulMask); /*Mask register ignores ext bit */ /* Set all filters to 0 */ mcp2515_write_id(MCP_RXF0SIDH, ext, ulFilt); /* RXB0: extended */ mcp2515_write_id(MCP_RXF1SIDH, std, ulFilt); /* RXB1: standard */ mcp2515_write_id(MCP_RXF2SIDH, ext, ulFilt); /* RXB2: extended */ mcp2515_write_id(MCP_RXF3SIDH, std, ulFilt); /* RXB3: standard */ mcp2515_write_id(MCP_RXF4SIDH, ext, ulFilt); mcp2515_write_id(MCP_RXF5SIDH, std, ulFilt); /* Clear, deactivate the three */ /* transmit buffers */ /* TXBnCTRL -> TXBnD7 */ a1 = MCP_TXB0CTRL; a2 = MCP_TXB1CTRL; a3 = MCP_TXB2CTRL; for (i = 0; i < 14; i++) { /* in-buffer loop */ mcp2515_setRegister(a1, 0); mcp2515_setRegister(a2, 0); mcp2515_setRegister(a3, 0); a1++; a2++; a3++; } mcp2515_setRegister(MCP_RXB0CTRL, 0); mcp2515_setRegister(MCP_RXB1CTRL, 0); }
bool mcp2515_set_filter(uint8_t number, const can_filter_t *filter) { uint8_t mask_address = 0; uint8_t mode = mcp2515_read_register(CANSTAT); if (number > 5) return false; // change to configuration mode mcp2515_change_operation_mode( (1<<REQOP2) ); // set filter mask if (number == 0) { mask_address = RXM0SIDH; #if SUPPORT_EXTENDED_CANID if (filter->flags.extended == 0x3) { // only extended identifier mcp2515_write_register(RXB0CTRL, (1<<RXM1)); } else if (filter->flags.extended == 0x2) { // only standard identifier mcp2515_write_register(RXB0CTRL, (1<<RXM0)); } else { // receive all messages mcp2515_write_register(RXB0CTRL, 0); } #else // Buffer 0: Empfangen aller Nachrichten mit Standard Identifier // die den Filter Kriterien gengen mcp2515_write_register(RXB0CTRL, (1<<RXM0)); #endif } else if (number == 2) { mask_address = RXM1SIDH; #if SUPPORT_EXTENDED_CANID if (filter->flags.extended == 0x3) { // only extended identifier mcp2515_write_register(RXB1CTRL, (1<<RXM1)); } else if (filter->flags.extended == 0x2) { // only standard identifier mcp2515_write_register(RXB1CTRL, (1<<RXM0)); } else { mcp2515_write_register(RXB1CTRL, 0); } #else // Buffer 1: Empfangen aller Nachrichten mit Standard Identifier // die den Filter Kriterien gengen mcp2515_write_register(RXB1CTRL, (1<<RXM0)); #endif } if (mask_address) { RESET(MCP2515_CS); spi_putc(SPI_WRITE); spi_putc(mask_address); #if SUPPORT_EXTENDED_CANID mcp2515_write_id(&filter->mask, (filter->flags.extended == 0x2) ? 0 : 1); #else mcp2515_write_id(&filter->mask); #endif SET(MCP2515_CS); _delay_us(1); } // write filter uint8_t filter_address; if (number >= 3) { number -= 3; filter_address = RXF3SIDH; } else { filter_address = RXF0SIDH; } RESET(MCP2515_CS); spi_putc(SPI_WRITE); spi_putc(filter_address | (number * 4)); #if SUPPORT_EXTENDED_CANID mcp2515_write_id(&filter->id, (filter->flags.extended == 0x2) ? 0 : 1); #else mcp2515_write_id(&filter->id); #endif SET(MCP2515_CS); _delay_us(1); // restore previous mode mcp2515_change_operation_mode( mode ); return true; }
// ---------------------------------------------------------------------------- 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_set_filter(uint8_t number, const can_filter_t *filter) { uint8_t mask_address = 0; if (number > 5) return false; // Konfiguration einschalten mcp2515_change_operation_mode( (1<<REQOP2) ); // Filtermaske setzen if (number == 0) { mask_address = RXM0SIDH; } else if (number == 2) { mask_address = RXM1SIDH; } if (mask_address) { RESET(MCP2515_CS); spi_putc(SPI_WRITE); spi_putc(mask_address); mcp2515_write_id(&filter->mask); asm volatile ("nop"); asm volatile ("nop"); SET(MCP2515_CS); asm volatile ("nop"); asm volatile ("nop"); } // Filter setzen uint8_t filter_address; if (number >= 3) { number -= 3; filter_address = RXF3SIDH; } else { filter_address = RXF0SIDH; } RESET(MCP2515_CS); spi_putc(SPI_WRITE); spi_putc(filter_address | (number * 4)); mcp2515_write_id(&filter->id); asm volatile ("nop"); asm volatile ("nop"); SET(MCP2515_CS); asm volatile ("nop"); asm volatile ("nop"); if (number == 0) { mcp2515_write_register(RXB0CTRL, (1<<RXM1)); } else if (number==2) { mcp2515_write_register(RXB1CTRL, (1<<RXM1)); } ; // zurueck zum normalen modus mcp2515_write_register(CANCTRL, 0); return true; }