test

Dependencies:   mbed

main.cpp

Committer:
takahashi_tomoya
Date:
2019-08-23
Revision:
0:9d4b535b9c8e

File content as of revision 0:9d4b535b9c8e:

#include "mbed.h"

//------------------------------------------------------------------------- 
// F-CAN 制御系(エンジンとか)
#define VSA_091         0x091
#define STR_156         0x156
#define EAT_158         0x158
#define ENG_17C         0x17C
#define VSA_1A4         0x1A4
#define METER_1A6       0x1A6
#define METER_294       0x294
#define SRS_305         0x305
#define ENG_320         0x320
#define ENG_324         0x324
#define TPMS_333        0x333
#define ENG_40C         0x40C
#define ENG_454         0x454


// B-CAN ボディ系(ドアとか)
#define HLSW_ICU        0x0AF87010
#define ACINFO          0x0EF95251
#define ACSTATE         0x0EF97B51
#define MICU_ICU        0x12F81010
#define DOORSW_ICU      0x12F83010
#define ASDOORSW_ICU    0x12F84010
#define AT              0x12F85150
#define ACHV            0x12F85851
#define ODO_TRIP        0x12F95F50
#define TRICOM2         0x12F96150
#define TRICOM3         0x12F96250
#define TRICOM4         0x12F96B50
#define ACHTR           0x12F97051


//------------------------------------------------------------------------- 
// Honda Vehicle Data Protocol

#define MSG_MAGIC_H                 0x5E
#define MSG_MAGIC_L                 0xC0

#define MSG_TYPE_DEBUG_LOG          0x01
#define MSG_TYPE_SUBSCRIBE          0x10
#define MSG_TYPE_REPORT_CAN_DATA    0x11
#define MSG_TYPE_SEND_CAN_DATA      0x12
#define MSG_TYPE_ACK_CAN_DATA       0x13
#define MSG_TYPE_SET_REAR_CAM       0x20
#define MSG_TYPE_SET_ACTIVE_CAM     0x21
#define MSG_TYPE_REPORT_KEY_EVENT   0x30

#define MSG_MIN_LEN         4   // minimum bytes of message ( contains header )
#define MSG_SUBSCRIBE_LEN   4

#define MAX_RX_BYTES    16

char sppRxBuffer[MAX_RX_BYTES];
char rxCnt;

//------------------------------------------------------------------------- 

Ticker debugViewer;
Ticker btSender;
Serial bluetooth(p13,p14);    // p13: TX, p14: RX (LPC1768)


typedef struct CanDataTable {
    bool            isUpdated:1;    // turns to 1 if first data in period is received. cleared after sending.
    bool            needToSend:1;   // turns to 1 if data is received.
    bool            hasData:1;      // turns to 1 if data is received at least once.
    unsigned long   id;
    unsigned char   dlc;
    unsigned char   data[8];
} CanBuf_t;

#define MAX_DATA_FREQ               10 * 1000   // 10 sec
#define MAX_CAN_TABLE_NUM   32


class SabCan {
    private:
        Serial      *serial;

    public:
        CAN         *can;
        char        canTableNum;
        CanBuf_t    canTableBuffer[MAX_CAN_TABLE_NUM];
        unsigned long retrievedCnt;
        int         updatedCnt;

    public:
        unsigned long   canIdToIndex[MAX_CAN_TABLE_NUM];

    public:
        SabCan( CAN *_can, int baudrate );
        
        ~SabCan( void ) {}

        void initCanTableBuffer( bool isAllClear );
        void setFilter( unsigned long id );
        void debugShow( void );
        void attach( Callback<void()> func );
        
        void setSerial( Serial *serial );
        void writeToSerial( void );
        bool sendCanData( CanBuf_t *buf );

    private:
        // void receiveCallback( void );
};

// SabCan fCan(p30, p29, 500 * 1000);
CAN _fCan(p30, p29);
SabCan fCan( &_fCan, 500 * 1000);
// SabCan bCan(p9, p10, 125 * 1000);

void receiveCallback( SabCan *can );
void fReceiveCallback( void );
// void bReceiveCallback( void );

//------------------------------------------------------------------------- 
SabCan::SabCan( CAN *_can, int baudrate )
{
    can = _can;
    can->frequency( baudrate );
    
    initCanTableBuffer( true );

    retrievedCnt = 0;
    
}

//------------------------------------------------------------------------- 
void
SabCan::initCanTableBuffer( bool isAllClear )
{
    updatedCnt = 0;
    for ( int i = 0; i < canTableNum; i++ ) {
        CanBuf_t *buf = &canTableBuffer[i];
        buf->id = canIdToIndex[i];
        if ( isAllClear ) {
            buf->isUpdated = buf->needToSend = buf->hasData = 0;
        } else {
            buf->isUpdated = buf->needToSend = buf->hasData;
            updatedCnt += (buf->hasData == true) ? 1 : 0;
        }
    }
}

//------------------------------------------------------------------------- 
void
SabCan::setFilter( unsigned long id )
{
    canIdToIndex[canTableNum++] = id;
    can->filter( id, 0 );
}

//------------------------------------------------------------------------- 
void
SabCan::attach( Callback<void()> func )
{
    can->attach(func);
}

//------------------------------------------------------------------------- 
void
fcanCb( void )
{
    receiveCallback( &fCan );
}

//------------------------------------------------------------------------- 
void
receiveCallback( SabCan *can )
{
    CANMessage msg;

    can->can->read(msg);
    if ( msg.id == ENG_17C ) {
        can->retrievedCnt++;
    }

    for ( int i = 0; i < can->canTableNum; i++ ) {
        if ( msg.id == can->canIdToIndex[i] ) {
            CanBuf_t *buf = &can->canTableBuffer[i];

            // copy data 
            for ( int j = 0; j < msg.len; j++ ) {
                if ( buf->data[j] != msg.data[j] ) {
                    buf->needToSend = true;
                    buf->data[j] = msg.data[j];
                }
            }
            if ( buf->isUpdated || !(buf->needToSend) ) {
                break;
            }
            can->updatedCnt++;
            buf->isUpdated = true;

            if ( !buf->hasData ) {
                buf->dlc = msg.len;
                buf->hasData = true;
            }
            break;
        }
    }
}

//------------------------------------------------------------------------- 
void
SabCan::setSerial( Serial *_serial )
{
    serial = _serial;
}

//------------------------------------------------------------------------- 
bool
SabCan::sendCanData( CanBuf_t *buf )
{

    if ( buf->needToSend ) {
#ifndef DRY_RUN
        serial->putc( (buf->id >> 24) & 0xFF );
        serial->putc( (buf->id >> 16) & 0xFF );
        serial->putc( (buf->id >> 8) & 0xFF );
        serial->putc( buf->id & 0xFF );

        serial->putc( buf->dlc );
        for ( int i = 0; i < buf->dlc; i++ ) {
            serial->putc( buf->data[i] );
        }
#endif  // DRY_RUN

        buf->needToSend = false;
        buf->isUpdated = false;
        return true;
    } else {
        return false;
    }
}

//------------------------------------------------------------------------- 
void
SabCan::writeToSerial( void )
{
#if 0
    if ( !serial ) {
        return;
    }

    for ( int i = 0; i < canTableNum; i++ ) {
        CanBuf_t  *buf = &canTableBuffer[i];

        if ( buf->needToSend ) {
            serial->printf( "%X : %d : [", buf->id, buf->dlc );
            for ( int j = 0; j < buf->dlc; j++ ) {
                serial->printf( "%02X ", buf->data[j] );
            }
            serial->printf( "]\n" );
            buf->needToSend = false;
            buf->isUpdated = false;
        }
    }
#endif
    int sent = 0;
    unsigned long curTime = 0;

#ifndef DRY_RUN
    // magic
    serial->putc( MSG_MAGIC_H );
    serial->putc( MSG_MAGIC_L );
    
    // message type
    serial->putc( MSG_TYPE_REPORT_CAN_DATA );
    
    // reception time
    serial->putc( (unsigned char) 0 );
    serial->putc( (unsigned char) 0 );
    serial->putc( (unsigned char) 0 );
    serial->putc( (unsigned char) 0 );
    serial->putc( (curTime >> 24) & 0xFF );
    serial->putc( (curTime >> 16) & 0xFF );
    serial->putc( (curTime >> 8) & 0xFF );
    serial->putc( curTime & 0xFF );
    
    // # of frames
    serial->putc( (unsigned char) 0 );
    serial->putc( updatedCnt );
#endif  // DRY_RUN

    for ( int i = 0; i < canTableNum; i++ ) {
        if ( sendCanData( &canTableBuffer[i] ) ) {
            sent++;
        }
    }
}

//------------------------------------------------------------------------- 
void
SabCan::debugShow( void )
{
    printf( "# of updated  : %d\n", updatedCnt );
    printf( "# of retrieved  : %lu\n", retrievedCnt );
    printf( "# of rd error  : %d\n", can->rderror() );
    retrievedCnt = 0;
    for ( int i = 0; i < canTableNum; i++ ) {
        CanBuf_t  *buf = &canTableBuffer[i];
        printf( "%lu : %d : [", buf->id, buf->dlc );
        for ( int j = 0; j < buf->dlc; j++ ) {
            printf( "%02X ", buf->data[j] );
        }
        printf( "]\n" );
    }
}

#if 0
//------------------------------------------------------------------------- 
void
btCallback( void )
{
    for ( int i = 0; i < fCanTableNum; i++ ) {
        CanBuf_t  *buf = &fCanTableBuffer[i];
        if ( buf->needToSend ) {
            bluetooth.printf( "%X : %d : [", buf->id, buf->dlc );
            for ( int j = 0; j < buf->dlc; j++ ) {
                bluetooth.printf( "%02X ", buf->data[j] );
            }
            bluetooth.printf( "]\n" );
            buf->needToSend = false;
            buf->isUpdated = false;
        }
    }
    for ( int i = 0; i < bCanTableNum; i++ ) {
        CanBuf_t  *buf = &bCanTableBuffer[i];
        if ( buf->needToSend ) {
            bluetooth.printf( "%X : %d : [", buf->id, buf->dlc );
            for ( int j = 0; j < buf->dlc; j++ ) {
                bluetooth.printf( "%02X ", buf->data[j] );
            }
            bluetooth.printf( "]\n" );
            buf->needToSend = false;
            buf->isUpdated = false;
        }
    }
}
#endif

//------------------------------------------------------------------------- 
int
main( void )
{
    printf("main()\n");
    CANMessage msg;

    // bCan.frequency(125 * 1000);
#if 0
    LPC_CAN1->MOD |= 1;          // Disble CAN controller
    LPC_CAN1->MOD |= (1 << 1);   // Put into listen only mode
    LPC_CAN1->MOD &= ~(1);       // Re-enable CAN controller
#endif

    // Initialize index table
    fCan.setFilter( VSA_091 );
    fCan.setFilter( STR_156 );
    fCan.setFilter( EAT_158 );
    fCan.setFilter( ENG_17C );
    fCan.setFilter( VSA_1A4 );
    fCan.setFilter( METER_1A6 );
    fCan.setFilter( METER_294 );
    fCan.setFilter( SRS_305 );
    fCan.setFilter( ENG_320 );
    fCan.setFilter( ENG_324 );
    fCan.setFilter( TPMS_333 );
    fCan.setFilter( ENG_40C );
    fCan.setFilter( ENG_454 );

    fCan.attach( fcanCb );
    fCan.setSerial( &bluetooth );

#if 0
    bCanIdToIndex[bCanTableNum++] = HLSW_ICU;
    bCanIdToIndex[bCanTableNum++] = ACINFO;
    bCanIdToIndex[bCanTableNum++] = ACSTATE;
    bCanIdToIndex[bCanTableNum++] = MICU_ICU;
    bCanIdToIndex[bCanTableNum++] = DOORSW_ICU;
    bCanIdToIndex[bCanTableNum++] = ASDOORSW_ICU;
    bCanIdToIndex[bCanTableNum++] = AT;
    bCanIdToIndex[bCanTableNum++] = ACHTR;
    bCanIdToIndex[bCanTableNum++] = ODO_TRIP;
    bCanIdToIndex[bCanTableNum++] = ACHV;
    bCanIdToIndex[bCanTableNum++] = TRICOM2;
    bCanIdToIndex[bCanTableNum++] = TRICOM3;
    bCanIdToIndex[bCanTableNum++] = TRICOM4;
    bCanIdToIndex[bCanTableNum++] = ACHTR;
#endif

    // bCan.attach(&bCanCallback);

    while ( 1 ) {
        static int cnt;
        fCan.writeToSerial();
        wait( 0.1 );

        if ( (cnt % 20) == 0 ) {
            fCan.debugShow();
        }
    }
}