File ns_i2c.c
File List > neuralSPOT > neuralspot > ns-i2c > src > ns_i2c.c
Go to the documentation of this file
#include "ns_i2c.h"
#include "am_bsp.h"
#include "am_mcu_apollo.h"
#include "am_util.h"
#include "ns_core.h"
const ns_core_api_t ns_i2c_V0_0_1 = {.apiId = NS_I2C_API_ID, .version = NS_I2C_V0_0_1};
const ns_core_api_t ns_i2c_V1_0_0 = {.apiId = NS_I2C_API_ID, .version = NS_I2C_V1_0_0};
const ns_core_api_t ns_i2c_oldest_supported_version = {
.apiId = NS_I2C_API_ID, .version = NS_I2C_V0_0_1};
const ns_core_api_t ns_i2c_current_version = {.apiId = NS_I2C_API_ID, .version = NS_I2C_V1_0_0};
uint32_t ns_i2c_interface_init(ns_i2c_config_t *cfg, uint32_t speed) {
#ifndef NS_DISABLE_API_VALIDATION
if (cfg == NULL) {
return NS_STATUS_INVALID_HANDLE;
}
if (ns_core_check_api(cfg->api, &ns_i2c_oldest_supported_version, &ns_i2c_current_version)) {
return NS_STATUS_INVALID_VERSION;
}
#endif
// Initialize local state
am_hal_pwrctrl_periph_enable((am_hal_pwrctrl_periph_e)(AM_HAL_PWRCTRL_PERIPH_IOM0 + cfg->iom));
cfg->sIomCfg.eInterfaceMode = AM_HAL_IOM_I2C_MODE;
cfg->sIomCfg.pNBTxnBuf = NULL;
cfg->sIomCfg.ui32NBTxnBufLength = 0;
cfg->sIomCfg.ui32ClockFreq = speed;
if (am_hal_iom_initialize(cfg->iom, &(cfg->iomHandle)) ||
am_hal_iom_power_ctrl(cfg->iomHandle, AM_HAL_SYSCTRL_WAKE, false) ||
am_hal_iom_configure(cfg->iomHandle, &(cfg->sIomCfg)) ||
am_hal_iom_enable(cfg->iomHandle)) {
return NS_I2C_STATUS_ERROR;
}
// Configure the IOM pins.
am_bsp_iom_pins_enable(cfg->iom, AM_HAL_IOM_I2C_MODE);
return NS_I2C_STATUS_SUCCESS;
}
uint32_t ns_i2c_read(ns_i2c_config_t *cfg, const void *buf, uint32_t size, uint16_t addr) {
am_hal_iom_transfer_t Transaction;
Transaction.ui8Priority = 1;
Transaction.ui32InstrLen = 0;
#if defined(AM_PART_APOLLO4B) || defined(AM_PART_APOLLO4P) || defined(AM_PART_APOLLO4L)
Transaction.ui64Instr = 0;
#else
Transaction.ui32Instr = 0;
#endif
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32NumBytes = size;
Transaction.pui32RxBuffer = (uint32_t *)buf;
Transaction.bContinue = false;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
Transaction.uPeerInfo.ui32I2CDevAddr = addr;
if (am_hal_iom_blocking_transfer(cfg->iomHandle, &Transaction)) {
return NS_I2C_STATUS_ERROR;
}
return NS_I2C_STATUS_SUCCESS;
}
uint32_t ns_i2c_write(ns_i2c_config_t *cfg, const void *buf, uint32_t size, uint16_t addr) {
am_hal_iom_transfer_t Transaction;
Transaction.ui8Priority = 1;
Transaction.ui32InstrLen = 0;
#if defined(AM_PART_APOLLO4B) || defined(AM_PART_APOLLO4P) || defined(AM_PART_APOLLO4L)
Transaction.ui64Instr = 0;
#else
Transaction.ui32Instr = 0;
#endif
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32NumBytes = size;
Transaction.pui32TxBuffer = (uint32_t *)buf;
Transaction.bContinue = false;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
Transaction.uPeerInfo.ui32I2CDevAddr = addr;
if (am_hal_iom_blocking_transfer(cfg->iomHandle, &Transaction)) {
return NS_I2C_STATUS_ERROR;
}
return NS_I2C_STATUS_SUCCESS;
}
uint32_t ns_i2c_write_read(
ns_i2c_config_t *cfg, uint16_t addr, const void *writeBuf, size_t numWrite, void *readBuf,
size_t numRead) {
ns_i2c_write(cfg, writeBuf, numWrite, addr);
return ns_i2c_read(cfg, readBuf, numRead, addr);
}
uint32_t ns_i2c_transfer(ns_i2c_config_t *cfg, ns_i2c_msg_t *msgs, size_t numMsgs) {
ns_i2c_msg_t *msg;
uint32_t msg_len = 0;
for (size_t i = 0; i < numMsgs; i++) {
msg = &msgs[i];
if (msg->flags == NS_I2C_XFER_RD) {
ns_i2c_read(cfg, msg->buf, msg->len, msg->addr);
msg_len += msg->len;
} else if (msg->flags == NS_I2C_XFER_WR) {
ns_i2c_write(cfg, msg->buf, msg->len, msg->addr);
msg_len += (msg->len - 1);
}
}
return msg_len;
}