c2a-core 4.5.1

Core of Command Centric Architecture
Documentation
#pragma section REPRO
/**
 * @file
 * @brief I2C 通信関連の一般 IO 以外の公開関数
 * @note  レジスタの読み書き等,ハードウェアに依存しない関数群を定義する
 */

#include "i2c_common.h"
#include "../library/endian.h"
#include <string.h>

/**
 * @brief I2C_Config 構造体にて指定されたデバイスのレジスタへ書き込む
 * @param[in] p_super  : ComponentDriverSuper 構造体へのポインタ
 * @param[in] stream   : 使用する stream_config の番号
 * @param[in] p_i2c_config : 対象とする I2C_Config 構造体へのポインタ
 * @param[in] register_address : 書き込むレジスタのアドレス
 * @param[in] data_v   : 書き込むデータを格納している場所のポインタ
 * @param[in] data_len : 書き込むデータの長さ.1 or 2 [byte] のみ指定可
 * @retval CDS_ERR_CODE (CDS_send_general_cmd の返り値)
 */
static CDS_ERR_CODE I2C_write_bytes_(ComponentDriverSuper* p_super, uint8_t stream, I2C_Config* p_i2c_config,
                                     uint8_t register_address, void* data_v, uint8_t data_len);

/**
 * @brief I2C_Config 構造体にて指定されたデバイスのレジスタへ読み込む
 * @param[in] p_super  : ComponentDriverSuper 構造体へのポインタ
 * @param[in] stream   : 使用する stream_config の番号
 * @param[in] p_i2c_config : 対象とする I2C_Config 構造体へのポインタ
 * @param[in] register_address : 読み込むレジスタのアドレス
 * @param[out] data_v  : データ格納先へのポインタ
 * @param[in] buffer_size : 読み込むデータの長さ.
 * @retval CDS_ERR_CODE
 */
static CDS_ERR_CODE I2C_read_bytes_(ComponentDriverSuper* p_super, uint8_t stream, I2C_Config* p_i2c_config,
                                    uint8_t register_address, void* data_v, uint8_t buffer_size);

CDS_ERR_CODE I2C_write_byte(ComponentDriverSuper* p_super, uint8_t stream, I2C_Config* p_i2c_config, uint8_t register_address, uint8_t data)
{
  return I2C_write_bytes_(p_super, stream, p_i2c_config, register_address, &data, sizeof(data));
}

CDS_ERR_CODE I2C_write_2bytes(ComponentDriverSuper* p_super, uint8_t stream, I2C_Config* p_i2c_config, uint8_t register_address, uint16_t data)
{
  return I2C_write_bytes_(p_super, stream, p_i2c_config, register_address, &data, sizeof(data));
}

static CDS_ERR_CODE I2C_write_bytes_(ComponentDriverSuper* p_super, uint8_t stream, I2C_Config* p_i2c_config,
                                     uint8_t register_address, void* data_v, uint8_t data_len)
{
  uint8_t tx_data[sizeof(register_address) + sizeof(uint16_t)];
  CDS_StreamConfig* stream_config = &(p_super->stream_config[stream]);

  tx_data[0] = register_address;
  ENDIAN_memcpy(tx_data + sizeof(register_address), data_v, data_len);
  I2C_set_stop_flag(p_i2c_config, 1);
  CDSSC_set_tx_frame(stream_config, tx_data);
  CDSSC_set_tx_frame_size(stream_config, sizeof(register_address) + data_len);

  return CDS_send_general_cmd(p_super, stream);
}

CDS_ERR_CODE I2C_read_byte(ComponentDriverSuper* p_super, uint8_t stream, I2C_Config* p_i2c_config,
                           uint8_t register_address, uint8_t* data)
{
  return I2C_read_bytes_(p_super, stream, p_i2c_config, register_address, data, sizeof(*data));
}

CDS_ERR_CODE I2C_read_2bytes(ComponentDriverSuper* p_super, uint8_t stream, I2C_Config* p_i2c_config,
                             uint8_t register_address, uint16_t* data)
{
  return I2C_read_bytes_(p_super, stream, p_i2c_config, register_address, data, sizeof(*data));
}

static CDS_ERR_CODE I2C_read_bytes_(ComponentDriverSuper* p_super, uint8_t stream, I2C_Config* p_i2c_config,
                                    uint8_t register_address, void* data_v, uint8_t buffer_size)
{
  CDS_ERR_CODE ret = CDS_ERR_CODE_OK;
  const uint8_t* rx_data;
  CDS_StreamConfig* stream_config = &(p_super->stream_config[stream]);

  // read setting
  CDSSC_set_rx_frame_size(stream_config, buffer_size);
  I2C_set_rx_length(p_i2c_config, buffer_size);
  CDS_clear_rx_buffer(p_super);
  // send
  I2C_set_stop_flag(p_i2c_config, 0);
  CDSSC_set_tx_frame(stream_config, &register_address);
  CDSSC_set_tx_frame_size(stream_config, sizeof(register_address));
  ret = CDS_send_req_tlm_cmd(p_super, stream);
  if (ret != CDS_ERR_CODE_OK) return ret;
  // read
  I2C_set_stop_flag(p_i2c_config, 1);
  ret = CDS_receive(p_super);
  if (ret != CDS_ERR_CODE_OK) return ret;
  if (CDSSC_get_rec_status(stream_config)->status_code != CDS_STREAM_REC_STATUS_FIXED_FRAME)
  {
    return CDS_ERR_CODE_ERR;
  }

  rx_data = CDSSC_get_rx_frame(stream_config);
  ENDIAN_memcpy(data_v, rx_data, buffer_size);

  return ret;
}

#pragma section