Ejemplo n.º 1
0
uint8_t receiveSingleFrame() { 
    
    uint8_t ret = LW232_OK;
    uint8_t idx = 0;
    if (CAN_OK == readMsgBufID(&lw232_CanId, &lw232_PacketLen, lw232_Buffer)) {
        if (lw232_CanId > 0x1FFFFFFF) {
            ret = LW232_ERR; // address if totally wrong
        }
        else if (checkPassFilter(lw232_CanId)) {// do we want to skip some addresses?
            if (isExtendedFrame()) {
                printChar(LW232_TR29);
                printFullByte(HIGH_BYTE(HIGH_WORD(lw232_CanId)));
                printFullByte(LOW_BYTE(HIGH_WORD(lw232_CanId)));
                printFullByte(HIGH_BYTE(LOW_WORD(lw232_CanId)));
                printFullByte(LOW_BYTE(LOW_WORD(lw232_CanId)));
            }
            else {
                printChar(LW232_TR11);
                printNibble(HIGH_BYTE(LOW_WORD(lw232_CanId)));
                printFullByte(LOW_BYTE(LOW_WORD(lw232_CanId)));
            }
            //write data len
            printNibble(lw232_PacketLen);
            //write data
            for (idx = 0; idx < lw232_PacketLen; idx++) {
                printFullByte(lw232_Buffer[idx]);
            }
            //write timestamp if needed
            if (lw232_TimeStamp != LW232_TIMESTAMP_OFF) {
                uint32_t time = 0; //millis();
                if (lw232_TimeStamp == LW232_TIMESTAMP_ON_NORMAL) { 
                    // standard LAWICEL protocol. two bytes.
                    time %= 60000;  
                } else {
                    // non standard protocol - 4 bytes timestamp
                    printFullByte(HIGH_BYTE(HIGH_WORD(time)));
                    printFullByte(LOW_BYTE(HIGH_WORD(time)));
                }
                printFullByte(HIGH_BYTE(LOW_WORD(time)));
                printFullByte(LOW_BYTE(LOW_WORD(time)));
            }
        }
    }
    else {
        ret = LW232_ERR;
    }
    return ret;
}
Ejemplo n.º 2
0
INT8U Can232::sendMsgBuf(INT32U id, INT8U ext, INT8U rtr, INT8U len, INT8U *buf) {
#ifndef _MCP_FAKE_MODE_
    return lw232CAN.sendMsgBuf(id, ext, rtr, len, buf);
#else
    Serial.print("<sending:");
    Serial.print(id, HEX);
    Serial.print(',');
    if (ext) Serial.print('+');
    else Serial.print('-');
    if (rtr) Serial.print('+');
    else Serial.print('-');
    Serial.print(',');
    Serial.print(len, DEC);
    Serial.print(',');
    int i;
    for (i = 0; i < len; i++) printFullByte(buf[i]);
    return CAN_OK;
#endif
}
Ejemplo n.º 3
0
//==============================================================================
// Parses and executes a command
// Returns: LW232_OK in case of success, otherwise - specific error code
//------------------------------------------------------------------------------
void CAN232_Command(char * command) {
    //SYS_PRINT(">%s", command);
    
    uint8_t ret = LW232_OK;
    uint8_t idx = 0;
    uint8_t err = 0;

    lw232_LastErr = LW232_OK;

    switch (command[0]) {
        case LW232_CMD_SETUP:
            // Sn[CR] Setup with standard CAN bit-rates where n is 0-9.
            if (lw232_CanChannelMode == LW232_STATUS_CAN_CLOSED) {
                idx = parseNibbleWithLimit(command[1], LW232_CAN_BAUD_NUM);
                lw232_CanSpeedSelection = lw232_CanBaudRates[idx];
                
            }
            else {
                ret = LW232_ERR;
            }
            break;
        case LW232_CMD_SETUP_BTR:
            // sxxyy[CR] Setup with BTR0/BTR1 CAN bit-rates where xx and yy is a hex value.
            ret = LW232_ERR; break;
        case LW232_CMD_OPEN:
            // O[CR] Open the CAN channel in normal mode (sending & receiving).
            if (lw232_CanChannelMode == LW232_STATUS_CAN_CLOSED) {
                lw232_CanChannelMode = LW232_STATUS_CAN_OPEN_NORMAL;
                ret = openCanBus();
            }
            else {
                ret = LW232_ERR;
            }
            break;
        case LW232_CMD_LISTEN:
            // L[CR] Open the CAN channel in listen only mode (receiving).
            if (lw232_CanChannelMode == LW232_STATUS_CAN_CLOSED) {
                lw232_CanChannelMode = LW232_STATUS_CAN_OPEN_LISTEN;
                ret = openCanBus();
            }
            else {
                ret = LW232_ERR;
            }
        break;
        case LW232_CMD_CLOSE:
            // C[CR] Close the CAN channel.
            if (lw232_CanChannelMode != LW232_STATUS_CAN_CLOSED) {
                lw232_CanChannelMode = LW232_STATUS_CAN_CLOSED;
                closeCanBus();
            }
            else {
                ret = LW232_ERR;
            }
        break;
        case LW232_CMD_TX11:
            // tiiildd...[CR] Transmit a standard (11bit) CAN frame.
            if (lw232_CanChannelMode == LW232_STATUS_CAN_OPEN_NORMAL) {
                lw232_CanId = parseCanStdId(command);
                lw232_PacketLen = parseNibbleWithLimit(command[LW232_OFFSET_STD_PKT_LEN], LW232_FRAME_MAX_LENGTH);
                for (idx=0; idx < lw232_PacketLen; idx++) {
                    lw232_Buffer[idx] = parseFullByte(command[LW232_OFFSET_STD_PKT_DATA + idx * 2], 
                                                     command[LW232_OFFSET_STD_PKT_DATA + idx * 2 + 1]);
                }
                if (CAN_OK != sendMsgBuf(lw232_CanId, 0, 0, lw232_PacketLen, lw232_Buffer)) {
                    ret = LW232_ERR;
                }
                else if (lw232_AutoPoll) {
                    ret = LW232_OK_SMALL;
                }
            }
            else {
                ret = LW232_ERR;
            }
        break;
    case LW232_CMD_TX29:
        // Tiiiiiiiildd...[CR] Transmit an extended (29bit) CAN frame
        if (lw232_CanChannelMode == LW232_STATUS_CAN_OPEN_NORMAL) {
            lw232_CanId = parseCanExtId(command);
            lw232_PacketLen = parseNibbleWithLimit(command[LW232_OFFSET_EXT_PKT_LEN], LW232_FRAME_MAX_LENGTH);
            for (idx=0; idx < lw232_PacketLen; idx++) {
                lw232_Buffer[idx] = parseFullByte(command[LW232_OFFSET_EXT_PKT_DATA + idx * 2],
                                                 command[LW232_OFFSET_EXT_PKT_DATA + idx * 2 + 1]);
            }
            if (CAN_OK != sendMsgBuf(lw232_CanId, 1, 0, lw232_PacketLen, lw232_Buffer)) {
                ret = LW232_ERR;
            } else if (lw232_AutoPoll) {
                ret = LW232_OK_BIG;
            }
        }
        break;
    case LW232_CMD_RTR11:
        // riiil[CR] Transmit an standard RTR (11bit) CAN frame.
        if (lw232_CanChannelMode == LW232_STATUS_CAN_OPEN_NORMAL) {
            parseCanStdId(command);
            lw232_PacketLen = parseNibbleWithLimit(command[LW232_OFFSET_STD_PKT_LEN], LW232_FRAME_MAX_LENGTH);
            if (CAN_OK != sendMsgBuf(lw232_CanId, 0, 1, lw232_PacketLen, lw232_Buffer)) {
                ret = LW232_ERR;
            }
            else if (lw232_AutoPoll) {
                ret = LW232_OK_SMALL;
            }
        }
        else {
            ret = LW232_ERR;
        }
        break;
    case LW232_CMD_RTR29:
        // Riiiiiiiil[CR] Transmit an extended RTR (29bit) CAN frame.
        if (lw232_CanChannelMode == LW232_STATUS_CAN_OPEN_NORMAL) {
            parseCanExtId(command);
            lw232_PacketLen = parseNibbleWithLimit(command[LW232_OFFSET_EXT_PKT_LEN], LW232_FRAME_MAX_LENGTH);
            if (CAN_OK != sendMsgBuf(lw232_CanId, 1, 1, lw232_PacketLen, lw232_Buffer)) {
                ret = LW232_ERR;
            }
            else if (lw232_AutoPoll) {
                ret = LW232_OK_SMALL; // not a typo. strangely can232_v3.pdf tells to return "z[CR]", not "Z[CR]" as in 29bit. todo: check if it is error in pdf???
            }
        } else {
            ret = LW232_ERR;
        }
        break;
    case LW232_CMD_POLL_ONE:
        // P[CR] Poll incomming FIFO for CAN frames (single poll)
        if (lw232_CanChannelMode != LW232_STATUS_CAN_CLOSED && lw232_AutoPoll == LW232_AUTOPOLL_OFF) {
            if (CAN_MSGAVAIL == checkReceive()) {
                ret = receiveSingleFrame();
            }
        } else {
            ret = LW232_ERR;
        }
        break;
    case LW232_CMD_POLL_MANY:
        // A[CR] Polls incomming FIFO for CAN frames (all pending frames)
        if (lw232_CanChannelMode != LW232_STATUS_CAN_CLOSED && lw232_AutoPoll == LW232_AUTOPOLL_OFF) {
            while (CAN_MSGAVAIL == checkReceive()) {
                ret = ret ^ receiveSingleFrame();
                if (ret != CAN_OK)
                    break;
                printChar(LW232_CR);
            }
            if (ret == CAN_OK)
                printChar(LW232_ALL);
        } else {
            ret = LW232_ERR;
        }
        break;
    case LW232_CMD_FLAGS:
        // F[CR] Read Status Flags.
        // LAWICEL CAN232 and CANUSB have some specific errors which differ from MCP2515/MCP2551 errors. We just return MCP2515 error.
        printChar(LW232_FLAG);
        if (checkError(&err) == CAN_OK) 
            err = 0;
        printFullByte(err & 0xFF); //MCP_EFLG_ERRORMASK);
        break;
    case LW232_CMD_AUTOPOLL:
        // Xn[CR] Sets Auto Poll/Send ON/OFF for received frames.
        if (lw232_CanChannelMode == LW232_STATUS_CAN_CLOSED) {
            lw232_AutoPoll = (command[1] == LW232_ON_ONE) ? LW232_AUTOPOLL_ON : LW232_AUTOPOLL_OFF;
            //todo: save to eeprom
        } else {
            ret = LW232_ERR;
        }
        break;
    case LW232_CMD_FILTER:
        // Wn[CR] Filter mode setting. By default CAN232 works in dual filter mode (0) and is backwards compatible with previous CAN232 versions.
        ret = LW232_ERR_NOT_IMPLEMENTED; break;
    case LW232_CMD_ACC_CODE:
        // Mxxxxxxxx[CR] Sets Acceptance Code Register (ACn Register of SJA1000). // we use MCP2515,
        ret = LW232_ERR_NOT_IMPLEMENTED; break;
    case LW232_CMD_ACC_MASK:
        // mxxxxxxxx[CR] Sets Acceptance Mask Register (AMn Register of SJA1000).
        ret = LW232_ERR_NOT_IMPLEMENTED; break;
    case LW232_CMD_UART:
        // Un[CR] Setup UART with a new baud rate where n is 0-6.
        idx = parseNibbleWithLimit(command[1], LW232_UART_BAUD_NUM);
        SYS_PRINT("%d",lw232_SerialBaudRates[idx]);
        break;
    case LW232_CMD_VERSION1:
    case LW232_CMD_VERSION2:
        // V[CR] Get Version number of both CAN232 hardware and software
        SYS_PRINT(LW232_LAWICEL_VERSION_STR);
        break;
    case LW232_CMD_SERIAL:
        // N[CR] Get Serial number of the CAN232.
        SYS_PRINT(LW232_LAWICEL_SERIAL_NUM);
        break;
    case LW232_CMD_TIMESTAMP:
        // Zn[CR] Sets Time Stamp ON/OFF for received frames only. Z0 - OFF, Z1 - Lawicel's timestamp 2 bytes, Z2 - arduino timestamp 4 bytes.
        if (lw232_CanChannelMode == LW232_STATUS_CAN_CLOSED) {
            // lw232_TimeStamp = (command[1] == LW232_ON_ONE); 
            if (command[1] == LW232_ON_ONE) {
                lw232_TimeStamp = LW232_TIMESTAMP_ON_NORMAL;
            }
            else if (command[1] == LW232_ON_TWO) {
                lw232_TimeStamp = LW232_TIMESTAMP_ON_EXTENDED;
            }
            else {
                lw232_TimeStamp = LW232_TIMESTAMP_OFF;
            }
        }
        else {
            ret = LW232_ERR;
        }
        break;
    case LW232_CMD_AUTOSTART:
        // Qn[CR] Auto Startup feature (from power on).
        if (lw232_CanChannelMode != LW232_STATUS_CAN_CLOSED) {
            if (command[1] == LW232_ON_ONE) {
                lw232_AutoStart = LW232_AUTOSTART_ON_NORMAL;
            }
            else if (command[1] == LW232_ON_TWO) {
                lw232_AutoStart = LW232_AUTOSTART_ON_LISTEN;
            }
            else {
                lw232_AutoStart = LW232_AUTOSTART_OFF;
            }
            //todo: save to eeprom
        }
        else {
            ret = LW232_ERR;
        }
        break;
    default:
        ret = LW232_ERR_UNKNOWN_CMD;
    }

    
    lw232_LastErr = ret; //parseAndRunCommand();

    switch (lw232_LastErr) {
    case LW232_OK:
        printChar(LW232_RET_ASCII_OK);
        break;
    case LW232_OK_SMALL:
        printChar(LW232_RET_ASCII_OK_SMALL);
        printChar(LW232_RET_ASCII_OK);
        break;
    case LW232_OK_BIG:
        printChar(LW232_RET_ASCII_OK_BIG);
        printChar(LW232_RET_ASCII_OK);
        break;
    case LW232_ERR_NOT_IMPLEMENTED:
        // Choose behavior: will it fail or not when not implemented command comes in. Some can monitors might be affected by this selection.
        printChar(LW232_RET_ASCII_ERROR);
        //SYS_PRINT(LW232_RET_ASCII_OK); 
        break;
    default:
        printChar(LW232_RET_ASCII_ERROR);
    }
}