/** * @brief Configura a CAN */ void canSetup(void) { // Initialize MCP2515 can_init(BITRATE_125_KBPS); // Load filters and masks can_static_filter(can_filter); // Set normal mode can_set_mode(CAN_MODE); }
// ---------------------------------------------------------------------------- void usbcan_decode_command(char *str, uint8_t length) { uint8_t temp; if (length == 0) return; switch (str[0]) { case 'S': // set bitrate // Lawicel has the folowing settings: // S0 10 kbps // S1 20 kbps // S2 50 kbps // S3 100 kbps // S4 125 kbps // S5 250 kbps // S6 500 kbps // S7 800 kbps // S8 1 mbps; is index 7 on USB2CAN // Note that the USB2CAN adapter does not support 800 kbps. // With index 7 USB2CAN runs on 1 mbps. // Report error if the range is wrong, communication channel // already open, Parameter wrong or the user tries to set // 800 kbps, which is not supported. if ( ((temp = str[1] - '0') > 8) || channel_open || length != 2 || temp == 7 ) { goto error; } else { // Take care of different index usage for 1 mbps. if ( temp == 8 ) { temp--; } // Set new bitrate, remember all MOB are cleared! can_init(temp); bitrate_set = true; } break; case 'r': // send frames case 't': case 'R': case 'T': if ( !channel_open ) { goto error; } else { if ( !usbcan_decode_message(str, length) ) { goto error; } } break; case 'M': // Set acceptance code for SJA1000 case 'm': // Set acceptance mask for SJA1000 case 's': // Set BTR0/BTR1 for SJA1000 goto error; // TODO break; case 'O': // Open channel, i.e. connect CAN to output. if ( channel_open || !bitrate_set ) { goto error; } else { can_set_mode(NORMAL_MODE); // In case the baudrate changed, re-enable some filters. can_filter_t filter = { .mask = 0, .id = 0, .flags.extended = 0, .flags.rtr = 0 }; for (uint8_t i=11; i<15; i++) { can_set_filter(i, &filter); } // Mark the channel as open. channel_open = true; } break; case 'L': // Open channel, i.e. connect CAN to output in listen only mode. if ( channel_open || !bitrate_set ) { goto error; } else { can_set_mode(LISTEN_ONLY_MODE); channel_open = true; } break; case 'C': // Close channel, i.e. disconnect CAN from output. if ( !channel_open ) { goto error; } else { channel_open = false; } break; case 'F': // read Status Flags term_put_hex(0); // TODO break; case 'N': // read serial number term_putc( 'N' ); term_put_hex( 0 ); term_put_hex( 0 ); break; case 'V': // read hardware and firmeware version term_putc( 'V' ); term_put_hex( (HARDWARE_VERSION_MAJOR << 4) | HARDWARE_VERSION_MINOR ); term_put_hex( (SOFTWARE_VERSION_MAJOR << 4) | SOFTWARE_VERSION_MINOR ); break; case 'Z': // Switch on or off timestamps. // On Lawicel this value is stored in EEPROM. if ( channel_open || length != 2) { goto error; } else { use_timestamps = (str[1] - '0' == 0) ? false : true; CANTIM = 0; } break; } term_putc('\r'); // command could be executed return; error: term_putc(7); // Error in command } // ---------------------------------------------------------------------------- // processes commands in usbcan-protocol mode void usbcan_handle_protocol(void) { static char buffer[40]; static uint8_t pos; static can_error_register_t last_error = { 0, 0 }; can_error_register_t error; // check for new messages if (can_check_message()) { can_t message; // Only communicate data if channel is open. // Due to left -> right evaluation messages are extracted from the // MOB to avoid overflow, even if no communication is desired. if ( can_get_message(&message) && channel_open ) { uint8_t length = message.length; if (message.flags.rtr) { // print identifier if (message.flags.extended) { printf_P(PSTR("R%08lx"), message.id); } else { uint16_t id = message.id; printf_P(PSTR("r%03x"), id); } term_putc(length + '0'); } else { // print identifier if (message.flags.extended) { printf_P(PSTR("T%08lx"), message.id); } else { uint16_t id = message.id; printf_P(PSTR("t%03x"), id); } term_putc(length + '0'); // print data for (uint8_t i = 0; i < length; i++) term_put_hex(message.data[i]); } if (use_timestamps) printf_P(PSTR("%04x"), message.timestamp); term_putc('\r'); } } // get commands while (term_data_available()) { char chr = term_getc(); if (chr != '\r') { buffer[pos] = chr; pos++; if (pos >= sizeof(buffer)) { // format-error: command to long! pos = 0; } } else { buffer[pos] = '\0'; usbcan_decode_command(buffer, pos); pos = 0; } } // get error-register error = can_read_error_register(); if (last_error.tx != error.tx || last_error.rx != error.rx) { printf_P(PSTR("E%02x%02x\r"), error.rx, error.tx); last_error = error; } }