#include <asf.h>
#include <string.h>
#include <stdio.h>
#include "atca_hal.h"
#include "atca_device.h"
#include "atca_execution.h"
#include "hal_uc3_i2c_asf.h"
static ATCAI2CMaster_t i2c_hal_data[MAX_I2C_BUSES];
ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses)
{
return ATCA_UNIMPLEMENTED;
}
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)
{
twi_options_t opt;
ATCA_STATUS status = !ATCA_SUCCESS;
ATCAI2CMaster_t* data = &i2c_hal_data[cfg->atcai2c.bus];
if (data->ref_ct <= 0)
{
switch (cfg->atcai2c.bus)
{
case 2:
data->twi_master_instance = &AVR32_TWI;
static const gpio_map_t TWI_GPIO_MAP =
{
{ AVR32_TWI_SDA_0_0_PIN, AVR32_TWI_SDA_0_0_FUNCTION },
{ AVR32_TWI_SCL_0_0_PIN, AVR32_TWI_SCL_0_0_FUNCTION }
};
gpio_enable_module(TWI_GPIO_MAP, sizeof(TWI_GPIO_MAP) / sizeof(TWI_GPIO_MAP[0]));
opt.pba_hz = 48000000;
opt.speed = 100000;
opt.chip = 0;
twi_master_init(&AVR32_TWI, &opt);
break;
default:
return ATCA_COMM_FAIL;
}
data->bus_index = cfg->atcai2c.bus;
data->ref_ct = 1;
}
else
{
data->ref_ct++;
}
((ATCAHAL_t*)hal)->hal_data = data;
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)
{
twi_package_t packet;
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
txdata[0] = 0x03; txlength++;
packet.chip = cfg->atcai2c.slave_address >> 1;
packet.addr[0] = 0;
packet.addr[1] = 0;
packet.addr[2] = 0;
packet.addr_length = 0;
packet.buffer = (void*)txdata;
packet.length = (uint32_t)txlength;
if (twi_master_write(i2c_hal_data[cfg->atcai2c.bus].twi_master_instance, &packet) != TWI_SUCCESS)
{
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 = cfg->rx_retries;
uint32_t status = !ATCA_SUCCESS;
uint16_t rxdata_max_size = *rxlength;
twi_package_t packet = {
.chip = cfg->atcai2c.slave_address >> 1,
.addr[0] = { 0 },
.addr[1] = { 0 },
.addr[2] = { 0 },
.addr_length = 0,
.buffer = (void*)rxdata,
.length = (uint32_t)1
};
*rxlength = 0;
if (rxdata_max_size < 1)
{
return ATCA_SMALL_BUFFER;
}
while (retries-- > 0 && status != ATCA_SUCCESS)
{
if (twi_master_read(i2c_hal_data[cfg->atcai2c.bus].twi_master_instance, &packet) != TWI_SUCCESS)
{
status = ATCA_COMM_FAIL;
}
else
{
status = ATCA_SUCCESS;
}
}
if (status != ATCA_SUCCESS)
{
return status;
}
if (rxdata[0] < ATCA_RSP_SIZE_MIN)
{
return ATCA_INVALID_SIZE;
}
if (rxdata[0] > rxdata_max_size)
{
return ATCA_SMALL_BUFFER;
}
atca_delay_ms(1);
packet.length = rxdata[0] - 1;
packet.buffer = &rxdata[1];
if (twi_master_read(i2c_hal_data[cfg->atcai2c.bus].twi_master_instance, &packet) != TWI_SUCCESS)
{
status = ATCA_COMM_FAIL;
}
else
{
status = ATCA_SUCCESS;
}
if (status != ATCA_SUCCESS)
{
return status;
}
*rxlength = rxdata[0];
return ATCA_SUCCESS;
}
ATCA_STATUS change_i2c_speed(ATCAIface iface, uint32_t speed)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int retries = cfg->rx_retries;
uint32_t bdrt = cfg->atcai2c.baud;
int status = !TWI_SUCCESS;
uint8_t data[4];
twi_package_t packet;
packet.chip = 0x00;
packet.addr[0] = 0;
packet.addr[1] = 0;
packet.addr[2] = 0;
packet.addr_length = 0;
packet.buffer = (void*)&data[0];
packet.length = 1;
if (bdrt != 100000)
{
change_i2c_speed(iface, 100000);
}
twi_master_write(i2c_hal_data[cfg->atcai2c.bus].twi_master_instance, &packet);
atca_delay_ms(((uint32_t)cfg->wake_delay + (1000 - 1)) / 1000);
if (bdrt != 100000)
{
change_i2c_speed(iface, bdrt);
}
packet.chip = cfg->atcai2c.slave_address >> 1;
packet.buffer = (void*)data;
packet.length = (uint32_t)4;
while (retries-- > 0 && status != TWI_SUCCESS)
{
status = twi_master_read(i2c_hal_data[cfg->atcai2c.bus].twi_master_instance, &packet);
}
if (status != TWI_SUCCESS)
{
return ATCA_COMM_FAIL;
}
return hal_check_wake(data, 4);
}
ATCA_STATUS hal_i2c_idle(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
uint8_t data[4];
data[0] = 0x02; twi_package_t packet = {
.chip = cfg->atcai2c.slave_address >> 1,
.addr = { 0 },
.addr_length = 0,
.buffer = (void*)data,
.length = 1
};
if (twi_master_write(i2c_hal_data[cfg->atcai2c.bus].twi_master_instance, &packet) != TWI_SUCCESS)
{
return ATCA_COMM_FAIL;
}
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
uint8_t data[4];
data[0] = 0x01; twi_package_t packet = {
.chip = cfg->atcai2c.slave_address >> 1,
.addr = { 0 },
.addr_length = 0,
.buffer = (void*)data,
.length = 1
};
if (twi_master_write(i2c_hal_data[cfg->atcai2c.bus].twi_master_instance, &packet) != TWI_SUCCESS)
{
return ATCA_COMM_FAIL;
}
return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_release(void *hal_data)
{
ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data;
if (hal && --(hal->ref_ct) <= 0)
{
twi_master_disable(hal->twi_master_instance);
hal->ref_ct = 0;
}
return ATCA_SUCCESS;
}