// ----------------------------------------------------------------------------------------
//
//  avr/can/can_helpers.cpp
//
//  Bob Cook Development, Robotics Library
//  http://www.bobcookdev.com/rl/
//    
//  This file provides utility routines for a Controller Area Network driver.
//
//  Copyright (C) 2007 Bob Cook
//    
//      This program is free software; you can redistribute it and/or modify it
//      under the terms of the GNU General Public License as published by the
//      Free Software Foundation; either version 2 of the License, or (at your
//      option) any later version.
//    
//      This program is distributed in the hope that it will be useful, but 
//      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
//      or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
//      for more details.
//    
//      You should have received a copy of the GNU General Public License along
//      with this program; if not, write to the Free Software Foundation, Inc., 
//      51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// ----------------------------------------------------------------------------------------


#include "can_helpers.h"


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

uint32_t can_build_message_id
    (
        const uint8_t  node_src,
        const uint8_t  node_dst,
        const uint16_t data_type
    )
{
    //--    Build the full "extended" message id in our proprietary format:
    //
    //      00000000000000000000000000000000  uint32_t
    //
    //      3   2   2   1   1   1   7   3  0
    //      1   7   3   9   5   1
    //
    //          +----+                        source node id (six bits)
    //                +----+                  destination node id (six bits)
    //                      +--------------+  message id (sixteen bits)
    //         +                              unused (one bit)

    uint32_t msg_id;

    msg_id  = static_cast< uint32_t >( node_src & 0x3f ) << 22;
    msg_id |= static_cast< uint32_t >( node_dst & 0x3f ) << 16;
    msg_id |= static_cast< uint32_t >( data_type );

    return msg_id;
}


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

void can_parse_message_id
    (
        const uint32_t& message_id,
        uint8_t*        node_src,
        uint8_t*        node_dst,
        uint16_t*       data_type
    )
{
    // decode the full "extended" message id in our proprietary format:
    //
    //      00000000000000000000000000000000  uint32_t
    //
    //      3   2   2   1   1   1   7   3  0
    //      1   7   3   9   5   1
    //
    //          +----+                        source node id (six bits)
    //                +----+                  destination node id (six bits)
    //                      +--------------+  message id (sixteen bits)
    //         +                              unused (one bit)

    *data_type = static_cast< uint16_t >( message_id );
    *node_dst  = static_cast< uint8_t >( message_id >> 16 ) & 0x3f;
    *node_src  = static_cast< uint8_t >( message_id >> 22 ) & 0x3f;
}


// ----------------------------------------------------------------------------------------
//  end of can_helpers.cpp
// ----------------------------------------------------------------------------------------

