#include <string.h>
#include <stdio.h>
#include "atca_config.h"
#include "atca_hal.h"
#include "atca_device.h"
#include "atca_execution.h"
#include "definitions.h"
ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses)
{
i2c_buses[0] = 0;
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg)
{
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_post_init(ATCAIface iface)
{
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength)
{
ATCAIfaceCfg* cfg = atgetifacecfg(iface);
atca_plib_api_t * plib;
if (!cfg)
{
return ATCA_BAD_PARAM;
}
plib = (atca_plib_api_t*)cfg->cfg_data;
if (!plib)
{
return ATCA_BAD_PARAM;
}
txdata[0] = 0x03; txlength++;
while (plib->is_busy() == true)
{
;
}
if (plib->write(cfg->atcai2c.slave_address >> 1, txdata, txlength) == true)
{
while (plib->is_busy() == true)
{
;
}
if (plib->error_get() != PLIB_I2C_ERROR_NONE)
{
return ATCA_COMM_FAIL;
}
}
else
{
return ATCA_COMM_FAIL;
}
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength)
{
ATCAIfaceCfg* cfg = atgetifacecfg(iface);
int retries;
uint16_t count;
uint16_t rxdata_max_size = *rxlength;
bool isSuccess = false;
atca_plib_api_t * plib;
if (!cfg)
{
return ATCA_BAD_PARAM;
}
plib = (atca_plib_api_t*)cfg->cfg_data;
if (!plib)
{
return ATCA_BAD_PARAM;
}
retries = cfg->rx_retries;
*rxlength = 0;
if (rxdata_max_size < 1)
{
return ATCA_SMALL_BUFFER;
}
while (plib->is_busy() == true)
{
;
}
while (retries-- > 0 && isSuccess == false)
{
if (plib->read(cfg->atcai2c.slave_address >> 1, rxdata, 1) == true)
{
while (plib->is_busy() == true)
{
;
}
if (plib->error_get() == PLIB_I2C_ERROR_NONE)
{
isSuccess = true;
}
}
}
if (isSuccess == false)
{
return ATCA_COMM_FAIL;
}
if (rxdata[0] < ATCA_RSP_SIZE_MIN)
{
return ATCA_INVALID_SIZE;
}
if (rxdata[0] > rxdata_max_size)
{
return ATCA_SMALL_BUFFER;
}
count = rxdata[0] - 1;
if (plib->read(cfg->atcai2c.slave_address >> 1, &rxdata[1], count) == true)
{
while (plib->is_busy() == true)
{
;
}
if (plib->error_get() != PLIB_I2C_ERROR_NONE)
{
return ATCA_COMM_FAIL;
}
}
else
{
return ATCA_COMM_FAIL;
}
*rxlength = rxdata[0];
return ATCA_SUCCESS;
}
void change_i2c_speed(ATCAIface iface, uint32_t speed)
{
ATCAIfaceCfg* cfg = atgetifacecfg(iface);
atca_plib_api_t * plib;
if (!cfg)
{
return;
}
plib = (atca_plib_api_t*)cfg->cfg_data;
if (!plib)
{
return;
}
PLIB_I2C_TRANSFER_SETUP setup;
setup.clkSpeed = speed;
while (plib->is_busy() == true)
{
;
}
(void)plib->transfer_setup(&setup, 0);
}
ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
ATCAIfaceCfg* cfg = atgetifacecfg(iface);
atca_plib_api_t * plib;
int retries;
uint32_t bdrt;
uint8_t data[4] = { 0 };
bool isSuccess = false;
if (!cfg)
{
return ATCA_BAD_PARAM;
}
plib = (atca_plib_api_t*)cfg->cfg_data;
if (!plib)
{
return ATCA_BAD_PARAM;
}
retries = cfg->rx_retries;
bdrt = cfg->atcai2c.baud;
if (bdrt != 100000) {
change_i2c_speed(iface, 100000);
}
while (plib->is_busy() == true)
{
;
}
(void)plib->write(0x00, (uint8_t*)&data[0], 1);
while (plib->is_busy() == true)
{
;
}
atca_delay_us(cfg->wake_delay);
while (retries-- > 0 && isSuccess == false)
{
if (plib->read(cfg->atcai2c.slave_address >> 1, (uint8_t*)&data[0], 4) == true)
{
while (plib->is_busy() == true)
{
;
}
if (plib->error_get() == PLIB_I2C_ERROR_NONE)
{
isSuccess = true;
}
}
}
if (isSuccess == true)
{
if (bdrt != 100000)
{
change_i2c_speed(iface, bdrt);
}
}
else
{
return ATCA_COMM_FAIL;
}
return hal_check_wake(data, 4);
}
ATCA_STATUS hal_i2c_idle(ATCAIface iface)
{
ATCAIfaceCfg* cfg = atgetifacecfg(iface);
atca_plib_api_t * plib;
uint8_t data[1];
if (!cfg)
{
return ATCA_BAD_PARAM;
}
plib = (atca_plib_api_t*)cfg->cfg_data;
if (!plib)
{
return ATCA_BAD_PARAM;
}
data[0] = 0x02;
while (plib->is_busy() == true)
{
;
}
if (plib->write(cfg->atcai2c.slave_address >> 1, (uint8_t*)&data[0], 1) == true)
{
while (plib->is_busy() == true)
{
;
}
if (plib->error_get() != PLIB_I2C_ERROR_NONE)
{
return ATCA_COMM_FAIL;
}
}
else
{
return ATCA_COMM_FAIL;
}
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
ATCAIfaceCfg* cfg = atgetifacecfg(iface);
atca_plib_api_t * plib;
uint8_t data[4];
if (!cfg)
{
return ATCA_BAD_PARAM;
}
plib = (atca_plib_api_t*)cfg->cfg_data;
if (!plib)
{
return ATCA_BAD_PARAM;
}
data[0] = 0x01;
while (plib->is_busy() == true)
{
;
}
if (plib->write(cfg->atcai2c.slave_address >> 1, (uint8_t*)&data[0], 1) == true)
{
while (plib->is_busy() == true)
{
;
}
if (plib->error_get() != PLIB_I2C_ERROR_NONE)
{
return ATCA_COMM_FAIL;
}
}
else
{
return ATCA_COMM_FAIL;
}
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_release(void *hal_data)
{
return ATCA_SUCCESS;
}