Пример #1
0
/*! \brief Write device register content.
 *
 * \param reg_index Register address. Use macros as defined in the header file.
 * \param data Data that should be written to the device register.
 */
void PCA9952_write_reg(unsigned char topBotn, uint8_t reg_index, uint8_t data)
{
	uint8_t pack[2];
	twihs_packet_t twi_package;

	pack[0] = reg_index;
	pack[1] = data;

//7apr15	twi_package.chip = PCA9952_TWI_ADDRESS;

	if (topBotn == LED_TOP)
	{
		twi_package.chip = PCA9952_U7_TOPDRIVE_TWI_ADDRESS;
	}
	else if (topBotn == LED_BOTTOM)
	{
		twi_package.chip = PCA9952_U8_BOTDRIVE_TWI_ADDRESS;
	}

	twi_package.addr[0] = 0;		//is this right? 8feb16
	twi_package.addr[1] = 0;		//is this right? 8feb16
	twi_package.addr[2] = 0;		//is this right? 8feb16
	twi_package.addr_length = 0;
	twi_package.buffer = &pack;
	twi_package.length = sizeof(pack);

	while(twihs_master_write(PCA9952_TWI, &twi_package)!=TWIHS_SUCCESS);

	return;
}
Пример #2
0
/**
 * \brief Test if a chip answers a given I2C address.
 *
 * \param p_twihs Pointer to a TWIHS instance.
 * \param uc_slave_addr Address of the remote chip to search for.
 *
 * \return TWIHS_SUCCESS if a chip was found, error code otherwise.
 */
uint32_t twihs_probe(Twihs *p_twihs, uint8_t uc_slave_addr)
{
	twihs_packet_t packet;
	uint8_t data = 0;

	/* Data to send */
	packet.buffer = &data;
	/* Data length */
	packet.length = 1;
	/* Slave chip address */
	packet.chip = (uint32_t) uc_slave_addr;
	/* Internal chip address */
	packet.addr[0] = 0;
	/* Address length */
	packet.addr_length = 0;

	/* Perform a master write access */
	return (twihs_master_write(p_twihs, &packet));
}
Пример #3
0
static sint8 nm_i2c_write(uint8 *b, uint16 sz)
{
	sint8 result = M2M_SUCCESS;
	twihs_packet_t packet_tx;
	uint16_t timeout = 0;

	/* Configure the data packet to be transmitted */
	packet_tx.chip        = SLAVE_ADDRESS;
	packet_tx.addr[0]     = 0;
	packet_tx.addr[1]     = 0;
	packet_tx.addr[2]     = 0;
	packet_tx.addr_length = 0;
	packet_tx.buffer      = b;
	packet_tx.length      = sz;

	while(twihs_master_write(CONF_WINC_I2C, &packet_tx) != TWIHS_SUCCESS) {
		if (timeout++ == I2C_TIMEOUT) {
			break;
		}
	}	
	return result;
}
Пример #4
0
/*! \brief Read device register content.
 *
 * \param reg_index Register address.
 * \returns Register content.
 */
uint8_t PCA9952_read_reg(unsigned char topBotn, uint8_t reg_index)
{
	uint8_t data;
	twihs_packet_t twi_package;

//7apr15	twi_package.chip = PCA9952_TWI_ADDRESS;

	if (topBotn == LED_TOP)
	{
		twi_package.chip = PCA9952_U7_TOPDRIVE_TWI_ADDRESS;
	}
	else if (topBotn == LED_BOTTOM)
	{
		twi_package.chip = PCA9952_U8_BOTDRIVE_TWI_ADDRESS;
	}

	twi_package.addr[0] = 0;		//is this right? 8feb16
	twi_package.addr[1] = 0;		//is this right? 8feb16
	twi_package.addr[2] = 0;		//is this right? 8feb16
	twi_package.addr_length = 0;
	twi_package.buffer = &reg_index;
	twi_package.length = 1;
	while(twihs_master_write(PCA9952_TWI, &twi_package)!=TWIHS_SUCCESS);
	/* We need a delay here to make this work although this is not
	* specified in the datasheet.
	* Also there seems to be a bug in the TWI module or the driver
	* since some delay here (code or real delay) adds about 500us
	* between the write and the next read cycle.
	*/
	mdelay(20);

//7apr15 this was set above, no need to reassign	twi_package.chip = PCA9952_TWI_ADDRESS;
	twi_package.addr_length = 0;
	twi_package.buffer = &data;
	twi_package.length = 1;
	while(twihs_master_read(PCA9952_TWI, &twi_package)!=TWIHS_SUCCESS);

	return data;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
/**
 * \brief Application entry point for TWI EEPROM example.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint32_t i;
	twihs_options_t opt;
	twihs_packet_t packet_tx, packet_rx;

	/* Initialize the SAM system */
	sysclk_init();

	/* Initialize the board */
	board_init();

	/* Turn off LEDs */
	LED_Off(LED0);
	
    /* Initialize the console UART */
	configure_console();

	/* Output example information */
	puts(STRING_HEADER);

	/* Configure systick for 1 ms */
	puts("Configure system tick to get 1ms tick period.\r");
	if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) {
		puts("-E- Systick configuration error\r");
		while (1) {
			/* Capture error */
		}
	}

	/* Enable the peripheral clock for TWI */
	pmc_enable_periph_clk(BOARD_ID_TWIHS_EEPROM);

	/* Configure the options of TWI driver */
	opt.master_clk = sysclk_get_cpu_hz();
	opt.speed      = TWIHS_CLK;

	/* Configure the data packet to be transmitted */
	packet_tx.chip        = AT24C_ADDRESS;
	packet_tx.addr[0]     = EEPROM_MEM_ADDR >> 8;
	packet_tx.addr[1]     = EEPROM_MEM_ADDR;
	packet_tx.addr_length = EEPROM_MEM_ADDR_LENGTH;
	packet_tx.buffer      = (uint8_t *) test_data_tx;
	packet_tx.length      = TEST_DATA_LENGTH;

	/* Configure the data packet to be received */
	packet_rx.chip        = packet_tx.chip;
	packet_rx.addr[0]     = packet_tx.addr[0];
	packet_rx.addr[1]     = packet_tx.addr[1];
	packet_rx.addr_length = packet_tx.addr_length;
	packet_rx.buffer      = gs_uc_test_data_rx;
	packet_rx.length      = packet_tx.length;

	if (twihs_master_init(BOARD_BASE_TWIHS_EEPROM, &opt) != TWIHS_SUCCESS) {
		puts("-E-\tTWI master initialization failed.\r");
		while (1) {
			/* Capture error */
		}
	}

	/* Send test pattern to EEPROM */
	if (twihs_master_write(BOARD_BASE_TWIHS_EEPROM, &packet_tx) != TWIHS_SUCCESS) {
		puts("-E-\tTWI master write packet failed.\r");
		while (1) {
			/* Capture error */
		}
	}
	puts("Write:\tOK!\n\r");

	/* Wait at least 10 ms */
	mdelay(WAIT_TIME);

	/* Get memory from EEPROM*/
	if (twihs_master_read(BOARD_BASE_TWIHS_EEPROM, &packet_rx) != TWIHS_SUCCESS) {
		puts("-E-\tTWI master read packet failed.\r");
		while (1) {
			/* Capture error */
		}
	}
	puts("Read:\tOK!\r");

	/* Compare the sent and the received */
	for (i = 0; i < TEST_DATA_LENGTH; i++) {
		if (test_data_tx[i] != gs_uc_test_data_rx[i]) {
			/* No match */
			puts("Data comparison:\tUnmatched!\r");
			while (1) {
				/* Capture error */
			}
		}
	}
	/* Match */
	puts("Data comparison:\tMatched!\r");
	LED_On(LED0);
	while (1) {
	}
}