// ----------------------------------------------------------------------------------------
//
//  avr/can/mcp2515.h
//    
//  Bob Cook Development, Robotics Library
//  http://www.bobcookdev.com/rl/
//    
//  This file implements CAN support using the Microchip MCP2515 via SPI.
//
//  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.
//
// ----------------------------------------------------------------------------------------


#if !defined( BCDRL_AVR_CAN_MCP2515_H )
#define BCDRL_AVR_CAN_MCP2515_H


#include <stdint.h>


// ----------------------------------------------------------------------------------------
//  definitions from "project_defs.h"
//
//  enable MCP2515 support with:
//
//      + PRJ_MCP2515_ENABLE
//
//  specify the SELECT pin for SPI communications with:
//
//      + PRJ_MCP2515_SELECT_DDR
//      + PRJ_MCP2515_SELECT_PORT
//      + PRJ_MCP2515_SELECT_PIN
//
//  specify the (optional) RESET pin with:
//
//      + PRJ_MCP2515_USE_HW_RESET
//      + PRJ_MCP2515_RESET_DDR
//      + PRJ_MCP2515_RESET_PORT
//      + PRJ_MCP2515_RESET_PIN
//
//  enable interrupt-driven RX and TX with:
//
//      + PRJ_MCP2515_USE_INTERRUPT_RXTX
//      + PRJ_MCP2515_RX_BUFFER_SIZE (14 bytes each, default is 4)
//      + PRJ_MCP2515_TX_BUFFER_SIZE (14 bytes each, default is 6)
//
//  specify the CAN bus speed with one of:
//
//      + PRJ_MCP2515_CANBUS_20_KHZ
//      + PRJ_MCP2515_CANBUS_125_KHZ
//
//  specify the clock frequency for the MCP2515 with one of:
//
//      + PRJ_MCP2515_FREQUENCY_4_MHZ
//      + PRJ_MCP2515_FREQUENCY_16_MHZ
//
//  enable the debug support with:
//
//      + PRJ_MCP2515_ENABLE_DEBUG
//
// ----------------------------------------------------------------------------------------


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

const uint8_t mcp2515_max_message_data = 0x08;

const uint8_t mcp2515_priority_urgent = 0x03;
const uint8_t mcp2515_priority_high   = 0x02;
const uint8_t mcp2515_priority_normal = 0x01;
const uint8_t mcp2515_priority_low    = 0x00;


// ----------------------------------------------------------------------------------------
//  mcp2515_init
//
//      Initialize the MCP2515 h/w according to the project_defs.h specification.
//
//      Returns true if the initialization was successful.
//

bool mcp2515_init();

    
// ----------------------------------------------------------------------------------------
//  mcp2515_reset
//
//      Reset the MCP2515 h/w. Any pending messages in the transmit or recieve buffers
//      are lost.
//

void mcp2515_reset();


// ----------------------------------------------------------------------------------------
//  mcp2515_process_interrupt
//
//      Respond to the INTERRUPT pin transitioning to a low state.
//
//      Only compiled if PRJ_MCP2515_USE_INTERRUPT_RXTX is defined.
//

void mcp2515_process_interrupt();


// ----------------------------------------------------------------------------------------
//  mcp2515_read
//
//      Read a pending message from one of the MCP2515 receive buffers. Does not block if
//      no message is available.
//
//      Returns true if a message was successfully received.
//

bool mcp2515_read    
    (
        uint32_t* can_id,
        bool*     is_request,
        uint8_t*  data_ptr,
        uint8_t*  length
    );


// ----------------------------------------------------------------------------------------
//  mcp2515_send
//
//      Queue an outgoing message into one of the MCP2515 transmit buffers.
//
//      Returns true if the message was successfully sent.
//

bool mcp2515_send
    (
        const uint32_t& can_id,
        const uint8_t*  data_ptr,
        uint8_t         length,
        uint8_t         priority = mcp2515_priority_normal
    );


// ----------------------------------------------------------------------------------------
//  mcp2515_request
//
//      Queue an outgoing request into one of the MCP2515 transmit buffers.
//
//      Returns true if the request was successfully sent.
//

bool mcp2515_request( const uint32_t& can_id, uint8_t priority = mcp2515_priority_normal );


// ----------------------------------------------------------------------------------------
//  mcp2515_debug_print_registers
//
//      Print the current state of the MCP2515 h/w registers to stdout.
//
//      Only compiled if PRJ_MCP2515_ENABLE_DEBUG is defined.
//

void mcp2515_debug_print_registers();


#endif  // #if defined( BCDRL_AVR_CAN_MCP2515_H )
// ----------------------------------------------------------------------------------------
//  end of mcp2515.h
// ----------------------------------------------------------------------------------------

