#include <stdlib.h>
#include <stdio.h>
#include <peripheral_clk_config.h>
#include "swi_uart_start.h"
#include "basic/atca_helpers.h"
#define USART_BAUD_RATE(baud, sercom_freq) (65536 - ((65536 * 16.0F * baud) / sercom_freq))
ATCA_STATUS swi_uart_init(ATCASWIMaster_t *instance)
{
ATCA_STATUS status = ATCA_SUCCESS;
instance->USART_SWI = USART_1;
instance->sercom_core_freq = SWI_USART_SERCOM_CORE_FREQ;
status |= usart_sync_set_mode(&(instance->USART_SWI), USART_MODE_ASYNCHRONOUS);
status |= usart_sync_set_character_size(&(instance->USART_SWI), USART_CHARACTER_SIZE_7BITS);
status |= usart_sync_set_parity(&(instance->USART_SWI), USART_PARITY_NONE);
status |= usart_sync_set_stopbits(&(instance->USART_SWI), USART_STOP_BITS_ONE);
status |= usart_sync_set_baud_rate(&(instance->USART_SWI), USART_BAUD_RATE(230400, instance->sercom_core_freq));
status |= usart_sync_enable(&(instance->USART_SWI));
return status;
}
ATCA_STATUS swi_uart_deinit(ATCASWIMaster_t *instance)
{
ATCA_STATUS status = ATCA_SUCCESS;
usart_sync_disable(&(instance->USART_SWI));
return status;
}
void swi_uart_setbaud(ATCASWIMaster_t *instance, uint32_t baudrate)
{
usart_sync_set_baud_rate(&(instance->USART_SWI), USART_BAUD_RATE(baudrate, instance->sercom_core_freq));
}
void swi_uart_mode(ATCASWIMaster_t *instance, uint8_t mode)
{
usart_sync_disable(&(instance->USART_SWI));
if (mode == TRANSMIT_MODE)
{
usart_sync_set_baud_rate(&(instance->USART_SWI), USART_BAUD_RATE(230400, instance->sercom_core_freq));
hri_sercomusart_clear_CTRLB_RXEN_bit(instance->USART_SWI.device.hw);
hri_sercomusart_set_CTRLB_TXEN_bit(instance->USART_SWI.device.hw);
}
else if (mode == RECEIVE_MODE)
{
usart_sync_set_baud_rate(&(instance->USART_SWI), USART_BAUD_RATE(170000, instance->sercom_core_freq));
hri_sercomusart_clear_CTRLB_TXEN_bit(instance->USART_SWI.device.hw);
hri_sercomusart_set_CTRLB_RXEN_bit(instance->USART_SWI.device.hw);
}
usart_sync_enable(&(instance->USART_SWI));
instance->bus_index &= 0x07;
}
void swi_uart_discover_buses(int swi_uart_buses[], int max_buses)
{
swi_uart_buses[0] = 4; }
ATCA_STATUS swi_uart_send_byte(ATCASWIMaster_t *instance, uint8_t data)
{
uint8_t retries = 2;
int32_t byte_sent = 0;
#ifdef DEBUG_PIN
gpio_toggle_pin_level(PA20);
#endif
while ((retries > 0) && (byte_sent < 1))
{
byte_sent = io_write(&(instance->USART_SWI.io), &data, 1);
retries--;
}
#ifdef DEBUG_PIN
gpio_toggle_pin_level(PA20);
#endif
if (byte_sent <= 0)
{
return ATCA_TIMEOUT;
}
else
{
while (!_usart_sync_is_transmit_done(&instance->USART_SWI.device))
{
;
}
return ATCA_SUCCESS;
}
}
ATCA_STATUS swi_uart_receive_byte(ATCASWIMaster_t *instance, uint8_t *data)
{
int32_t byte_sent = 0;
uint8_t retries = 3;
#ifdef DEBUG_PIN
gpio_toggle_pin_level(PA21);
#endif
while ((retries-- > 0) && (byte_sent < 1))
{
delay_us(30);
if (usart_sync_is_rx_not_empty(&instance->USART_SWI))
{
byte_sent = io_read(&instance->USART_SWI.io, data, 1);
}
}
#ifdef DEBUG_PIN
gpio_toggle_pin_level(PA21);
#endif
if (byte_sent <= 0)
{
return ATCA_TIMEOUT;
}
else
{
return ATCA_SUCCESS;
}
}