view main/robots/odr-gps/canmsgs.cpp @ 257:9e43076f1433 main

Updates for the more modern platform: 500kHz bus speed, better error handling, remvoe unnecessary code.
author Bob Cook <bob@bobcookdev.com>
date Mon, 07 Sep 2015 20:28:32 -0700
parents 74381e5dd204
children
line wrap: on
line source

// ----------------------------------------------------------------------------------------
//
//  Copyright (C) 2013-2015 Bob Cook
//    
//  Bob Cook Development, Robotics Library
//  http://www.bobcookdev.com/rl/
// 
//  CAN related functions for the Outdoor Robot gps node.
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
// 
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
// 
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
// ----------------------------------------------------------------------------------------

#include "project_defs.h"

#include "func.h"

#include "packages/avr/can/m1.h"

#include "packages/common/gps/nmea.h"
#include "packages/common/can/can_helpers.h"
#include "packages/common/can/can_messages.h"
#include "packages/common/can/can_nodes.h"

#include "packages/avr/device/spinwait.h"

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

bool canmsg_init()
{
    return m1can_init();
}

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

bool canmsg_send_emergency()
{
    return m1can_send( can_build_message_id( can_node_sensor_gps,
                                             can_node_broadcast,
                                             can_dataid_emergency ), 0, 0 );
}

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

bool canmsg_send_all_clear()
{
    return m1can_send( can_build_message_id( can_node_sensor_gps,
                                             can_node_broadcast,
                                             can_dataid_all_clear ), 0, 0 );
}

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

bool canmsg_send_heartbeat()
{
    return m1can_send( can_build_message_id( can_node_sensor_gps,
                                             can_node_broadcast,
                                             can_dataid_heartbeat ), 0, 0 );
}

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

bool canmsg_send_gps_fix_info( uint8_t satellites )
{
    uint32_t msgid;
    msgid = can_build_message_id( can_node_sensor_gps,
                                  can_node_broadcast,
                                  can_dataid_gps_fix );

    can_data_gps_fix data;
    data.satellites = satellites;

    return m1can_send( msgid, reinterpret_cast< uint8_t* >( &data ), sizeof( data ) );
}

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

bool canmsg_send_gps_latitude( int16_t degrees, uint16_t minutes, uint16_t min_fract )
{
    uint32_t msgid;
    msgid = can_build_message_id( can_node_sensor_gps,
                                  can_node_broadcast,
                                  can_dataid_gps_latitude );

    can_data_gps_data data;

    data.degrees          = degrees;
    data.min_thousandths  = minutes;
    data.min_thousandths *= can_data_gps_min_multiplier;
    data.min_thousandths += ( min_fract / // convert between units
                ( nmea_fractional_minutes_multiplier / can_data_gps_min_multiplier ) );

    return m1can_send( msgid, reinterpret_cast< uint8_t* >( &data ), sizeof( data ) );
}

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

bool canmsg_send_gps_longitude( int16_t degrees, uint16_t minutes, uint16_t min_fract )
{
    uint32_t msgid;
    msgid = can_build_message_id( can_node_sensor_gps,
                                  can_node_broadcast,
                                  can_dataid_gps_longitude );

    can_data_gps_data data;

    data.degrees          = degrees;
    data.min_thousandths  = minutes;
    data.min_thousandths *= can_data_gps_min_multiplier;
    data.min_thousandths += ( min_fract / // convert between units
                ( nmea_fractional_minutes_multiplier / can_data_gps_min_multiplier ) );

    return m1can_send( msgid, reinterpret_cast< uint8_t* >( &data ), sizeof( data ) );
}

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

bool canmsg_process_pending()
{
    uint32_t recvid;
    bool     recvrequest = false;
    uint8_t  recvdata[ 8 ];
    uint8_t  recvlen = sizeof( recvdata );

    for ( ;; )
    {
        if ( ! m1can_read( &recvid, &recvrequest, recvdata, &recvlen ) )
        {
            return true; // no messages, everything ok
        }

        uint8_t  srcnode;
        uint8_t  dstnode;
        uint16_t dataid;
        can_parse_message_id( recvid, &srcnode, &dstnode, &dataid );

        if ( dstnode != can_node_broadcast && dstnode != can_node_sensor_gps )
        {
            return true; // not for us, everything ok
        }

        switch ( dataid )
        {
            case can_dataid_emergency:
                status_got_emergency( srcnode );
                break;

            case can_dataid_all_clear:
                status_got_all_clear( srcnode );
                break;

            case can_dataid_heartbeat:
            case can_dataid_odrmgr_update:
                status_got_heartbeat( srcnode );
                break;
        }
    }

    return true; // no errors
}

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