// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

#pragma once

#include <stdint.h>

#include "hal/I2CTypes.h"

/**
 * @defgroup hal_i2c I2C Functions
 * @ingroup hal_capi
 * @{
 */

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Initializes the I2C port.
 *
 * Opens the port if necessary and saves the handle.
 * If opening the MXP port, also sets up the channel functions appropriately.
 *
 * @param[in] port    The port to open, 0 for the on-board, 1 for the MXP.
 * @param[out] status Error status variable. 0 on success.
 */
void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status);

/**
 * Generic I2C read/write transaction.
 *
 * This is a lower-level interface to the I2C hardware giving you more control
 * over each transaction.
 *
 * @param port The I2C port, 0 for the on-board, 1 for the MXP.
 * @param deviceAddress The address of the register on the device to be
 *                      read/written.
 * @param dataToSend Buffer of data to send as part of the transaction.
 * @param sendSize Number of bytes to send as part of the transaction.
 * @param dataReceived Buffer to read data into.
 * @param receiveSize Number of bytes to read from the device.
 * @return >= 0 on success or -1 on transfer abort.
 */
int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
                           const uint8_t* dataToSend, int32_t sendSize,
                           uint8_t* dataReceived, int32_t receiveSize);

/**
 * Executes a write transaction with the device.
 *
 * Writes a single byte to a register on a device and wait until the
 *   transaction is complete.
 *
 * @param port The I2C port, 0 for the on-board, 1 for the MXP.
 * @param deviceAddress The address of the register on the device to be
 *                      written.
 * @param dataToSend The byte to write to the register on the device.
 * @param sendSize Number of bytes to send.
 * @return >= 0 on success or -1 on transfer abort.
 */
int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
                     const uint8_t* dataToSend, int32_t sendSize);

/**
 * Executes a read transaction with the device.
 *
 * Reads bytes from a device.
 * Most I2C devices will auto-increment the register pointer internally allowing
 *   you to read consecutive registers on a device in a single transaction.
 *
 * @param port The I2C port, 0 for the on-board, 1 for the MXP.
 * @param deviceAddress The register to read first in the transaction.
 * @param count The number of bytes to read in the transaction.
 * @param buffer A pointer to the array of bytes to store the data read from the
 * device.
 * @return >= 0 on success or -1 on transfer abort.
 */
int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
                    int32_t count);

/**
 * Closes an I2C port
 *
 * @param port The I2C port, 0 for the on-board, 1 for the MXP.
 */
void HAL_CloseI2C(HAL_I2CPort port);
#ifdef __cplusplus
}  // extern "C"
#endif
/** @} */
