#include <asf.h>
#include <string.h>
#include <stdio.h>
#include "atca_hal.h"
#include "hal_swi_bitbang.h"
#include "atca_device.h"
static ATCASWIMaster_t swi_hal_data[MAX_SWI_BUSES];
ATCA_STATUS hal_swi_discover_buses(int swi_buses[], int max_buses)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_swi_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_swi_init(void *hal, ATCAIfaceCfg *cfg)
{
if (cfg->atcaswi.bus >= MAX_SWI_BUSES)
{
return ATCA_COMM_FAIL;
}
ATCASWIMaster_t* data = &swi_hal_data[cfg->atcaswi.bus];
if (data->ref_ct <= 0)
{
data->pin_sda = swi_buses_default.pin_sda[cfg->atcaswi.bus];
swi_set_pin(data->pin_sda);
swi_enable();
data->bus_index = cfg->atcaswi.bus;
data->ref_ct = 1;
}
else
{
data->ref_ct++;
}
((ATCAHAL_t*)hal)->hal_data = data;
return ATCA_SUCCESS;
}
ATCA_STATUS hal_swi_post_init(ATCAIface iface)
{
return ATCA_SUCCESS;
}
ATCA_STATUS hal_swi_send(ATCAIface iface, uint8_t *txdata, int txlength)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int bus = cfg->atcaswi.bus;
txdata++;
swi_set_pin(swi_hal_data[bus].pin_sda);
swi_send_byte(SWI_FLAG_CMD);
swi_send_bytes(txlength, txdata);
return ATCA_SUCCESS;
}
ATCA_STATUS hal_swi_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
ATCA_STATUS status = !ATCA_SUCCESS;
int bus = cfg->atcaswi.bus;
int retries = cfg->rx_retries;
uint16_t rxdata_max_size = *rxlength;
*rxlength = 0;
if (rxdata_max_size < 1)
{
return ATCA_SMALL_BUFFER;
}
swi_set_pin(swi_hal_data[bus].pin_sda);
while (retries-- > 0 && status != ATCA_SUCCESS)
{
swi_send_byte(SWI_FLAG_TX);
status = swi_receive_bytes(rxdata_max_size, rxdata);
}
if (status != ATCA_SUCCESS)
{
return status;
}
*rxlength = rxdata[0];
return ATCA_SUCCESS;
}
ATCA_STATUS hal_swi_wake(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
ATCA_STATUS status = ATCA_WAKE_FAILED;
int bus = cfg->atcaswi.bus;
uint8_t data[4] = { 0x00, 0x00, 0x00, 0x00 };
uint16_t rxlength = sizeof(data);
swi_set_pin(swi_hal_data[bus].pin_sda);
swi_send_wake_token();
atca_delay_us(cfg->wake_delay);
status = hal_swi_receive(iface, data, &rxlength);
if (status != ATCA_SUCCESS)
{
return status;
}
return hal_check_wake(data, 4);
}
ATCA_STATUS hal_swi_idle(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int bus = cfg->atcaswi.bus;
swi_set_pin(swi_hal_data[bus].pin_sda);
swi_send_byte(SWI_FLAG_IDLE);
return ATCA_SUCCESS;
}
ATCA_STATUS hal_swi_sleep(ATCAIface iface)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int bus = cfg->atcaswi.bus;
swi_set_pin(swi_hal_data[bus].pin_sda);
swi_send_byte(SWI_FLAG_SLEEP);
return ATCA_SUCCESS;
}
ATCA_STATUS hal_swi_release(void *hal_data)
{
ATCASWIMaster_t *hal = (ATCASWIMaster_t*)hal_data;
if (hal && --(hal->ref_ct) <= 0)
{
swi_set_pin(swi_hal_data[hal->bus_index].pin_sda);
swi_disable();
hal->ref_ct = 0;
}
return ATCA_SUCCESS;
}