///
/// @file i2cp.h
/// @authors k. headley
/// @date 05 dec 2019

/// I2C primary (master) API
/// 2021-08-26 [klh] : this code is mostly untested; the bit-banged implementation
/// was tested w/o a secondary (slave) device using a PIC Curiosity development board.
/// The MCC implementation is untested, and potentially lacks logic for retries, error handling, etc..

/// In this wrapper library, both MCC and bit-banged I2C implementations are supported.
/// It should be possible to use them concurrently, provided that the hardware is configured correctly.
/// If either is unused, it's implementation is compiled out to minimize the resource footprint.

/// Applications should include i2cp.h and link ic2p.o
/// Configuration options are described below

///   i2cp.h - I2C API
///   i2cx-common.h - common data types and defintions
///   i2cx-bb.h -   I2C BB API and configuration
///   i2cx-mcc.h -  I2C MCC API and configuration
///   i2cp.c - contains  implementations for the BB and MCC versions

/// Configuration

/// i2cp.h
/// I2C implementation selecion
///  WITH_MMC_I2C1
///  WITH_MMC_I2C2
///  WITH_BB_I2C1
///  WITH_BB_I2C2
/// I2C bus handles for use by application code
///  I2CP_HND_BB1
///  I2CP_HND_BB2
///  I2CP_HND_MMC1
///  I2CP_HND_MMC2

/// i2cp-mcc.h
/// size of MCC transfer resource block data buffer (bytes)
///  TRB_BUFFER_BYTES

/// i2cp-bb.h
/// BB I2C clock and data pin selection
///  I2CP_I2C1_SDC_PIN
///  I2CP_I2C1_SDA_PIN
///  I2CP_I2C2_SDC_PIN
///  I2CP_I2C2_SDA_PIN
/// Additionally, the port, ODBC, ANSx, TRISx must be specified in
/// the appropriate bus data structure in  i2cp.c (i2c_bb_bus_1, i2c_bb_bus_2, etc.)

/// Notes :
/// For some reason, Microchip gives unique data types for otherwise identical structures used on each bus
/// generated by MCC.
/// This creates a problem since passing these unique types makes the function signatures unique for each bus,
/// making it impossible to simply index (e.g. via a handle) the functions in a table.
/// Further more, it may be necessary to use a bit-banged (BB) I2C implementation instead of the MCC one,
/// since the MCC implementation only works on specific pins,
/// To create an API that is consistent across implementations, a scheme is used to isolate the different
/// implemenations, and  to address the issue caused by MCC data typing.

/// The implementation mapping scheme is summarized as follows:
/// - each implementation allocates resources (data structures, buffers) for each bus that is defined
/// - in i2cx-mcc.h, generic types shadowing the uniquely named MCC types are defined
/// - in i2cp.c,  generic API wrapper functions  call implementation-specific functions; the implementation-specific
///  handles to the appropriate resources.

/// When  applications make a function call,
/// - The MCC implementation calls the appropriate generic API functions, passing generic
///  arguments that are cast to types required by the underlying MCC functions.
/// - The BB implementation uses the arguments directly, using the handle to index into an implementation
///  that includes bus hardware mappings and state.

/// @sa doxygen-examples.c for more examples of Doxygen markup


/////////////////////////
// Terms of use
/////////////////////////
/*
 Copyright Information
  
 Copyright 2002-2019 MBARI
 Monterey Bay Aquarium Research Institute, all rights reserved.
 
 Terms of Use
 
 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 3 of the License, or
 (at your option) any later version. You can access the GPLv3 license at
 http://www.gnu.org/licenses/gpl-3.0.html
 
 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
 (http://www.gnu.org/licenses/gpl-3.0.html)
 
 MBARI provides the documentation and software code "as is", with no warranty,
 express or implied, as to the software, title, non-infringement of third party
 rights, merchantability, or fitness for any particular purpose, the accuracy of
 the code, or the performance or results which you may obtain from its use. You
 assume the entire risk associated with use of the code, and you agree to be
 responsible for the entire cost of repair or servicing of the program with
 which you are using the code.
 
 In no event shall MBARI be liable for any damages, whether general, special,
 incidental or consequential damages, arising out of your use of the software,
 including, but not limited to, the loss or corruption of your data or damages
 of any kind resulting from use of the software, any prohibited use, or your
 inability to use the software. You agree to defend, indemnify and hold harmless
 MBARI and its officers, directors, and employees against any claim, loss,
 liability or expense, including attorneys' fees, resulting from loss of or
 damage to property or the injury to or death of any person arising out of the
 use of the software.
 
 The MBARI software is provided without obligation on the part of the
 Monterey Bay Aquarium Research Institute to assist in its use, correction,
 modification, or enhancement.
 
 MBARI assumes no responsibility or liability for any third party and/or
 commercial software required for the database or applications. Licensee agrees
 to obtain and maintain valid licenses for any additional third party software
 required.
 */

// Always do this
#ifndef I2CP_H
#define I2CP_H

/////////////////////////
// Includes 
/////////////////////////
#ifdef WITH_PIC24F_CURIOSITY
#include "bbcommon.h"
#endif // WITH_PIC24F_CURIOSITY
#include <xc.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "pic24.h"
#include "i2cx-common.h"
#include "i2cx-bb.h"
#include "i2cx-mcc.h"

/////////////////////////
// Macros
/////////////////////////

/// @def WITH_MMC_I2C1
/// @brief enable MMC I2C1 bus
#define WITH_MMC_I2C1

/// @def WITH_MMC_I2C2
/// @brief enable MMC I2C2 bus
#undef WITH_MMC_I2C2

/// @def WITH_BB_I2C1
/// @brief enable bit-banged I2C1 bus
#undef WITH_BB_I2C1

/// @def WITH_BB_I2C2
/// @brief enable bit-banged I2C2 bus
#undef WITH_BB_I2C2

#if defined WITH_MMC_I2C1 || defined WITH_MMC_I2C2
#define WITH_MMC_I2C
#endif

#if defined WITH_BB_I2C1 || defined WITH_I2C2
#define WITH_BB_I2C
#endif

/////////////////////////
// Type Definitions
/////////////////////////

///@typedef enum i2cp_hnd_t
///@brief I2C bus handle IDs
/// Applications use these to reference I2C resources
typedef enum{
    I2CP_HND_INVALID = -1,
    I2CP_HND_BB1 = 0,
    I2CP_HND_BB2 = 1,
    I2CP_HND_MMC1 = 2,
    I2CP_HND_MMC2 = 3,
    I2CP_HND_COUNT
}i2cp_hnd_t;

/////////////////////////
// Exports
/////////////////////////

#ifdef __cplusplus
extern "C" {
#endif

void i2cp_initialize(i2cp_hnd_t hnd);
void i2cp_set_debug(i2cp_hnd_t hnd, bool enable);
bool i2cp_get_debug(i2cp_hnd_t hnd);
bool i2cp_send_bytes(i2cp_hnd_t hnd, i2c_addr_t addr, byte *src, uint32_t len, uint32_t *bw);
bool i2cp_recv_bytes(i2cp_hnd_t hnd, i2c_addr_t addr, byte *dest, uint32_t len, uint32_t *br);

#ifdef __cplusplus
}
#endif

#endif // THIS_FILE
