Example #1
0
/*
 * Init TWI interface for WM8731 .
 */
static void init_twi_wm8731(void)
{
	twi_options_t opt;

	/* Configure the options of TWI driver */
	opt.master_clk = sysclk_get_peripheral_hz();
	opt.speed	   = TWI_WM8731_CLK;
	opt.chip	   = WM8731_SLAVE_ADDRESS;
	twi_master_setup(TWI_WM8731, &opt);
}
 void configure_twi( void ) {
     
     twi_master_options_t * p_opt = (twi_master_options_t * ) pvPortMalloc (sizeof(twi_master_options_t));
     p_opt->speed = TWI0_SPEED;
     p_opt->chip = TWI0_CHIP;
          
     twi_master_setup(TWI0, p_opt);
     
    // twi_enable_interrupt(TWI0, TWI0_INTERRUPT_FLAGS);
     
 }
Example #3
0
/**
 * \brief Initialize TWI communication interface.
 */
static void init_interface(void)
{
    /** TWI master initialization options. */
    twi_master_options_t twi_opt;

    memset((void *)&twi_opt, 0, sizeof(twi_master_options_t));

    /** 100KHz for I2C speed */
    twi_opt.speed = 100000;

    /** Initialize the TWI master driver. */
    twi_master_setup(BOARD_QT_TWI_INSTANCE, &twi_opt);
}
Example #4
0
/* Init the CDCE906 chip, set offline */
bool cdce906_init(void)
{
	gpio_configure_pin(PIN_CDCE_SDA, PIN_CDCE_SDA_FLAGS);
	gpio_configure_pin(PIN_CDCE_SCL, PIN_CDCE_SCL_FLAGS);
	
	twi_master_options_t opt = {
		.speed = 50000,
		.chip  = CDCE906_ADDR
	};
	
	twi_master_setup(TWI1, &opt);
	
	uint8_t data = 0;
	
	/* Read addr 0 */
	if (cdce906_read(0, &data) == false){
		return false;
	}
	
	/* Check vendor ID matches expected */
	if ((data & 0x0F) == 0x01){
		return true;
	}

	return false;
}

bool cdce906_write(uint8_t addr, uint8_t data)
{
	twi_package_t packet_write = {
		.addr         = {0x80 | addr},      // TWI slave memory address data
		.addr_length  = 1,    // TWI slave memory address data size
		.chip         = CDCE906_ADDR,      // TWI slave bus address
		.buffer       = &data, // transfer data source buffer
		.length       = 1  // transfer data size (bytes)
	};
	
	if (twi_master_write(TWI1, &packet_write) == TWI_SUCCESS){
		return true;
	} else {
		return false;
	}
}
Example #5
0
File: main.c Project: kerichsen/asf
/*! \brief Initializes the two-wire interface
 */
static void init_twi(uint32_t fpba_hz)
{
  volatile uint32_t i;

  static const gpio_map_t CS2200_TWI_GPIO_MAP =
  {
    {AVR32_TWI_SCL_0_0_PIN, AVR32_TWI_SCL_0_0_FUNCTION},
    {AVR32_TWI_SDA_0_0_PIN, AVR32_TWI_SDA_0_0_FUNCTION}
  };

  static twi_master_options_t CS2200_TWI_OPTIONS =
  {
    .speed  = CS2200_TWI_MASTER_SPEED,
    .chip   = CS2200_TWI_SLAVE_ADDRESS
  };
  CS2200_TWI_OPTIONS.pba_hz = fpba_hz;

  gpio_enable_module(CS2200_TWI_GPIO_MAP,
                     sizeof(CS2200_TWI_GPIO_MAP) / sizeof(CS2200_TWI_GPIO_MAP[0]));
  twi_master_setup(CS2200_TWI, &CS2200_TWI_OPTIONS);
}
/**
 * \brief Set maXTouch configuration
 *
 * This function writes a set of predefined, optimal maXTouch configuration data
 * to the mXT143E Xplained.
 *
 * \param device Pointer to mxt_device struct
 */
static void mxt_init(struct mxt_device *device)
{
	enum status_code status;
	UNUSED(status);

	/* T8 configuration object data */
	uint8_t t8_object[] = {
		0x10, 0x05, 0x0a, 0x14, 0x64, 0x00, 0x05,
		0x0a, 0x00, 0x00,
	};

	/* T9 configuration object data */
	uint8_t t9_object[] = {
		0x8f, 0x00, 0x00, 0x0d, 0x0b, 0x00, 0x21,
		0x3c, 0x0f, 0x00, 0x32, 0x01, 0x01, 0x00,
		0x08, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x1c, 0x1c, 0x37, 0x37, 0x8f, 0x50,
		0xcf, 0x6e, 0x00, 0x02, 0x2f, 0x2c, 0x00
	};

	/* T48 configuration object data */
	uint8_t t48_object[] = {
		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00
	};

	/* TWI configuration */
	twi_master_options_t twi_opt = {
		.speed = MXT_TWI_SPEED,
		.chip  = MAXTOUCH_TWI_ADDRESS,
	};

	status = twi_master_setup(TWI_INTERFACE, &twi_opt);
	Assert(status == STATUS_OK);

	/* Initialize the maXTouch device */
	status = mxt_init_device(device, TWI_INTERFACE,
			MAXTOUCH_TWI_ADDRESS, MXT143E_XPLAINED_CHG);
	Assert(status == STATUS_OK);

	/* Issue soft reset of maXTouch device by writing a non-zero value to
	 * the reset register */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_COMMANDPROCESSOR_T6, 0)
			+ MXT_GEN_COMMANDPROCESSOR_RESET, 0x01);

	/* Wait for the reset of the device to complete */
	delay_ms(MXT_RESET_TIME);

	/* Write data to configuration registers in T7 configuration object */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 0, 0xff);
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 1, 0xff);
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 2, 0x32);

	/* Write predefined configuration data to configuration objects */
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_GEN_ACQUISITIONCONFIG_T8, 0), &t8_object);
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_TOUCH_MULTITOUCHSCREEN_T9, 0), &t9_object);
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_PROCG_TOUCHSUPPRESSION_T48, 0), &t48_object);

	/* Issue recalibration command to maXTouch device by writing a non-zero
	 * value to the calibrate register */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_COMMANDPROCESSOR_T6, 0)
			+ MXT_GEN_COMMANDPROCESSOR_CALIBRATE, 0x01);
}
int main(void)
{
	static uint8_t ret = 0;
	uint8_t i = 0;
	uint8_t ibuf[16] = {0};
	static uint8_t test_pattern[PATTERN_TEST_LENGTH];
	sensor_data_t sensor_data;
	twi_master_options_t opt;

	irq_initialize_vectors();

	sysclk_init();

	/* Initialize the board.
	 * The board-specific conf_board.h file contains the configuration of
	 * the board initialization.
	 */
	board_init();
	gfx_mono_init();
	ioport_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
	gfx_mono_draw_string("Reading....\r\n", 0, 0, &sysfont);
	gfx_mono_generic_draw_filled_rect(0, 8, 128, 8, GFX_PIXEL_CLR);

	/* configure the pins connected to LEDs as output and set their default
	 * initial state to low (LEDs off).
	 */
	ioport_configure_pin(LED_LOW, IOPORT_DIR_OUTPUT);
	ioport_configure_pin(LED_HIGH, IOPORT_DIR_OUTPUT);
	ioport_configure_pin(LED_CRIT, IOPORT_DIR_OUTPUT);
	ioport_configure_pin(LED_NORM, IOPORT_DIR_OUTPUT);

	ioport_set_pin_low(LED_LOW);
	ioport_set_pin_low(LED_HIGH);
	ioport_set_pin_low(LED_CRIT);
	ioport_set_pin_low(LED_NORM);

	/* Configure the ALERT/EVENT pin which is
	 * routed to pin 2 of J2 on A3BU Xplained
	 * This pin can be used for polling or interrupt
	 */
	ioport_configure_pin(EVENT_PIN, IOPORT_DIR_INPUT);

	attach_device(EXAMPLE_TS_DEVICE_ADDR, EXAMPLE_TS_DEVICE);
	opt.chip = EXAMPLE_TS_DEVICE_ADDR;
	opt.speed = TWI_SPEED;

	/* Initialize TWI driver with options */
	twi_master_setup(TWI_MODULE, &opt);

	sensor_data.config_reg.value = 0;
	/* Set configuration register to 12-bis resolution */
	sensor_data.config_reg.option.RES  = AT30TS7_RES12;

	if (write_config(sensor_data.config_reg.value) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Set the polarity of ALERT/EVENT pin to low */

	if (set_config_option(&sensor_data, AT30TS_POL, AT30TS7_POL_ACTIVE_LOW) !=
	TWI_SUCCESS) {
	test_fail_indication();
	}

	/* Read the configuration register */
	if (read_config(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}

#if defined _AT30TS00_ || defined _AT30TSE002B_
	/* Set t_high limit register to +75.0000C */
	if (write_tcrit(pos, 75, 0000) != TWI_SUCCESS) {
		test_fail_indication();
	}
#endif

	/* Set t_high limit register to +50.7500C */
	if (write_temperature_high(pos, 50, 7500) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Set t_low limit register to -25.2500C */

	/*
	 * if (write_temperature_low(neg, 25, 2500)!= TWI_SUCCESS) {
	 * test_fail_indication();
	 * }
	 */

	/* Set t_low limit register to +35.5000C */
	if (write_temperature_low(pos, 35, 5000) != TWI_SUCCESS) {
		test_fail_indication();
	}

#if defined _AT30TS00_ || defined _AT30TSE002B_
	/* Read t_crit register register */
	if (read_tcrit(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}
#endif

	/* Read t_high limit register */
	if (read_temperature_high(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Read t_low register register */
	if (read_temperature_low(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Non volatile register functionality */
#if defined _AT30TS750_  || defined _AT30TSE752_ || \
	defined _AT30TSE754_ || defined _AT30TSE758_

	/* Copy volatile registers to nonvolatile registers
	 * vol configuration register  -> nonvol configuration register
	 * vol t_high register -> nonvol t_high register
	 * vol t_low  register -> nonvol t_low register
	 */
        ret = ts75_copy_vol_nonvol_register();
	if (ret != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Read the nonvol configuration register */
	if (read_nvconfig(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Read the nonvol t_high register */
	if (read_nvthigh(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Read the nonvol t_low register */
	if (read_nvtlow(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Clear vol configuration register */
	if (write_config(0x0000) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Read the vol configuration register */
	if (read_config(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Copy nonvolatile registers to volatile registers */
	if (ts75_copy_nonvol_vol_register() != TWI_SUCCESS) {
		test_fail_indication();
	}

	/* Read the configuration register */
	if (read_config(&sensor_data) != TWI_SUCCESS) {
		test_fail_indication();
	}
#endif
        /* To avoid 'variable unused' warning */
        test_pattern[0] = ibuf[0];
        ibuf[0] = test_pattern[0];

	/* EEPROM Test */
#if defined _AT30TSE002B_  || defined _AT30TSE752_ || \
	defined _AT30TSE754_   || defined _AT30TSE758_

	/* Generate Test Pattern */
	for (i = 0; i < PATTERN_TEST_LENGTH; i++) {
		test_pattern[i] = 0x41 + i; // 'ABCD...'
	}

	/* Perform a write access & check write result */
	if ((ret = ts_write_memory(EE_TEST_ADDR, PATTERN_TEST_LENGTH,
	(void *)test_pattern)) != TWI_SUCCESS) {
		gfx_mono_draw_string("EE Write Failed ", 0, 24, &sysfont);
		test_fail_indication();
	}

	/* Allow time for EEPROM to settle */
	delay_ms(5);
	/* Clear test_pattern */
	memset(ibuf, 0, sizeof(ibuf));

	/* Perform a read access & check read result */
	if (ts_read_eeprom(EE_TEST_ADDR, PATTERN_TEST_LENGTH,
			ibuf) != TWI_SUCCESS) {
		gfx_mono_draw_string("EE Read Failed ", 0, 24, &sysfont);
		test_fail_indication();
	}

	/* Check received data against sent data */
	for (i = 0; i < PATTERN_TEST_LENGTH; i++) {
		if (ibuf[i] != test_pattern[i]) {
			gfx_mono_draw_string("EE Read mismatch ", 0, 24,
				&sysfont);
			test_fail_indication();
		}
	}

	gfx_mono_draw_string("EE Write/Read OK", 0, 24, &sysfont);
	gfx_mono_draw_string((char const*)ibuf, 0, 16, &sysfont);
#endif
	/*
	 * Temperature reading contained in struct,i.e.
	 * temperature register value = 0x3240 (+50.25C), AT30TSE758 device
	 * sensor_data.temperature.itemp = 50 //!< integer part
	 * sensor_data.temperature.ftemp = 2500 //!< fractional part
	 * sensor_data.temperature.sign = 0 //!< sign (pos(+) = 0, neg(-) = 1)
	 * sensor_data.temperature.raw_value = 0x324 //!< raw data
	 */

	char senseData[50] = {0};
	while (1) {
		/* Read temperature */
		read_temperature(&sensor_data);
		sprintf(senseData, "%d.%04d DegC",
					sensor_data.temperature.itemp,
						sensor_data.temperature.ftemp);
		gfx_mono_draw_string(senseData, 0, 8, &sysfont);
		ioport_set_pin_low(LED_NORM);
		delay_ms(200);
		ioport_set_pin_high(LED_NORM);
		delay_ms(200);
	}
}
Example #8
0
/**
 * Periodic task
 */
static void masterHandler(void) {
    static twiRequestT req;
    static enum {
        idleTS = 0,
        queryRegulatorTemperature1TS,
        waitForRegulatorTemperature1TS,
        queryRegulatorTemperature2TS,
        waitForRegulatorTemperature2TS,
        queryRegulatorFailCodesTS,
        waitForRegulatorFailCodesTS,
        queryRegulatorCurrentFaultTS,
        waitForRegulatorCurrentFaultTS,
        queryRegulatorPhaseFaultTS,
        waitForRegulatorPhaseFaultTS,
        queryInputVoltageTS,
        waitForInputVoltageTS,
        queryOutputVoltageTS,
        waitForOutputVoltageTS,
        queryBoardTempsTS,
        waitForBoardTempsTS,
        queryTachsTS,
        waitForTachsTS,
        queryPowerStatusTS,
        waitForPowerStatusTS
    } state;
    static enum {
        resetBS = 0,
        idleBS,
        retrySubmitBS,
        busyBS
    } busState[TWI_BUS_COUNT];
    static uint16_t lastModulePoll;
    static uint16_t lastIRPoll;
    static uint16_t watchdog[TWI_BUS_COUNT];
    static uint8_t txBuffer[16];
    static uint8_t rxBuffer[32];
    static uint8_t slave;
    static uint8_t ir;
    static int16_t temperature;
    int status;
    uint16_t v;
    uint8_t i;

    spiFpgaTwiMasterHandler();

    for (i = 0; i < TWI_BUS_COUNT; i++) {
        if (masterRequestHead[i]) {
            switch (busState[i]) {
            case resetBS:
                switch (i) {
                case TWI_BUS_UC:
                    twiReset();
                    twi_master_setup();
                    break;
                case TWI_BUS_FPGA:
                    spiFpgaTwiReset();
                    break;
                }
                busState[i] = idleBS;
                break;
            case idleBS:
                /* fall through */
            case retrySubmitBS:
                switch (i) {
                case TWI_BUS_UC:
                    status = twiMasterWriteRead(masterRequestHead[TWI_BUS_UC]->addr, masterRequestHead[TWI_BUS_UC]->tx, masterRequestHead[TWI_BUS_UC]->txLength, masterRequestHead[TWI_BUS_UC]->rx, masterRequestHead[TWI_BUS_UC]->rxLength);
                    break;
                case TWI_BUS_FPGA:
                    status = spiFpgaTwiMasterWriteRead(masterRequestHead[TWI_BUS_FPGA]->addr, masterRequestHead[TWI_BUS_FPGA]->tx, masterRequestHead[TWI_BUS_FPGA]->txLength, masterRequestHead[TWI_BUS_FPGA]->rx, masterRequestHead[TWI_BUS_FPGA]->rxLength);
                    break;
                }
                if (status == TWI_SUCCESS) {
                    busState[i] = busyBS;
                    watchdog[i] = msec_ticker;
                } else {
                    if (busState[i] == idleBS) {
                        watchdog[i] = msec_ticker;
                        busState[i] = retrySubmitBS;
                    } else if (elapsed_since(watchdog[i]) > TWI_TIME_MAX) {
                        masterRequestHead[i]->result = status;
                        masterRequestHead[i]->pending = 0;
                        masterRequestHead[i] = masterRequestHead[i]->next;
                        busState[i] = resetBS;
                    }
                }
                break;
            case busyBS:
                switch (i) {
                case TWI_BUS_UC:
                    status = twiStatus();
                    break;
                case TWI_BUS_FPGA:
                    status = spiFpgaTwiStatus();
                    break;
                }
                if (status != TWI_BUSY) {
                    masterRequestHead[i]->result = status;
                    masterRequestHead[i]->pending = 0;
                    masterRequestHead[i] = masterRequestHead[i]->next;
                    busState[i] = idleBS;
                } else if (elapsed_since(watchdog[i]) > TWI_TIME_MAX) {
                    masterRequestHead[i]->result = TWI_TIMEOUT;
                    masterRequestHead[i]->pending = 0;
                    masterRequestHead[i] = masterRequestHead[i]->next;
                    busState[i] = resetBS;
                }
                break;
            }
        }
    }

    switch (state) {
    case idleTS:
        if (boardid == iraBID &&
        elapsed_since(lastIRPoll) >= TWI_IR_POLLING_INTERVAL) {
            lastIRPoll = msec_ticker;
            ir = 0;
            state = queryRegulatorTemperature1TS;
        } else if (ucinfo.master && ucinfo.num_slaves &&
        elapsed_since(lastModulePoll) >=
        TWI_MODULE_POLLING_INTERVAL) {
            lastModulePoll = msec_ticker;
            slave = 0;
            state = queryBoardTempsTS;
        }
        break;

    /*
     * Regulator Temperature 1
     */
    case queryRegulatorTemperature1TS:
        txBuffer[0] = IR3566B_REG_TEMP1;
        req.addr = TWI_IR3566B_STARTADDR + ir;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 1;
        twiQueueRequest(TWI_BUS_IR3566B, &req);
        state = waitForRegulatorTemperature1TS;
        break;
    case waitForRegulatorTemperature1TS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS)
                temperature = rxBuffer[0];
            else
                temperature = -1;
            state = queryRegulatorTemperature2TS;
        }
        break;

    /*
     * Regulator Temperature 2
     */
    case queryRegulatorTemperature2TS:
        txBuffer[0] = IR3566B_REG_TEMP2;
        req.addr = TWI_IR3566B_STARTADDR + ir;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 1;
        twiQueueRequest(TWI_BUS_IR3566B, &req);
        state = waitForRegulatorTemperature2TS;
        break;
    case waitForRegulatorTemperature2TS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS) {
                if ((int16_t) rxBuffer[0] > temperature)
                    temperature = rxBuffer[0];
            }
            if (temperature >= 0)
                gwq_update_board_temperature(ir, 0x1000 | (uint16_t) temperature);
            state = queryRegulatorFailCodesTS;
        }
        break;

    /*
     * Regulator Fail Codes
     */
    case queryRegulatorFailCodesTS:
        txBuffer[0] = IR3566B_REG_L1_FAIL;
        req.addr = TWI_IR3566B_STARTADDR + ir;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 1;
        twiQueueRequest(TWI_BUS_IR3566B, &req);
        state = waitForRegulatorFailCodesTS;
        break;
    case waitForRegulatorFailCodesTS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS) {
                if (rxBuffer[0]) {
                    /* a failure code is pending */
                    if (rxBuffer[0] & IR3566B_REG_L1_FAIL_OVER_TEMP)
                        usbctrlDebugStreamPrintf("Regulator %d Fail: Over Temp\n", ir);
                    if (rxBuffer[0] & IR3566B_REG_L1_FAIL_OVER_CURRENT)
                        usbctrlDebugStreamPrintf("Regulator %d Fail: Over Current\n", ir);
                    if (rxBuffer[0] & IR3566B_REG_L1_FAIL_VCPU_HIGH)
                        usbctrlDebugStreamPrintf("Regulator %d Fail: VCPU High\n", ir);
                    if (rxBuffer[0] & IR3566B_REG_L1_FAIL_VCPU_LOW)
                        usbctrlDebugStreamPrintf("Regulator %d Fail: VCPU Low\n", ir);
                    if (rxBuffer[0] & IR3566B_REG_L1_FAIL_V12_LOW)
                        usbctrlDebugStreamPrintf("Regulator %d Fail: V12 Low\n", ir);
                    if (rxBuffer[0] & IR3566B_REG_L1_FAIL_V3_LOW)
                        usbctrlDebugStreamPrintf("Regulator %d Fail: V3 Low\n", ir);
                    if (rxBuffer[0] & IR3566B_REG_L1_FAIL_PHASE_FAULT)
                        usbctrlDebugStreamPrintf("Regulator %d Fail: Phase Fault\n", ir);
                    if (rxBuffer[0] & IR3566B_REG_L1_FAIL_SLOW_OVER_CURRENT)
                        usbctrlDebugStreamPrintf("Regulator %d Fail: Slow Over Current\n", ir);
                    /* clear sticky codes */
                    txBuffer[0] = IR3566B_REG_CLEAR_FAIL;
                    txBuffer[1] = IR3566B_REG_CLEAR_FAIL_L1_STICKY;
                    req.addr = TWI_IR3566B_STARTADDR + ir;
                    req.tx = txBuffer;
                    req.txLength = 2;
                    req.rx = rxBuffer;
                    req.rxLength = 0;
                    twiQueueRequest(TWI_BUS_IR3566B, &req);
                }
            }
            state = queryRegulatorCurrentFaultTS;
        }
        break;

    /*
     * Regulator Current Fault
     */
    case queryRegulatorCurrentFaultTS:
        txBuffer[0] = IR3566B_REG_L1_CURRENT_FAULT;
        req.addr = TWI_IR3566B_STARTADDR + ir;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 1;
        twiQueueRequest(TWI_BUS_IR3566B, &req);
        state = waitForRegulatorCurrentFaultTS;
        break;
    case waitForRegulatorCurrentFaultTS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS) {
                if ((rxBuffer[0] & IR3566B_REG_L1_CURRENT_FAULT_MAX) || (rxBuffer[0] & IR3566B_REG_L1_CURRENT_FAULT_MIN)) {
                    /* a failure code is pending */
                    if (rxBuffer[0] & IR3566B_REG_L1_CURRENT_FAULT_MIN)
                        usbctrlDebugStreamPrintf("Regulator %d Current Fault: Min\n", ir);
                    if (rxBuffer[0] & IR3566B_REG_L1_CURRENT_FAULT_MAX)
                        usbctrlDebugStreamPrintf("Regulator %d Current Fault: Max\n", ir);
                    /* read the phase that is generating the fault */
                    state = queryRegulatorPhaseFaultTS;
                } else {
                    /* move to next statistic */
                    state = queryInputVoltageTS;
                }
            }
        }
        break;

    /*
     * Regulator Phase Fault
     */
    case queryRegulatorPhaseFaultTS:
        txBuffer[0] = IR3566B_REG_PHASE_FAULT;
        req.addr = TWI_IR3566B_STARTADDR + ir;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 1;
        twiQueueRequest(TWI_BUS_IR3566B, &req);
        state = waitForRegulatorPhaseFaultTS;
        break;
    case waitForRegulatorPhaseFaultTS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS) {
                /* report which phase is generating the fault */
                if (rxBuffer[0] == IR3566B_REG_PHASE_FAULT_PHASE1)
                    usbctrlDebugStreamWriteStr("Fault in Phase 1\n");
                if (rxBuffer[0] == IR3566B_REG_PHASE_FAULT_PHASE2)
                    usbctrlDebugStreamWriteStr("Fault in Phase 2\n");
                if (rxBuffer[0] == IR3566B_REG_PHASE_FAULT_PHASE3)
                    usbctrlDebugStreamWriteStr("Fault in Phase 3\n");
                if (rxBuffer[0] == IR3566B_REG_PHASE_FAULT_PHASE4)
                    usbctrlDebugStreamWriteStr("Fault in Phase 4\n");
                if (rxBuffer[0] == IR3566B_REG_PHASE_FAULT_PHASE5)
                    usbctrlDebugStreamWriteStr("Fault in Phase 5\n");
                if (rxBuffer[0] == IR3566B_REG_PHASE_FAULT_PHASE6)
                    usbctrlDebugStreamWriteStr("Fault in Phase 6\n");
                if (rxBuffer[0] == IR3566B_REG_PHASE_FAULT_PHASE7)
                    usbctrlDebugStreamWriteStr("Fault in Phase 7\n");
                /* clear the phase fault */
                txBuffer[0] = IR3566B_REG_CLEAR_PHASE_FAULT;
                txBuffer[1] = IR3566B_REG_CLEAR_PHASE_FAULT_BIT;
                req.addr = TWI_IR3566B_STARTADDR + ir;
                req.tx = txBuffer;
                req.txLength = 2;
                req.rx = rxBuffer;
                req.rxLength = 0;
                twiQueueRequest(TWI_BUS_IR3566B, &req);
            }
            state = queryInputVoltageTS;
        }
        break;

    /*
     * Regulator Input Voltage
     */
    case queryInputVoltageTS:
        txBuffer[0] = IR3566B_REG_VIN_SUPPLY;
        req.addr = TWI_IR3566B_STARTADDR + ir;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 1;
        twiQueueRequest(TWI_BUS_IR3566B, &req);
        state = waitForInputVoltageTS;
        break;
    case waitForInputVoltageTS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS)
                moduleStatus[0].inputMillivolts[ir] = (uint16_t) ((uint32_t) rxBuffer[0] * 1000 / 8);
            state = queryOutputVoltageTS;
        }
        break;

    /*
     * Regulator Output Voltage
     */
    case queryOutputVoltageTS:
        txBuffer[0] = IR3566B_REG_L1_VOUT;
        req.addr = TWI_IR3566B_STARTADDR + ir;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 1;
        twiQueueRequest(TWI_BUS_IR3566B, &req);
        state = waitForOutputVoltageTS;
        break;
    case waitForOutputVoltageTS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS) {
                moduleStatus[0].outputMillivolts[ir] = (uint16_t) ((uint32_t) rxBuffer[0] * 1000 / 128);
            }
            if (++ir < 4) {
                state = queryRegulatorTemperature1TS;
            } else {
                state = idleTS;
            }
        }
        break;

    /*
     * Board Temperatures
     */
    case queryBoardTempsTS:
        txBuffer[0] = TWICMD_BOARD_TEMPERATURES;
        req.addr = TWI_SLAVE_STARTADDR + slave;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 8;
        twiQueueRequest(TWI_BUS_UC, &req);
        state = waitForBoardTempsTS;
        break;
    case waitForBoardTempsTS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS) {
                for (i = 0; i < 4; i++) {
                    v = ((uint16_t) rxBuffer[i * 2 + 0] << 8) | rxBuffer[i * 2 + 1];
                    gwq_update_board_temperature((slave + 1) * 4 + i, v);
                }
            }
            state = queryTachsTS;
        }
        break;

    /*
     * Board Tachs
     */
    case queryTachsTS:
        txBuffer[0] = TWICMD_TACHS;
        req.addr = TWI_SLAVE_STARTADDR + slave;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 8;
        twiQueueRequest(TWI_BUS_UC, &req);
        state = waitForTachsTS;
        break;
    case waitForTachsTS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS) {
                for (i = 0; i < 4; i++) {
                    v = ((uint16_t) rxBuffer[i * 2 + 0] << 8) | rxBuffer[i * 2 + 1];
                    gwq_update_tach((slave + 1) * 4 + i, v);
                }
            }
            state = queryPowerStatusTS;
        }
        break;

    /*
     * Board Power Status
     */
    case queryPowerStatusTS:
        txBuffer[0] = TWICMD_POWER_STATUS;
        req.addr = TWI_SLAVE_STARTADDR + slave;
        req.tx = txBuffer;
        req.txLength = 1;
        req.rx = rxBuffer;
        req.rxLength = 18;
        twiQueueRequest(TWI_BUS_UC, &req);
        state = waitForPowerStatusTS;
        break;
    case waitForPowerStatusTS:
        if (!req.pending) {
            if (req.result == TWI_SUCCESS) {
                for (i = 0; i < 4; i++) {
                    v = ((uint16_t) rxBuffer[i * 4 + 2] << 8) | rxBuffer[i * 4 + 3];
                    moduleStatus[slave + 1].inputMillivolts[i] = v;
                    v = ((uint16_t) rxBuffer[i * 4 + 4] << 8) | rxBuffer[i * 4 + 5];
                    moduleStatus[slave + 1].outputMillivolts[i] = v;
                }
            }
            if (++slave < ucinfo.num_slaves)
                state = queryBoardTempsTS;
            else
                state = idleTS;
        }
        break;
    }
}
ATCA_STATUS hal_i2c_discover_devices(int busNum, ATCAIfaceCfg cfg[], int *found )
{
	ATCAIfaceCfg *head = cfg;
	uint8_t slaveAddress = 0x01;
	ATCADevice device;
	ATCAIface discoverIface;
	ATCACommand command;
	ATCAPacket packet;
	uint32_t execution_time;
	ATCA_STATUS status;
	uint8_t revs508[1][4] = { { 0x00, 0x00, 0x50, 0x00 } };
	uint8_t revs108[1][4] = { { 0x80, 0x00, 0x10, 0x01 } };
	uint8_t revs204[2][4] = { { 0x00, 0x02, 0x00, 0x08 },
							  { 0x00, 0x04, 0x05, 0x00 } };
	int i;

	/** \brief default configuration, to be reused during discovery process */
	ATCAIfaceCfg discoverCfg = {
		.iface_type				= ATCA_I2C_IFACE,
		.devtype				= ATECC508A,
		.atcai2c.slave_address	= 0x07,
		.atcai2c.bus			= busNum,
		.atcai2c.baud			= 400000,
		//.atcai2c.baud = 100000,
		.wake_delay				= 800,
		.rx_retries				= 3
	};

	// build an info command
	packet.param1 = INFO_MODE_REVISION;
	packet.param2 = 0;

	device = newATCADevice( &discoverCfg );
	discoverIface = atGetIFace( device );
	command = atGetCommands( device );

	// iterate through all addresses on given i2c bus
	// all valid 7-bit addresses go from 0x07 to 0x78
	for ( slaveAddress = 0x07; slaveAddress <= 0x78; slaveAddress++ ) {
		discoverCfg.atcai2c.slave_address = slaveAddress << 1;  // turn it into an 8-bit address which is what the rest of the i2c HAL is expecting when a packet is sent

		// wake up device
		// If it wakes, send it a dev rev command.  Based on that response, determine the device type
		// BTW - this will wake every cryptoauth device living on the same bus (ecc508a, sha204a)

		if ( hal_i2c_wake( discoverIface ) == ATCA_SUCCESS ) {
			(*found)++;
			memcpy( (uint8_t*)head, (uint8_t*)&discoverCfg, sizeof(ATCAIfaceCfg));

			memset( packet.info, 0x00, sizeof(packet.info));

			// get devrev info and set device type accordingly
			atInfo( command, &packet );
			execution_time = atGetExecTime(command, CMD_INFO) + 1;

			// send the command
			if ( (status = atsend( discoverIface, (uint8_t*)&packet, packet.txsize )) != ATCA_SUCCESS ) {
				printf("packet send error\r\n");
				continue;
			}

			// delay the appropriate amount of time for command to execute
			atca_delay_ms(execution_time);

			// receive the response
			if ( (status = atreceive( discoverIface, &(packet.info[0]), &(packet.rxsize) )) != ATCA_SUCCESS )
				continue;

			if ( (status = isATCAError(packet.info)) != ATCA_SUCCESS ) {
				printf("command response error\r\n");
				continue;
			}

			// determine device type from common info and dev rev response byte strings
			for ( i = 0; i < sizeof(revs508) / 4; i++ ) {
				if ( memcmp( &packet.info[1], &revs508[i], 4) == 0 ) {
					discoverCfg.devtype = ATECC508A;
					break;
				}
			}

			for ( i = 0; i < sizeof(revs204) / 4; i++ ) {
				if ( memcmp( &packet.info[1], &revs204[i], 4) == 0 ) {
					discoverCfg.devtype = ATSHA204A;
					break;
				}
			}

			for ( i = 0; i < sizeof(revs108) / 4; i++ ) {
				if ( memcmp( &packet.info[1], &revs108[i], 4) == 0 ) {
					discoverCfg.devtype = ATECC108A;
					break;
				}
			}

			atca_delay_ms(15);
			// now the device type is known, so update the caller's cfg array element with it
			head->devtype = discoverCfg.devtype;
			head++;
		}

		hal_i2c_idle(discoverIface);
	}

	deleteATCADevice(&device);

	return ATCA_SUCCESS;
}


/** \brief
    - this HAL implementation assumes you've included the ASF I2C libraries in your project, otherwise,
    the HAL layer will not compile because the ASF I2C drivers are a dependency *
 */

/** \brief hal_i2c_init manages requests to initialize a physical interface.  it manages use counts so when an interface
 * has released the physical layer, it will disable the interface for some other use.
 * You can have multiple ATCAIFace instances using the same bus, and you can have multiple ATCAIFace instances on
 * multiple i2c buses, so hal_i2c_init manages these things and ATCAIFace is abstracted from the physical details.
 */

/** \brief initialize an I2C interface using given config
 * \param[in] hal - opaque ptr to HAL data
 * \param[in] cfg - interface configuration
 */
ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg)
{
	int bus = cfg->atcai2c.bus;   // 0-based logical bus number
	ATCAHAL_t *phal = (ATCAHAL_t*)hal;

	if ( i2c_bus_ref_ct == 0 )     // power up state, no i2c buses will have been used
		for ( int i = 0; i < MAX_I2C_BUSES; i++ )
			i2c_hal_data[i] = NULL;

	i2c_bus_ref_ct++;  // total across buses

	if ( bus >= 0 && bus < MAX_I2C_BUSES ) {
		// if this is the first time this bus and interface has been created, do the physical work of enabling it
		if ( i2c_hal_data[bus] == NULL ) {
			i2c_hal_data[bus] = malloc( sizeof(ATCAI2CMaster_t) );
			i2c_hal_data[bus]->ref_ct = 1;  // buses are shared, this is the first instance

			config_i2c_master.speed = cfg->atcai2c.baud;
			config_i2c_master.chip  = 0x50;
			config_i2c_master.speed_reg = TWI_BAUD(sysclk_get_cpu_hz(), cfg->atcai2c.baud);
			switch (bus) {
			case 0: i2c_hal_data[bus]->i2c_master_instance = &TWIC; break;
			//case 1: i2c_hal_data[bus]->i2c_master_instance = &TWID; break;	// for XMEGA-A1
			case 2: i2c_hal_data[bus]->i2c_master_instance = &TWIE; break;
				//case 3: i2c_hal_data[bus]->i2c_master_instance = &TWIF; break;	// for XMEGA-A1
			}

			twi_master_setup((i2c_hal_data[bus]->i2c_master_instance), &config_i2c_master);
			// store this for use during the release phase
			i2c_hal_data[bus]->bus_index = bus;
			twi_master_enable(i2c_hal_data[bus]->i2c_master_instance);
		}  else{
			// otherwise, another interface already initialized the bus, so this interface will share it and any different
			// cfg parameters will be ignored...first one to initialize this sets the configuration
			i2c_hal_data[bus]->ref_ct++;
		}

		phal->hal_data = i2c_hal_data[bus];

		return ATCA_SUCCESS;
	}

	return ATCA_COMM_FAIL;
}
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 #11
0
/*! \brief TWI Master Example Main
 *
 * The master example begins by initializing required board resources.  The
 * system clock, basic GPIO pin mapping, and interrupt vectors are established.
 *
 * A memory location on a TWI slave is written with a fixed test pattern which
 * is then read back into a separate buffer.  As a basic sanity check, the
 * original write-buffer values are compared with values read from the slave to
 * a separate buffer.  An LED on the development board is illuminated when there
 * is a match between the written and read data.
 *
 * \return Nothing.
 */
int main(void)
{
  /* Initialize the common clock service, board-specific initialization, and
   * interrupt vector support prior to using the TWI master interfaces.
   */
  sysclk_init();

  board_init();

#if (!SAM && !MEGA)
  irq_initialize_vectors();
#endif // SAM

  // TWI master initialization options.

  twi_master_options_t opt;
#if SAM
  memset((void *)&opt, 0, sizeof(opt));
#endif
  opt.speed = TWI_SPEED;
#if (!SAM4L)
  opt.chip  = EEPROM_BUS_ADDR;
#endif

  // Initialize the TWI master driver.

  twi_master_setup(TWI_EXAMPLE, &opt);

  // Initialize the platform LED's.
#if defined(sam4cek)
  LED_Off(LED0);
#elif defined(sam4cmpdb) || defined(sam4cmsdb)
  LED_Off(LED4);
#else
  LED_Off(LED0_GPIO);
#endif

  twi_package_t packet = {
/**
 * The SAM3X_EK, SAM3X Arduino board and SAM4C_EK use two bytes length internal
 * address EEPROM.
 */
#if defined(sam3xek) || defined(arduinoduex) || defined(sam4cek) || defined(sam4cmpdb) || defined(sam4cmsdb)
    .addr[0]      = EEPROM_MEM_ADDR >> 8, // TWI slave memory address data MSB
    .addr[1]      = EEPROM_MEM_ADDR,      // TWI slave memory address data LSB
    .addr_length  = sizeof (uint16_t),    // TWI slave memory address data size
#else
    .addr[0]      = EEPROM_MEM_ADDR,      // TWI slave memory address data MSB
    .addr_length  = sizeof (uint8_t),     // TWI slave memory address data size
#endif
    .chip         = EEPROM_BUS_ADDR,      // TWI slave bus address
    .buffer       = (void *)test_pattern, // transfer data source buffer
    .length       = PATTERN_TEST_LENGTH   // transfer data size (bytes)
  };

  // Perform a multi-byte write access then check the result.
  while (twi_master_write(TWI_EXAMPLE, &packet) != TWI_SUCCESS);

  uint8_t data_received[PATTERN_TEST_LENGTH] = {0};

  twi_package_t packet_received = {
#if defined(sam3xek) || defined(arduinoduex) || defined(sam4cek) || defined(sam4cmpdb) || defined(sam4cmsdb)
    .addr[0]      = EEPROM_MEM_ADDR >> 8, // TWI slave memory address data MSB
    .addr[1]      = EEPROM_MEM_ADDR,      // TWI slave memory address data LSB
    .addr_length  = sizeof (uint16_t),    // TWI slave memory address data size
#else
    .addr[0]      = EEPROM_MEM_ADDR,      // TWI slave memory address data MSB
    .addr_length  = sizeof (uint8_t),     // TWI slave memory address data size
#endif
    .chip         = EEPROM_BUS_ADDR,      // TWI slave bus address
    .buffer       = data_received,        // transfer data destination buffer
    .length       = PATTERN_TEST_LENGTH   // transfer data size (bytes)
  };

  // Perform a multi-byte read access then check the result.
  while (twi_master_read(TWI_EXAMPLE, &packet_received) != TWI_SUCCESS);

  // Verify that the received data matches the sent data.
  for (uint32_t i = 0 ; i < PATTERN_TEST_LENGTH; ++i) {

    if (data_received[i] != test_pattern[i]) {
      // Error
      while(1);
    }
  }

  //test PASS
#if SAM4C
  LED_On(LED0);
#elif defined(sam4cmpdb) || defined(sam4cmsdb)
  LED_On(LED4);
#else
  LED_On(LED0_GPIO);
#endif

  while(1);
}
/*! \brief TWI Master Example Main
 *
 * The master example begins by initializing required board resources.  The
 * system clock, basic GPIO pin mapping, and interrupt vectors are established.
 *
 * A memory location on a TWI slave is written with a fixed test pattern which
 * is then read back into a separate buffer.  As a basic sanity check, the
 * original write-buffer values are compared with values read from the slave to
 * a separate buffer.  An LED on the development board is illuminated when there
 * is a match between the written and read data.
 *
 * \return Nothing.
 */
int main(void)
{
  /* Initialize the common clock service, board-specific initialization, and
   * interrupt vector support prior to using the TWI master interfaces.
   */
  sysclk_init();

  board_init();

#if !SAM
  irq_initialize_vectors();
#endif // SAM

  // TWI master initialization options.

  twi_master_options_t opt = {
    .speed = TWI_SPEED,
    .chip  = EEPROM_BUS_ADDR
  };

  // Initialize the TWI master driver.

  twi_master_setup(TWI_EXAMPLE, &opt);

  // Initialize the platform LED's.

  LED_Off(LED0_GPIO);

  twi_package_t packet = {
#if SAM
    .addr[0]      = EEPROM_MEM_ADDR >> 8, // TWI slave memory address data MSB
    .addr[1]      = EEPROM_MEM_ADDR,      // TWI slave memory address data LSB
    .addr_length  = sizeof (uint16_t),    // TWI slave memory address data size
#else
    .addr[0]      = EEPROM_MEM_ADDR,      // TWI slave memory address data MSB
    .addr_length  = sizeof (uint8_t),     // TWI slave memory address data size
#endif
    .chip         = EEPROM_BUS_ADDR,      // TWI slave bus address
    .buffer       = (void *)test_pattern, // transfer data source buffer
    .length       = PATTERN_TEST_LENGTH   // transfer data size (bytes)
  };

  // Perform a multi-byte write access then check the result.
  while (twi_master_write(TWI_EXAMPLE, &packet) != TWI_SUCCESS);

  uint8_t data_received[PATTERN_TEST_LENGTH] = {0};

  twi_package_t packet_received = {
#if SAM
    .addr[0]      = EEPROM_MEM_ADDR >> 8, // TWI slave memory address data MSB
    .addr[1]      = EEPROM_MEM_ADDR,      // TWI slave memory address data LSB
    .addr_length  = sizeof (uint16_t),    // TWI slave memory address data size
#else
    .addr[0]      = EEPROM_MEM_ADDR,      // TWI slave memory address data MSB
    .addr_length  = sizeof (uint8_t),     // TWI slave memory address data size
#endif
    .chip         = EEPROM_BUS_ADDR,      // TWI slave bus address
    .buffer       = data_received,        // transfer data destination buffer
    .length       = PATTERN_TEST_LENGTH   // transfer data size (bytes)
  };

  // Perform a multi-byte read access then check the result.
  while (twi_master_read(TWI_EXAMPLE, &packet_received) != TWI_SUCCESS);

  // Verify that the received data matches the sent data.
  for (uint32_t i = 0 ; i < PATTERN_TEST_LENGTH; ++i) {

    if (data_received[i] != test_pattern[i]) {
      // Error
      while(1);
    }
  }

  //test PASS
  LED_On(LED0_GPIO);

  while(1);
}
/**
 * \brief Application entry point for AT24CXX Component Example.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint32_t i;
	twi_options_t opt;

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

	/* Initialize the board */
	board_init();

	/* Turn off LEDs */
	ioport_set_pin_level(LED0_GPIO, LED0_INACTIVE_LEVEL);
	ioport_set_pin_level(LED1_GPIO, LED1_INACTIVE_LEVEL);

	/* Initialize the console UART */
	configure_console();

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

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

	if (twi_master_setup(BOARD_AT24C_TWI_INSTANCE, &opt) != TWI_SUCCESS) {
		puts("AT24CXX initialization is failed.\r");
		ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
		ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
		while (1) {
			/* Capture error */
		}
	}

	/* Fill EEPROM with memory pattern */
	if (at24cxx_fill_pattern(AT24C_MEM_ADDR,
			AT24C_MEM_ADDR + TEST_DATA_LENGTH - 1,
			MEMORY_PATTERN) != AT24C_WRITE_SUCCESS) {
		puts("AT24CXX pattern fill is failed.\r");
		ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
		ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
		while (1) {
			/* Capture error */
		}
	}

	if (at24cxx_read_continuous(AT24C_MEM_ADDR, TEST_DATA_LENGTH,
			test_data_rx) != AT24C_READ_SUCCESS) {
		puts("AT24CXX read packet is failed.\r");
		ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
		ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
		while (1) {
			/* Capture error */
		}
	}

	/* Compare the sent and the received */
	for (i = 0; i < TEST_DATA_LENGTH; i++) {
		if (MEMORY_PATTERN != test_data_rx[i]) {
			/* No match */
			puts("Pattern comparison: Unmatched!\r");
			ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
			ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
			while (1) {
				/* Capture error */
			}
		}
	}
	puts("Pattern comparison: Matched!\r");

	/* Send test pattern to EEPROM */
	if (at24cxx_write_continuous(AT24C_MEM_ADDR, TEST_DATA_LENGTH,
			test_data_tx) != AT24C_WRITE_SUCCESS) {
		puts("AT24CXX write packet is failed.\r");
		ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
		ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
		while (1) {
			/* Capture error */
		}
	}

	/* Get memory from EEPROM */
	if (at24cxx_read_continuous(AT24C_MEM_ADDR, TEST_DATA_LENGTH,
			test_data_rx) != AT24C_READ_SUCCESS) {
		puts("AT24CXX read packet is failed.\r");
		ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
		ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
		while (1) {
			/* Capture error */
		}
	}

	/* Compare the sent and the received */
	for (i = 0; i < TEST_DATA_LENGTH; i++) {
		if (test_data_tx[i] != test_data_rx[i]) {
			/* No match */
			puts("Data comparison: Unmatched!\r");
			ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
			ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
			while (1) {
				/* Capture error */
			}
		}
	}
	/* Match */
	puts("Data comparison: Matched!\r");

	/* Page Operation */
	for (i = 0; i < PAGE_SIZE; i++) {
		page_read_buf[i] = 0;
		page_write_buf[i] = i;
	}

	if (at24cxx_write_page(PAGE_ADDR, PAGE_SIZE, page_write_buf) !=
			AT24C_WRITE_SUCCESS) {
		puts("AT24CXX page write is failed.\r");
		ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
		ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
		while (1) {
			/* Capture error */
		}
	}

	if (at24cxx_read_page(PAGE_ADDR, PAGE_SIZE, page_read_buf) !=
			AT24C_READ_SUCCESS) {
		puts("AT24CXX page read is failed.\r");
		ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
		ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
		while (1) {
			/* Capture error */
		}
	}

	for (i = 0; i < PAGE_SIZE; i++) {
		if (page_read_buf[i] != page_write_buf[i]) {
			/* No match */
			puts("Page comparison: Unmatched!\r");
			ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);
			ioport_set_pin_level(LED1_GPIO, LED1_ACTIVE_LEVEL);
			while (1) {
				/* Capture error */
			}
		}
	}
	/* Match */
	puts("Page comparison: Matched!\r");
	while (1) {
	}
}