#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "atca_hal.h"
#include "kit_phy.h"
#include "hal_linux_kit_cdc.h"
#include "kit_protocol.h"
#ifndef __cplusplus
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
atcacdc_t _gCdc;
char *dev = "/dev/ttyACM0"; int speed = B115200;
ATCA_STATUS hal_cdc_discover_buses(int cdc_buses[], int max_buses)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_cdc_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_kit_cdc_init(void* hal, ATCAIfaceCfg* cfg)
{
ATCAHAL_t *phal = NULL;
struct termios serialTermios;
uint32_t i = 0;
uint32_t index = 0;
int fd;
if ((hal == NULL) || (cfg == NULL))
{
return ATCA_BAD_PARAM;
}
phal = (ATCAHAL_t*)hal;
memset(&_gCdc, 0, sizeof(_gCdc));
for (i = 0; i < CDC_DEVICES_MAX; i++)
{
_gCdc.kits[i].read_handle = INVALID_HANDLE_VALUE;
_gCdc.kits[i].write_handle = INVALID_HANDLE_VALUE;
}
_gCdc.num_kits_found = 0;
if ( (fd = open(dev, O_RDWR | O_NOCTTY)) < 0)
{
printf("Failed to open %s ret:%02X\n", dev, fd);
return ATCA_COMM_FAIL;
}
index++;
if (index > 0)
{
_gCdc.num_kits_found = 1;
phal->hal_data = &_gCdc;
}
tcgetattr(fd, &serialTermios);
cfsetispeed(&serialTermios, speed);
cfsetospeed(&serialTermios, speed);
cfmakeraw(&serialTermios);
serialTermios.c_cflag |= CS8 | CLOCAL | CREAD;
serialTermios.c_iflag = 0;
serialTermios.c_oflag = 0;
serialTermios.c_lflag = 0;
tcsetattr(fd, TCSANOW, &serialTermios);
_gCdc.kits[0].read_handle = fd;
_gCdc.kits[0].write_handle = fd;
return ATCA_SUCCESS;
}
ATCA_STATUS hal_kit_cdc_post_init(ATCAIface iface)
{
ATCA_STATUS status = ATCA_SUCCESS;
atcacdc_t* phaldat = atgetifacehaldat(iface);
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int i = 0;
for (i = 0; i < phaldat->num_kits_found; i++)
{
cfg->atcauart.port = i;
status = kit_init(iface);
if (status != ATCA_SUCCESS)
{
return status;
}
}
return status;
}
ATCA_STATUS kit_phy_send(ATCAIface iface, const char* txdata, int txlength)
{
ATCA_STATUS status = ATCA_SUCCESS;
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int cdcid = cfg->atcauart.port;
atcacdc_t* pCdc = (atcacdc_t*)atgetifacehaldat(iface);
size_t bytesWritten = 0;
#ifdef KIT_DEBUG
printf("--> %s", txdata);
#endif
if ((txdata == NULL) || (pCdc == NULL))
{
return ATCA_BAD_PARAM;
}
if (pCdc->kits[cdcid].write_handle == INVALID_HANDLE_VALUE)
{
return ATCA_COMM_FAIL;
}
bytesWritten = write(pCdc->kits[cdcid].write_handle, txdata, txlength);
return status;
}
ATCA_STATUS kit_phy_receive(ATCAIface iface, char* rxdata, int* rxsize)
{
ATCA_STATUS status = ATCA_SUCCESS;
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int cdcid = cfg->atcauart.port;
atcacdc_t* pCdc = (atcacdc_t*)atgetifacehaldat(iface);
uint8_t buffer[CDC_BUFFER_MAX] = { 0 };
bool continue_read = true;
int bytes_read = 0;
uint16_t total_bytes = 0;
char* location = NULL;
int bytes_remain = 0;
int bytes_to_cpy = 0;
do
{
if ((rxdata == NULL) || (rxsize == NULL) || (pCdc == NULL))
{
status = ATCA_BAD_PARAM;
break;
}
if (pCdc->kits[cdcid].read_handle == INVALID_HANDLE_VALUE)
{
status = ATCA_COMM_FAIL;
break;
}
while (continue_read == true)
{
bytes_read = read(pCdc->kits[cdcid].read_handle, buffer, CDC_BUFFER_MAX);
location = strchr((char*)&buffer[0], '\n');
if (location == NULL)
{
bytes_to_cpy = bytes_read;
}
else
{
bytes_to_cpy = (uint8_t)(location - (char*)buffer) + 1;
continue_read = false;
}
memcpy(&rxdata[total_bytes], &buffer[0], bytes_to_cpy);
total_bytes += bytes_to_cpy;
}
}
while (0);
*rxsize = total_bytes;
#ifdef KIT_DEBUG
printf("<-- %s", rxdata);
#endif
return status;
}
ATCA_STATUS hal_kit_phy_num_found(int8_t* num_found)
{
*num_found = _gCdc.num_kits_found;
return ATCA_SUCCESS;
}
ATCA_STATUS hal_kit_cdc_send(ATCAIface iface, uint8_t* txdata, int txlength)
{
return kit_send(iface, txdata, txlength);
}
ATCA_STATUS hal_kit_cdc_receive(ATCAIface iface, uint8_t* rxdata, uint16_t* rxsize)
{
return kit_receive(iface, rxdata, rxsize);
}
ATCA_STATUS hal_kit_cdc_wake(ATCAIface iface)
{
return kit_wake(iface);
}
ATCA_STATUS hal_kit_cdc_idle(ATCAIface iface)
{
return kit_idle(iface);
}
ATCA_STATUS hal_kit_cdc_sleep(ATCAIface iface)
{
return kit_sleep(iface);
}
ATCA_STATUS hal_kit_cdc_release(void* hal_data)
{
int i = 0;
atcacdc_t* phaldat = (atcacdc_t*)hal_data;
if ((hal_data == NULL))
{
return ATCA_BAD_PARAM;
}
for (i = 0; i < phaldat->num_kits_found; i++)
{
if (phaldat->kits[i].read_handle != INVALID_HANDLE_VALUE)
{
close(phaldat->kits[i].read_handle);
phaldat->kits[i].read_handle = INVALID_HANDLE_VALUE;
}
if (phaldat->kits[i].write_handle != INVALID_HANDLE_VALUE)
{
close(phaldat->kits[i].write_handle);
phaldat->kits[i].write_handle = INVALID_HANDLE_VALUE;
}
}
return ATCA_SUCCESS;
}
ATCA_STATUS hal_kit_cdc_discover_buses(int cdc_buses[], int max_buses)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_kit_cdc_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found)
{
*found = 0;
return ATCA_UNIMPLEMENTED;
}