/** \brief method to change the bus speed of I2C
 * \param[in] interface on which to change bus speed
 * \param[in] baud rate (typically 100000 or 400000)
 */
void change_i2c_speed( ATCAIface iface, uint32_t speed )
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	
	switch(bus)
	{
		case 0:
			//pmc_enable_periph_clk(ID_TWI0);
			//flexcom_enable(FLEXCOM0);
			//flexcom_set_opmode(FLEXCOM0, FLEXCOM_TWI);
			flexcom_enable(FLEX_Channel0);
			flexcom_set_opmode(FLEX_Channel0, FLEXCOM_TWI);
			
			opt_twi_master.master_clk = sysclk_get_cpu_hz();
			opt_twi_master.speed      = speed;
			opt_twi_master.smbus      = 0;
			//twi_master_init(TWI0, &opt_twi_master);
			twi_master_init(TWI_Channel0, &opt_twi_master);
			
			break;
		case 1:
			//pmc_enable_periph_clk(ID_TWI1);
			flexcom_enable(FLEX_Channel1);
			flexcom_set_opmode(FLEX_Channel1, FLEXCOM_TWI);
			
			opt_twi_master.master_clk = sysclk_get_cpu_hz();
			opt_twi_master.speed      = speed;
			opt_twi_master.smbus      = 0;
			twi_master_init(TWI_Channel1, &opt_twi_master);
			break;
	}
}
Example #2
0
ATCA_STATUS hal_swi_wake(ATCAIface iface)
{
#ifdef DEBUG_HAL
	printf("hal_swi_wake()\r\n");
#endif
	ATCA_STATUS status = ATCA_COMM_FAIL;
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcaswi.bus;
	int retries = cfg->rx_retries;
	uint16_t datalength = 4;
	uint8_t data[4] = { 0x00, 0x00, 0x00, 0x00 }, expected[4] = { 0x04, 0x11, 0x33, 0x43 };

	while ((status != ATCA_SUCCESS) && (retries >= 0x00)) {
		retries--;
		// Change baudrate to 115200 to get low signal more than 60us
		swi_uart_setbaud(swi_hal_data[bus], 115200);
		// Send byte 0x00
		status = swi_uart_send_byte(swi_hal_data[bus], SWI_WAKE_TOKEN);
		// Change baudrate back to 230400
		swi_uart_setbaud(swi_hal_data[bus], 230400);
	}

	if (!status) {
		atca_delay_us(cfg->wake_delay);  // wait tWHI + tWLO which is configured based on device type and configuration structure
		status = hal_swi_receive(iface, data, &datalength);
	}

	if ((retries == 0x00) && (status != ATCA_SUCCESS) )
		return ATCA_TIMEOUT;

	if ( memcmp( data, expected, 4 ) == 0 )
		return ATCA_SUCCESS;

	return ATCA_COMM_FAIL;
}
/**
 * \brief wake up CryptoAuth device using I2C bus
 *
 * \param[in] iface  interface to logical device to wakeup
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
    ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint32_t bdrt = cfg->atcai2c.baud;
    
    uint8_t data[4], expected[4] = { 0x04, 0x11, 0x33, 0x43 };
    
    if ( bdrt != 100000 )   // if not already at 100KHz, change it
        change_i2c_speed(iface, 100000);
    
    // Send 0x00 as wake pulse
    i2c_write(i2c_hal_data[bus]->id, 0x00, NULL, NULL);
    
    atca_delay_ms(3);   // wait tWHI + tWLO which is configured based on device type and configuration structure
    //atca_delay_us(cfg->wake_delay);
    
	// if necessary, revert baud rate to what came in.
	if ( bdrt != 100000 )
        change_i2c_speed(iface, cfg->atcai2c.baud);
    
    i2c_read(i2c_hal_data[bus]->id, cfg->atcai2c.slave_address, data, 4);
    
    if (memcmp(data, expected, 4) == 0)
        return ATCA_SUCCESS;
    
    return ATCA_COMM_FAIL;
}
/** \brief HAL implementation of kit protocol send over USB CDC
 * \param[in] ATCAIface instance
 * \param[out] rxdata pointer to space to receive the data
 * \param[inout] ptr to expected number of receive bytes to request
 * \return ATCA_STATUS
 */
ATCA_STATUS kit_phy_receive(ATCAIface iface, uint8_t* 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 {
		// Verify the input variables
		if ((rxdata == NULL) || (rxsize == NULL) || (pCdc == NULL)) {
			status = ATCA_BAD_PARAM;
			break;
		}
		// Verify the write handle
		if (pCdc->kits[cdcid].read_handle == INVALID_HANDLE_VALUE) {
			status = ATCA_COMM_FAIL;
			break;
		}
		// Read all of the bytes
		while (continue_read == true) {
			bytes_read = read(pCdc->kits[cdcid].read_handle, buffer, CDC_BUFFER_MAX);

			// Find the location of the '\n' character in read buffer
			// todo: generalize this read...  it only applies if there is an ascii protocol with an <eom> of \n and if the <eom> exists
			location = strchr((char*)&buffer[0], '\n');
			if (location == NULL)
				// Copy all of the bytes
				bytes_to_cpy = bytes_read;
			else{
				// Copy only the bytes remaining in the read buffer to the <eom>
				bytes_to_cpy = (uint8_t)(location - (char*)buffer) + 1;
				// The response has been received, stop receiving more data
				continue_read = false;
			}
			// Protect rxdata from overwriting, this will have the result of truncating the returned bytes
			// Remaining space in rxdata
			bytes_remain = (*rxsize - total_bytes);
			// Use the minimum between number of bytes read and remaining space
			bytes_to_cpy = min(bytes_remain, bytes_to_cpy);

			// Copy the received data
			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;
}
/**
 * \brief HAL implementation of I2C receive function for ASF I2C
 *
 * \param[in] iface     instance
 * \param[in] rxdata    pointer to space to receive the data
 * \param[in] rxlength  ptr to expected number of receive bytes to request
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength)
{
    ATCAIfaceCfg *cfg = atgetifacecfg(iface);
    int bus = cfg->atcai2c.bus;
    
    i2c_read(i2c_hal_data[bus]->id, cfg->atcai2c.slave_address, rxdata, *rxlength);
    
    return ATCA_SUCCESS;
}
/** \brief HAL implementation of I2C receive function for ASF I2C
 * \param[in] ATCAIface instance
 * \param[in] rxdata pointer to space to receive the data
 * \param[in] ptr to expected number of receive bytes to request
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_receive( ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength)
{
#ifdef DEBUG_HAL
	printf("hal_i2c_receive()\r\n");
#endif
	
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int retries = cfg->rx_retries;
	int bus = cfg->atcai2c.bus;
	uint32_t status = !TWI_SUCCESS;
	
	//twi_package_t packet = {
	twi_packet_t packet = {	
		.chip        = cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length = 0,
		.buffer      = (void *)rxdata,
		.length      = (uint32_t)*rxlength
	};
	
	switch(bus)
	{
		case 0:
			while(retries-- > 0 && status != TWI_SUCCESS)
			{
				//status = twi_master_read(TWI0, &packet);
				status = twi_master_read(TWI_Channel0, &packet);
			}
			break;
		case 1:
			while(retries-- > 0 && status != TWI_SUCCESS)
			{
				status = twi_master_read(TWI_Channel1, &packet);
			}
			break;
	}
	if (status != TWI_SUCCESS)
	{
		return ATCA_COMM_FAIL;
	}
	
#ifdef DEBUG_HAL
	printf("\r\nResponse Packet (size:0x%.4x)\r\n", rxlength);
	printf("Count  : %.2x\r\n", rxdata[0]);
	if (rxdata[0] > 3)
	{
		printf("Data   : "); print_array(&rxdata[1], rxdata[0]-3);
		printf("CRC    : "); print_array(&rxdata[rxdata[0]-2], 2);
	}
	printf("\r\n");
#endif
	
	return ATCA_SUCCESS;
}
/**
 * \brief sleep CryptoAuth device using I2C bus
 *
 * \param[in] iface  interface to logical device to sleep
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
    ATCAIfaceCfg *cfg = atgetifacecfg(iface);
    int bus = cfg->atcai2c.bus;
    uint8_t data[4];
    
    data[0] = 0x01; // idle word address value
    
    i2c_write(i2c_hal_data[bus]->id, cfg->atcai2c.slave_address, data, 1);
        
    return ATCA_SUCCESS;
}
/**
 * \brief HAL implementation of I2C send over ASF
 *
 * \param[in] iface     instance
 * \param[in] txdata    pointer to space to bytes to send
 * \param[in] txlength  number of bytes to send
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength)
{
    ATCAIfaceCfg *cfg = atgetifacecfg(iface);
    int bus = cfg->atcai2c.bus;
    
    txdata[0] = 0x03;   // insert the Word Address Value, Command token
    txlength++;         // account for word address value byte.
    
    i2c_write(i2c_hal_data[bus]->id, cfg->atcai2c.slave_address, txdata, txlength);
    
    return ATCA_SUCCESS;
}
/**
 * \brief method to change the bus speed of I2C
 *
 * \param[in] iface  interface on which to change bus speed
 * \param[in] speed  baud rate (typically 100000 or 400000)
 */
void change_i2c_speed(ATCAIface iface, uint32_t speed)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
    
    // Disable the I2C bus
    I2CEnable(i2c_hal_data[bus]->id, FALSE);
    
    // Set the I2C baudrate
    I2CSetFrequency(i2c_hal_data[bus]->id, GetPeripheralClock(), speed);
    
    // Enable the I2C bus
    I2CEnable(i2c_hal_data[bus]->id, TRUE);
}
Example #10
0
/**
 * \brief method to change the bus speed of I2C
 *
 * \param[in] iface  interface on which to change bus speed
 * \param[in] speed  baud rate (typically 100000 or 400000)
 */
void change_i2c_speed(ATCAIface iface, uint32_t speed)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);

	// set to default i2c bus
	if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1)
		cfg->atcai2c.bus = 0;
	int bus = cfg->atcai2c.bus;

	pmc_enable_periph_clk(i2c_hal_data[bus]->twi_id);

	opt_twi_master.master_clk = sysclk_get_cpu_hz();
	opt_twi_master.speed      = speed;
	opt_twi_master.smbus      = 0;

	twi_master_init(i2c_hal_data[bus]->twi_master_instance, &opt_twi_master);
}
Example #11
0
/**
 * \brief HAL implementation of I2C send over ASF
 *
 * \param[in] iface     instance
 * \param[in] txdata    pointer to space to bytes to send
 * \param[in] txlength  number of bytes to send
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength)
{
#ifdef DEBUG_HAL
	printf("hal_i2c_send()\r\n");

	printf("\r\nCommand Packet (size:0x%.8x)\r\n", (uint32_t)txlength);
	printf("Count  : %.2x\r\n", txdata[1]);
	printf("Opcode : %.2x\r\n", txdata[2]);
	printf("Param1 : %.2x\r\n", txdata[3]);
	printf("Param2 : "); print_array(&txdata[4], 2);
	if (txdata[1] > 7) {
		printf("Data   : "); print_array(&txdata[6], txdata[1] - 7);
	}
	printf("CRC    : "); print_array(&txdata[txdata[1] - 1], 2);
	printf("\r\n");
#endif

	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	// set to default i2c bus
	if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1)
		cfg->atcai2c.bus = 0;
	int bus = cfg->atcai2c.bus;

	txdata[0] = 0x03;   // insert the Word Address Value, Command token
	txlength++;         // account for word address value byte.

	twi_package_t packet = {
		.chip			= cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length	= 0,
		.buffer			= (void*)txdata,
		.length			= (uint32_t)txlength //(uint32_t)txdata[1]
	};

	// for this implementation of I2C with CryptoAuth chips, txdata is assumed to have ATCAPacket format

	// other device types that don't require i/o tokens on the front end of a command need a different hal_i2c_send and wire it up instead of this one
	// this covers devices such as ATSHA204A and ATECCx08A that require a word address value pre-pended to the packet

	if (twi_master_write(i2c_hal_data[bus]->twi_master_instance, &packet) != TWI_SUCCESS)
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}
Example #12
0
ATCA_STATUS hal_swi_send_flag(ATCAIface iface, uint8_t data)
{
	ATCA_STATUS status = ATCA_SUCCESS;
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcaswi.bus;
	uint8_t bit_mask, bit_data;

	for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
		// Send one byte that represent one bit, 0x7F for one or 0x7D for zero
		// The LSB (least significant bit) is sent first.
		bit_data = (bit_mask & data) ? 0x7F : 0x7D;
		status |= swi_uart_send_byte(swi_hal_data[bus], bit_data);

	}
	if (status != ATCA_SUCCESS)
		return ATCA_COMM_FAIL;
	else
		return ATCA_SUCCESS;
}
Example #13
0
ATCA_STATUS hal_swi_send(ATCAIface iface, uint8_t *txdata, int txlength)
{

#ifdef DEBUG_HAL
	printf("hal_swi_send()\r\n");

	printf("\r\nCommand Packet (size:0x%.4x)\r\n", txlength);
	printf("Count  : %.2x\r\n", txdata[1]);
	printf("Opcode : %.2x\r\n", txdata[2]);
	printf("Param1 : %.2x\r\n", txdata[3]);
	printf("Param2 : "); print_array(&txdata[4], 2);
	if (txdata[1] > 7) {
		printf("Data   : "); print_array(&txdata[6], txdata[1] - 7);
	}
	printf("CRC    : "); print_array(&txdata[txdata[1] - 1], 2);
	printf("\r\n");
#endif
	ATCA_STATUS status = ATCA_SUCCESS;
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcaswi.bus;
	uint8_t i, bit_mask, bit_data;

	//Skip the Word Address data as SWI doesn't use it
	txdata++;

	status = hal_swi_send_flag(iface, SWI_FLAG_CMD);
	if (status == ATCA_SUCCESS) {
		for (i = 0; i < txlength; i++) {
			for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
				// Send one byte that represent one bit, 0x7F for one or 0x7D for zero
				// The LSB (least significant bit) is sent first.
				bit_data = (bit_mask & *txdata) ? 0x7F : 0x7D;
				status = swi_uart_send_byte(swi_hal_data[bus], bit_data);
				if (status != ATCA_SUCCESS)
					return ATCA_COMM_FAIL;
			}
			txdata++;
		}
		return ATCA_SUCCESS;
	}
	return ATCA_COMM_FAIL;
}
/** \brief HAL implementation of Kit USB CDC post init
 *  \param[in] ATCAIface instance
 *  \return ATCA_STATUS
 */
ATCA_STATUS hal_kit_cdc_post_init(ATCAIface iface)
{
	ATCA_STATUS status = ATCA_SUCCESS;
	atcacdc_t* phaldat = atgetifacehaldat(iface);
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int cdcid = cfg->atcauart.port;
	int i = 0;

	// Init all kit USB devices
	for (i = 0; i < phaldat->num_kits_found; i++) {
		// Set the port
		cfg->atcauart.port = i;
		// Perform the kit protocol init
		status = kit_init(iface);
		if (status != ATCA_SUCCESS)
			return status;
	}

	return status;
}
Example #15
0
/**
 * \brief HAL implementation of I2C receive function for ASF I2C
 *
 * \param[in] iface     instance
 * \param[in] rxdata    pointer to space to receive the data
 * \param[in] rxlength  ptr to expected number of receive bytes to request
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength)
{
#ifdef DEBUG_HAL
	printf("hal_i2c_receive()\r\n");
#endif

	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	// set to default i2c bus
	if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1)
		cfg->atcai2c.bus = 0;
	int bus = cfg->atcai2c.bus;
	int retries = cfg->rx_retries;
	uint32_t status = !TWI_SUCCESS;

	twi_package_t packet = {
		.chip			= cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length	= 0,
		.buffer			= (void*)rxdata,
		.length			= (uint32_t)*rxlength
	};

	while (retries-- > 0 && status != TWI_SUCCESS)
		status = twi_master_read(i2c_hal_data[bus]->twi_master_instance, &packet);
	if (status != TWI_SUCCESS)
		return ATCA_COMM_FAIL;

#ifdef DEBUG_HAL
	printf("\r\nResponse Packet (size:0x%.4x)\r\n", rxlength);
	printf("Count  : %.2x\r\n", rxdata[0]);
	if (rxdata[0] > 3) {
		printf("Data   : "); print_array(&rxdata[1], rxdata[0] - 3);
		printf("CRC    : "); print_array(&rxdata[rxdata[0] - 2], 2);
	}
	printf("\r\n");
#endif

	return ATCA_SUCCESS;
}
/** \brief HAL implementation of send over USB CDC
 *  \param[in] ATCAIface instance
 *  \param[in] txdata pointer to bytes to send
 *  \param[in] txlength number of bytes to send
 *  \return ATCA_STATUS
 */
ATCA_STATUS kit_phy_send(ATCAIface iface, uint8_t* 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
	// Verify the input parameters
	if ((txdata == NULL) || (pCdc == NULL))
		return ATCA_BAD_PARAM;

	// Verify the write handle
	if (pCdc->kits[cdcid].write_handle == INVALID_HANDLE_VALUE)
		return ATCA_COMM_FAIL;

	// Write the bytes to the specified com port
	bytesWritten = write(pCdc->kits[cdcid].write_handle, txdata, txlength);

	return status;
}
Example #17
0
/** \brief wake up CryptoAuth device using I2C bus
 * \param[in] interface to logical device to wakeup
 */
ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	int retries = cfg->rx_retries;
	uint32_t bdrt = cfg->atcai2c.baud;
	uint8_t data[4], expected[4] = { 0x04,0x11,0x33,0x43 };
	int status = !TWI_SUCCESS;
	
	// if not already at 100KHz, change it
	if (bdrt != 100000)
	{
		change_i2c_speed(iface, 100000);
	}
	
	// Send 0x00 as wake pulse
	switch(bus)
	{
		//case 0: twi_write_byte(TWI0, 0x00); break;
		case 0: twi_write_byte(TWI_Channel0,0);break;
		case 1: twi_write_byte(TWI_Channel1,0); break;
	}
	
	atca_delay_us(cfg->wake_delay);	// wait tWHI + tWLO which is configured based on device type and configuration structure
	
	//twi_package_t packet = {
	twi_packet_t packet = {
		.chip        = cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length = 0,
		.buffer      = (void *)data,
		.length      = 4
	};
	
	// if necessary, revert baud rate to what came in.
	if (bdrt != 100000)
	{
		change_i2c_speed(iface, bdrt);
	}
	
	switch(bus)
	{
		case 0:
			//if (twi_master_read(TWI0, &packet) != TWI_SUCCESS)
			while (retries-- > 0 && status != TWI_SUCCESS)
				status = twi_master_read(TWI_Channel0, &packet);
			/*if (twi_master_read(TWI_Channel0, &packet) != TWI_SUCCESS)
			{
				return ATCA_COMM_FAIL;
			}*/
			break;
		case 1:
			/*
			if (twi_master_read(TWI_Channel1, &packet) != TWI_SUCCESS)
			{
				return ATCA_COMM_FAIL;
			}*/
			break;
	}
	
	if (memcmp(data, expected, 4) == 0)
	{
		return ATCA_SUCCESS;
	}
	
	return ATCA_COMM_FAIL;
}

/** \brief idle CryptoAuth device using I2C bus
 * \param[in] interface to logical device to idle
 */
ATCA_STATUS hal_i2c_idle(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];
	
	data[0] = 0x02;	// idle word address value
	
	//twi_package_t packet = {
	twi_packet_t packet = {
		.chip        = cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length = 0,
		.buffer      = (void *)data,
		.length      = 1
	};
	
	switch(bus)
	{
		case 0:
			//if (twi_master_write(TWI0, &packet) != TWI_SUCCESS)
			if (twi_master_write(TWI_Channel0, &packet) != TWI_SUCCESS)
			{
				return ATCA_COMM_FAIL;
			}
			break;
		case 1:
			if (twi_master_write(TWI_Channel1, &packet) != TWI_SUCCESS)
			{
				return ATCA_COMM_FAIL;
			}
			break;
	}
	
	return ATCA_SUCCESS;
}

/** \brief sleep CryptoAuth device using I2C bus
 * \param[in] interface to logical device to sleep
 */
ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];
	
	data[0] = 0x01;	// sleep word address value
	
	//twi_package_t packet = {
	twi_packet_t packet = {
		.chip        = cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length = 0,
		.buffer      = (void *)data,
		.length      = 1
	};
	
	switch(bus)
	{
		case 0:
			//if (twi_master_write(TWI0, &packet) != TWI_SUCCESS)
			if (twi_master_write(TWI_Channel0, &packet) != TWI_SUCCESS)
			{
				return ATCA_COMM_FAIL;
			}
			break;
		case 1:
			if (twi_master_write(TWI_Channel1, &packet) != TWI_SUCCESS)
			{
				return ATCA_COMM_FAIL;
			}
			break;
	}
	
	return ATCA_SUCCESS;
}

/** \brief manages reference count on given bus and releases resource if no more refences exist
 * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation
 */
ATCA_STATUS hal_i2c_release( void *hal_data )
{
	ATCAI2CMaster_t *hal = (ATCAI2CMaster_t *)hal_data;
	
	i2c_bus_ref_ct--;  // track total i2c bus interface instances for consistency checking and debugging
	
	// if the use count for this bus has gone to 0 references, disable it.  protect against an unbracketed release
	if (hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL)
	{
		switch(hal->bus_index)
		{
			//case 0: twi_reset(TWI0); break;
			case 0: twi_reset(TWI_Channel0);break;
			case 1: twi_reset(TWI_Channel1);break;
		}
		free(i2c_hal_data[hal->bus_index]);
		i2c_hal_data[hal->bus_index] = NULL;
	}
	
	return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint32_t twihs_device;
	uint16_t status;

	twihs_device = i2c_hal_data[bus]->twi_module;

	twihs_packet_t packet = {
		.addr[0]        = 0,
		.addr[1]        = 0,
		.addr_length	= 0,                              //very important, since cryptoauthdevices do not require addressing;
		.chip			= cfg->atcai2c.slave_address >> 1,
		.buffer			= txdata,
	};

	// for this implementation of I2C with CryptoAuth chips, txdata is assumed to have ATCAPacket format

	// other device types that don't require i/o tokens on the front end of a command need a different hal_i2c_send and wire it up instead of this one
	// this covers devices such as ATSHA204A and ATECCx08A that require a word address value pre-pended to the packet
	// txdata[0] is using _reserved byte of the ATCAPacket
	txdata[0] = 0x03;   // insert the Word Address Value, Command token
	txlength++;         // account for word address value byte.
	packet.length = txlength;

	if (twihs_master_write( twihs_device, &packet) != STATUS_OK)
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/** \brief HAL implementation of I2C receive function for ASF I2C
 * \param[in] iface     instance
 * \param[in] rxdata    pointer to space to receive the data
 * \param[in] rxlength  ptr to expected number of receive bytes to request
 * \return ATCA_STATUS
 */

ATCA_STATUS hal_i2c_receive( ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	int retries = cfg->rx_retries;
	int status = !STATUS_OK;
	Twihs *twihs_device;

	twihs_packet_t packet = {
		.chip	= cfg->atcai2c.slave_address >> 1, // use 7-bit address
		.buffer = rxdata,
		.length = *rxlength
	};

	twihs_device = i2c_hal_data[bus]->twi_module;

	while ( retries-- > 0 && status != STATUS_OK ) {
		if ( twihs_master_read(twihs_device, &packet) != TWIHS_SUCCESS )
			status = ATCA_COMM_FAIL;
		else
			status = ATCA_SUCCESS;
	}

	if ( status != STATUS_OK )
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/** \brief method to change the bus speed of I2C
 * \param[in] iface  interface on which to change bus speed
 * \param[in] speed  baud rate (typically 100000 or 400000)
 */

ATCA_STATUS change_i2c_speed( ATCAIface iface, uint32_t speed )
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;

	// if necessary, revert baud rate to what came in.
	if (twihs_set_speed(i2c_hal_data[bus]->twi_module, speed, sysclk_get_cpu_hz() / CONFIG_SYSCLK_DIV) == FAIL)
		return ATCA_COMM_FAIL;
}
ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	int retries = cfg->rx_retries;
	uint32_t bdrt = cfg->atcai2c.baud;
	int status = !STATUS_OK;
	uint8_t data[4], expected[4] = { 0x04, 0x11, 0x33, 0x43 };

	if ( bdrt != 100000 )  // if not already at 100KHz, change it
		change_i2c_speed( iface, 100000 );

	// Send the wake by writing to an address of 0x00
	twi_package_t packet = {
		.addr_length	= 0,        // TWI slave memory address data size
		.chip			= 0x00,     // TWI slave bus address
		.buffer			= &data[0], // transfer data source buffer
		.length			= 0         // transfer data size (bytes)
	};


	// Send the 00 address as the wake pulse
	twi_master_write(i2c_hal_data[bus]->i2c_master_instance, &packet ); // part will NACK, so don't check for status

	atca_delay_us(cfg->wake_delay);                                     // wait tWHI + tWLO which is configured based on device type and configuration structure

	packet.chip = cfg->atcai2c.slave_address >> 1;
	packet.length = 4;
	packet.buffer = data;

	while ( retries-- > 0 && status != STATUS_OK )
		status = twi_master_read(i2c_hal_data[bus]->i2c_master_instance, &packet);

	if ( status != STATUS_OK )
		return ATCA_COMM_FAIL;

	// if necessary, revert baud rate to what came in.
	if ( bdrt != 100000 )
		change_i2c_speed( iface, bdrt );

	if ( memcmp( data, expected, 4 ) == 0 )
		return ATCA_SUCCESS;

	return ATCA_COMM_FAIL;
}

/** \brief idle CryptoAuth device using I2C bus
 * \param[in] iface  interface to logical device to idle
 */

ATCA_STATUS hal_i2c_idle(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];

	twi_package_t packet = {
		.addr_length	= 0,                                // TWI slave memory address data size
		.chip			= cfg->atcai2c.slave_address >> 1,  // TWI slave bus address
		.buffer			= &data[0],                         // transfer data source buffer
		.length			= 1                                 // transfer data size (bytes)
	};

	data[0] = 0x02;  // idle word address value
	if ( twi_master_write((i2c_hal_data[bus]->i2c_master_instance), &packet) != STATUS_OK )
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;

}

/** \brief sleep CryptoAuth device using I2C bus
 * \param[in] iface  interface to logical device to sleep
 */

ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];

	twi_package_t packet = {
		.addr_length	= 0,                                // TWI slave memory address data size
		.chip			= cfg->atcai2c.slave_address >> 1,  // TWI slave bus address
		.buffer			= &data[0],                         // transfer data source buffer
		.length			= 1                                 // transfer data size (bytes)
	};

	data[0] = 0x01;  // sleep word address value
	if ( twi_master_write((i2c_hal_data[bus]->i2c_master_instance), &packet) != STATUS_OK )
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/** \brief manages reference count on given bus and releases resource if no more refences exist
 * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation
 */

ATCA_STATUS hal_i2c_release( void *hal_data )
{
	ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data;

	i2c_bus_ref_ct--;  // track total i2c bus interface instances for consistency checking and debugging

	// if the use count for this bus has gone to 0 references, disable it.  protect against an unbracketed release
	if ( hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL ) {
		twi_master_disable(hal->i2c_master_instance);
		free(i2c_hal_data[hal->bus_index]);
		i2c_hal_data[hal->bus_index] = NULL;
	}

	return ATCA_SUCCESS;
}
Example #20
0
/**
 * \brief wake up CryptoAuth device using I2C bus
 *
 * \param[in] iface  interface to logical device to wakeup
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);

	// set to default i2c bus
	if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1)
		cfg->atcai2c.bus = 0;
	int bus = cfg->atcai2c.bus;
	int retries = cfg->rx_retries;
	uint32_t bdrt = cfg->atcai2c.baud;
	int status = !TWI_SUCCESS;
	uint8_t data[4], expected[4] = { 0x04, 0x11, 0x33, 0x43 };

	// if not already at 100kHz, change it
	if (bdrt != 100000)
		change_i2c_speed(iface, 100000);

	// Send 0x00 as wake pulse
	twi_write_byte(i2c_hal_data[bus]->twi_master_instance, 0x00);

	// rounded up to the nearest ms
	atca_delay_ms(((uint32_t)cfg->wake_delay + (1000 - 1)) / 1000);   // wait tWHI + tWLO which is configured based on device type and configuration structure

	twi_package_t packet = {
		.chip			= cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length	= 0,
		.buffer			= (void*)data,
		.length			= 4
	};

	// if necessary, revert baud rate to what came in.
	if (bdrt != 100000)
		change_i2c_speed(iface, bdrt);

	while (retries-- > 0 && status != TWI_SUCCESS)
		status = twi_master_read(i2c_hal_data[bus]->twi_master_instance, &packet);
	if (status != TWI_SUCCESS)
		return ATCA_COMM_FAIL;

	if (memcmp(data, expected, 4) == 0)
		return ATCA_SUCCESS;

	return ATCA_COMM_FAIL;
}

/**
 * \brief idle CryptoAuth device using I2C bus
 *
 * \param[in] iface  interface to logical device to idle
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_idle(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);

	// set to default i2c bus
	if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1)
		cfg->atcai2c.bus = 0;
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];

	data[0] = 0x02; // idle word address value

	twi_package_t packet = {
		.chip			= cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length	= 0,
		.buffer			= (void*)data,
		.length			= 1
	};

	if (twi_master_write(i2c_hal_data[bus]->twi_master_instance, &packet) != TWI_SUCCESS)
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/**
 * \brief sleep CryptoAuth device using I2C bus
 *
 * \param[in] iface  interface to logical device to sleep
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);

	// set to default i2c bus
	if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1)
		cfg->atcai2c.bus = 0;
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];

	data[0] = 0x01; // sleep word address value

	twi_package_t packet = {
		.chip			= cfg->atcai2c.slave_address >> 1,
		.addr[0]     = NULL,
		.addr_length	= 0,
		.buffer			= (void*)data,
		.length			= 1
	};

	if (twi_master_write(i2c_hal_data[bus]->twi_master_instance, &packet) != TWI_SUCCESS)
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/**
 * \brief manages reference count on given bus and releases resource if no more refences exist
 *
 * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation
 *
 * \return ATCA_STATUS
 */
ATCA_STATUS hal_i2c_release(void *hal_data)
{
	ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data;

	// set to default i2c bus
	if (hal->bus_index > MAX_I2C_BUSES - 1)
		hal->bus_index = 0;

	i2c_bus_ref_ct--;  // track total i2c bus interface instances for consistency checking and debugging

	// if the use count for this bus has gone to 0 references, disable it.  protect against an unbracketed release
	if (hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL) {
		twi_reset(hal->twi_master_instance);
		free(i2c_hal_data[hal->bus_index]);
		i2c_hal_data[hal->bus_index] = NULL;
	}

	return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_wake(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	int retries = cfg->rx_retries, rxlength;
	uint32_t bdrt = cfg->atcai2c.baud;
	int status = !STATUS_OK;
	uint8_t data[4], expected[4] = { 0x04, 0x11, 0x33, 0x43 };
	volatile Twihs * twihs_device;

	twihs_device = i2c_hal_data[bus]->twi_module;

	if ( bdrt != 100000 )  // if not already at 100KHz, change it

		if (twihs_set_speed(twihs_device, 100000, sysclk_get_cpu_hz() / CONFIG_SYSCLK_DIV) == FAIL)
			return ATCA_COMM_FAIL;

	twihs_packet_t packet = {
		.addr[0]        = 0,
		.addr[1]        = 0,
		.addr_length	= 0,                              //very important, since cryptoauthdevices do not require addressing;
		.chip			= cfg->atcai2c.slave_address >> 1,
		.buffer			=  &data[0],
		.length			= 1
	};

	twihs_master_write(twihs_device, &packet);

	atca_delay_us(cfg->wake_delay);   // wait tWHI + tWLO which is configured based on device type and configuration structure

	// look for wake response
	rxlength = 4;
	memset(data, 0x00, rxlength);
	status = hal_i2c_receive(iface, data, &rxlength );

	// if necessary, revert baud rate to what came in.
	if ( bdrt != 100000)
		if (twihs_set_speed(twihs_device, bdrt, sysclk_get_cpu_hz() / CONFIG_SYSCLK_DIV) == FAIL)
			return ATCA_COMM_FAIL;

	if ( status != STATUS_OK )
		return ATCA_COMM_FAIL;

	if ( memcmp( data, expected, 4 ) == 0 )
		return ATCA_SUCCESS;

	return ATCA_COMM_FAIL;
}


/** \brief idle CryptoAuth device using I2C bus
 * \param[in] iface  interface to logical device to idle
 */

ATCA_STATUS hal_i2c_idle(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];
	int length;
	uint32_t twihs_device;
	uint16_t status;

	data[0] = 0x02;  // idle word address value

	twihs_device = i2c_hal_data[bus]->twi_module;

	twihs_packet_t packet = {
		.addr[0]        = 0,
		.addr[1]        = 0,
		.addr_length	= 0,                              //very important, since cryptoauthdevices do not require addressing;
		.chip			= cfg->atcai2c.slave_address >> 1,
		.buffer			= data,
	};

	packet.length = 1;

	if (twihs_master_write( twihs_device, &packet) != STATUS_OK)
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/** \brief sleep CryptoAuth device using I2C bus
 * \param[in] iface  interface to logical device to sleep
 */

ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];
	int length;
	uint32_t twihs_device;
	uint16_t status;

	data[0] = 0x01;  // sleep word address value

	twihs_device = i2c_hal_data[bus]->twi_module;

	twihs_packet_t packet = {
		.addr[0]        = 0,
		.addr[1]        = 0,
		.addr_length	= 0,                              //very important, since cryptoauthdevices do not require addressing;
		.chip			= cfg->atcai2c.slave_address >> 1,
		.buffer			= data,
	};

	packet.length = 1;

	if (twihs_master_write( twihs_device, &packet) != STATUS_OK)
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/** \brief manages reference count on given bus and releases resource if no more refences exist
 * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation
 */

ATCA_STATUS hal_i2c_release( void *hal_data )
{
	ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data;

	i2c_bus_ref_ct--;  // track total i2c bus interface instances for consistency checking and debugging

	// if the use count for this bus has gone to 0 references, disable it.  protect against an unbracketed release
	if ( hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL ) {
		twihs_disable_master_mode( i2c_hal_data[hal->bus_index]->twi_module );
		free(i2c_hal_data[hal->bus_index]);
		i2c_hal_data[hal->bus_index] = NULL;
	}

	return ATCA_SUCCESS;
}
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;

	twi_package_t packet = {
		.addr_length	= 0,                                // TWI slave memory address data size
		.chip			= cfg->atcai2c.slave_address >> 1,  // TWI slave bus address
		.buffer			= txdata,                           // transfer data source buffer
		.length			= txlength,                         // transfer data size (bytes)
	};

	// for this implementation of I2C with CryptoAuth chips, txdata is assumed to have ATCAPacket format

	// other device types that don't require i/o tokens on the front end of a command need a different hal_i2c_send and wire it up instead of this one
	// this covers devices such as ATSHA204A and ATECCx08A that require a word address value pre-pended to the packet
	// txdata[0] is using _reserved byte of the ATCAPacket
	txdata[0] = 0x03;   // insert the Word Address Value, Command token
	txlength++;         // account for word address value byte.
	packet.length = txlength;

	if ( twi_master_write(i2c_hal_data[bus]->i2c_master_instance, &packet) != STATUS_OK )
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/** \brief HAL implementation of I2C receive function for ASF I2C
 * \param[in] iface     instance
 * \param[in] rxdata    pointer to space to receive the data
 * \param[in] rxlength  ptr to expected number of receive bytes to request
 * \return ATCA_STATUS
 */

ATCA_STATUS hal_i2c_receive( ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength)
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	int retries = cfg->rx_retries;
	int status = !STATUS_OK;

	twi_package_t packet = {
		.addr_length	= 0,                                // TWI slave memory address data size
		.chip			= cfg->atcai2c.slave_address >> 1,  // TWI slave bus address
		.buffer			= rxdata,                           // transfer data source buffer
		.length			= *rxlength,                        // transfer data size (bytes)
	};

	while ( retries-- > 0 && status != STATUS_OK )
		status = twi_master_read(i2c_hal_data[bus]->i2c_master_instance, &packet);

	if ( status != STATUS_OK )
		return ATCA_COMM_FAIL;

	return ATCA_SUCCESS;
}

/** \brief method to change the bus speec of I2C
 * \param[in] iface  interface on which to change bus speed
 * \param[in] speed  baud rate (typically 100000 or 400000)
 */

void change_i2c_speed( ATCAIface iface, uint32_t speed )
{
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;

	config_i2c_master.speed = speed;
	config_i2c_master.speed_reg = TWI_BAUD(sysclk_get_cpu_hz(), speed);

	twi_master_disable(i2c_hal_data[bus]->i2c_master_instance);

	switch (bus) {
	case 0: i2c_hal_data[bus]->i2c_master_instance = &TWIC; break;
	case 2: i2c_hal_data[bus]->i2c_master_instance = &TWIE; break;
	}

	twi_master_setup((i2c_hal_data[bus]->i2c_master_instance), &config_i2c_master);

	twi_master_enable(i2c_hal_data[bus]->i2c_master_instance);
}
Example #23
0
ATCA_STATUS hal_swi_receive( ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength)
{
#ifdef DEBUG_HAL
	printf("hal_swi_receive()\r\n");
#endif
	ATCA_STATUS status = ATCA_COMM_FAIL;
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcaswi.bus;
	int retries = cfg->rx_retries;
	uint8_t bit_mask, *head_buff, bit_data;
	uint16_t i = 0;

	while ((status != ATCA_SUCCESS) && (retries >= 0x00)) {
		retries--;
		head_buff = rxdata;

		status = hal_swi_send_flag(iface, SWI_FLAG_TX);

		// Set SWI to receive mode.
		swi_uart_mode(swi_hal_data[bus], RECEIVE_MODE);
#ifdef SAMD21_ASF
		RX_DELAY
#else
		atca_delay_us(RX_DELAY); // Must be configured to sync with response from device
#endif
		if (status == ATCA_SUCCESS) {
			for (i = 0; i < *rxlength; i++) {
				*head_buff = 0x00;
				for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
					bit_data = 0;
					status = swi_uart_receive_byte(swi_hal_data[bus], &bit_data);
					if ((i == 0) && (bit_mask == 1) && (status != ATCA_SUCCESS)) break;
					// Sometimes bit data from device is stretched
					// When the device sends a "one" bit, it is read as 0x7E or 0x7F.
					// When the device sends a "zero" bit, it is read as 0x7A, 0x7B, or 7D.
					if ((bit_data ^ 0x7F) < 2)
						// Received "one" bit.
						*head_buff |= bit_mask;
				}
				if ((i == 0) && (bit_mask == 1) && (status != ATCA_SUCCESS)) break;
				head_buff++;
			}
			// Set SWI to transmit mode.
			swi_uart_mode(swi_hal_data[bus], TRANSMIT_MODE);
			atca_delay_us(TX_DELAY); // Must be configured to sync with response from device
		}
		// The Response shorter than expected
		if ((i >= 4) && (status = ATCA_TIMEOUT))
			status = ATCA_SUCCESS;
	}
#ifdef DEBUG_HAL
	printf("\r\nResponse Packet (size:0x%.4x)\r\n", *rxlength);
	printf("Count  : %.2x\r\n", rxdata[0]);
	if (rxdata[0] > 3) {
		printf("Data   : "); print_array(&rxdata[1], rxdata[0] - 3);
		printf("CRC    : "); print_array(&rxdata[rxdata[0] - 2], 2);
	}
	printf("\r\n");
#endif
	return status;
}