Exemple #1
0
uint8_t ICACHE_FLASH_ATTR 
twi_writeTo(uint8_t address, uint8_t *buf, unsigned int len,
	    uint8_t sendStop)
{
	unsigned int i;
	if (!twi_write_start()) {
		serial_print("I2C: bus busy\r\n");
		return 4;
	}
	if (!twi_write_byte(((address << 1) | 0) & 0xFF)) {
		if (sendStop)
			twi_write_stop();
		serial_print("I2C: received NACK on transmit of address\r\n");
		return 2;
	}
	for (i = 0; i < len; i++) {
		if (!twi_write_byte(buf[i])) {
			if (sendStop)
				twi_write_stop();
			serial_print("I2C: received NACK on transmit of data\r\n");
			return 3;
		}
	}
	if (sendStop)
		twi_write_stop();
	i = 0;
	while (SDA_READ() == 0 && (i++) < 10) {
		SCL_LOW();
		twi_delay(twi_dcount);
		SCL_HIGH();
		twi_delay(twi_dcount);
	}
	return 0;
}
Exemple #2
0
void rtc_set_time (uint8_t h, uint8_t m, uint8_t s) {
	twi_send_start();
	twi_write_byte(RTC_ADDR & 0xFE);
	twi_write_byte(RTC_SEC_OFFSET);
	twi_write_byte(((s/10) << 4) | (s%10));
	twi_write_byte(((m/10) << 4) | (m%10));
	twi_write_byte(((h/10) << 4) | (h%10));
	twi_send_stop();
}
Exemple #3
0
/** Czyści rekord w logu
* @param logp wartość wskaźnika
*/
void log_clear_record (uint16_t logp) {
	twi_send_start();
	twi_write_byte(EXT_EEPROM_ADDR & 0xFE);
	twi_write_byte(FIRST_WORD(logp));
	twi_write_byte(SECOND_WORD(logp));
	twi_write_byte(UINT8_T_DISABLED);
	twi_send_stop();
	_delay_ms(LOG_WRITE_DELAY);
}
Exemple #4
0
/** Ustawia wskaźnik wpisu
* @param pointer wartość wskaźnika
*/
void log_write_pointer(uint16_t pointer) {
	twi_send_start();
	twi_write_byte(EXT_EEPROM_ADDR & 0xFE);
	twi_write_byte(FIRST_WORD(LOG_CONTROL_RECORD_NUMBER) + LOG_CONTROL_POINTER_LSB);
	twi_write_byte(SECOND_WORD(LOG_CONTROL_RECORD_NUMBER));
	twi_write_byte((uint8_t)pointer);
	twi_write_byte((uint8_t)(pointer >> 8));
	twi_send_stop();
	_delay_ms(LOG_WRITE_DELAY);
}
Exemple #5
0
void main()
{
  //clock_buffer test = {1,2,3,4,5,6,7};
  init();

  q = twi_write_byte(0,0);
  clock = rtc_read();
  q = twi_write_byte(7,( 0<<OUT | 1<<SQWE | 0<<RS1 | 0<<RS0 )); // Set DS1307 square wave output on, freq = 1Hz
  set_display(DISPLAY_TIME);
  while(1);
}
Exemple #6
0
/** Zwraca wskaźnik
* @return wartość wskaźnika
*/
uint16_t log_read_pointer(void) {
	uint16_t logp;
	twi_send_start();
	twi_write_byte(EXT_EEPROM_ADDR & 0xFE);
	twi_write_byte(FIRST_WORD(LOG_CONTROL_RECORD_NUMBER) + LOG_CONTROL_POINTER_LSB);
	twi_write_byte(SECOND_WORD(LOG_CONTROL_RECORD_NUMBER));
	twi_send_start();
	twi_write_byte(EXT_EEPROM_ADDR);
	twi_read_byte(TRUE);
	logp = twi_byte;
	twi_read_byte(FALSE);
	logp |= ((uint16_t)twi_byte) << 8;
	return logp;
}
Exemple #7
0
void rtc_get_time (void) {
	twi_send_start();
	twi_write_byte(RTC_ADDR & 0xFE);
	twi_write_byte(RTC_SEC_OFFSET);
	twi_send_start();
	twi_write_byte(RTC_ADDR);
	twi_read_byte(TRUE);
	seconds=((twi_byte&0x7f)>>4)*10 + (twi_byte&0xf);
	twi_read_byte(TRUE);
	minutes=((twi_byte&0x7f)>>4)*10 + (twi_byte&0xf);
	twi_read_byte(FALSE);
	hours=((twi_byte&0x3f)>>4)*10 + (twi_byte&0xf);
	twi_send_stop();
}
Exemple #8
0
uint8_t ICACHE_FLASH_ATTR 
twi_readFrom(uint8_t address, uint8_t *buf, unsigned int len,
	     uint8_t sendStop)
{
	unsigned int i;
	if (!twi_write_start()) {
		serial_print("I2C: bus busy\r\n");
		return 4;
	}
	if (!twi_write_byte(((address << 1) | 1) & 0xFF)) {
		if (sendStop)
			twi_write_stop();
		serial_print("I2C: received NACK on transmit of address\r\n");
		return 2;
	}
	for (i = 0; i < (len - 1); i++)
		buf[i] = twi_read_byte(false);
	buf[len - 1] = twi_read_byte(true);
	if (sendStop)
		twi_write_stop();
	i = 0;
	while (SDA_READ() == 0 && (i++) < 10) {
		SCL_LOW();
		twi_delay(twi_dcount);
		SCL_HIGH();
		twi_delay(twi_dcount);
	}
	return 0;
}
Exemple #9
0
uint8_t get_io (uint8_t addr) {
	twi_send_start();
	twi_write_byte(addr);
	twi_read_byte(FALSE);
	twi_send_stop();
	return twi_byte;
}
Exemple #10
0
void rtc_get_date (void) {
	twi_send_start();
	twi_write_byte(RTC_ADDR & 0xFE);
	twi_write_byte(RTC_DAY_OFFSET);
	twi_send_start();
	twi_write_byte(RTC_ADDR);
	twi_read_byte(TRUE);
	day=((twi_byte&0x3f)>>4)*10 + (twi_byte&0xf);
	twi_read_byte(TRUE);
	wday=twi_byte&0x07;
	twi_read_byte(TRUE);
	month=((twi_byte&0x1f)>>4)*10 + (twi_byte&0xf);
	twi_read_byte(FALSE);
	year=((twi_byte)>>4)*10 + (twi_byte&0xf);
	twi_send_stop();
}
Exemple #11
0
/**
 * \brief Notification about the start condition was sent.
 *
 * This function is a TWI Master start indication.
 *
 * \param none
 */
static void twi_master_start(void)
{
	uint8_t chip_add;

	if ((TWI_WRITE_IADDR_WRITE_DATA == master_transfer.state) || (TWI_WRITE_DATA ==
			master_transfer.state) || (TWI_WRITE_IADDR_READ_DATA ==
			master_transfer.state)) {
		chip_add = TWI_WRITE_ENABLE(master_transfer.pkg->chip);
		twi_write_byte(chip_add);
	} else if (TWI_READ_DATA == master_transfer.state) {
		chip_add = TWI_READ_ENABLE(master_transfer.pkg->chip);
		twi_write_byte(chip_add);
	} else { /* abnormal */
		twi_master_bus_reset();
		master_transfer.status = ERR_PROTOCOL;
	}
}
Exemple #12
0
/** Czyta wpis z loga
* @param logp wartość wskaźnika
* @param *pbuff wskaźnik do bufora, gdzie zostanie zapisany wpis
*/
void log_read_record_at_pointer(uint16_t logp,uint8_t *pbuff) {
	
	uint8_t i;
	
	twi_send_start();
	twi_write_byte(EXT_EEPROM_ADDR & 0xFE);
	twi_write_byte(FIRST_WORD(logp));
	twi_write_byte(SECOND_WORD(logp));
	twi_send_start();
	twi_write_byte(EXT_EEPROM_ADDR);
	for(i=0;i<LOG_BYTES_PER_RECORD-1;i++) { 	// 7 bajtów z potwierdzeniem
		twi_read_byte(TRUE);
		*pbuff++ = twi_byte;
	}
	twi_read_byte(FALSE);						// 1 bajt bez potwierdzenia
	*pbuff = twi_byte;
	twi_send_stop();
}
Exemple #13
0
/**
 * \brief Sending data to twi bus. If last byte then send stop condition.
 *
 * \param none.
 */
static void twi_master_data_write(void)
{
	if (master_transfer.data_count < master_transfer.pkg->length) {
		twi_write_byte(master_transfer.pkg->buffer[master_transfer.data_count++]);
	} else {
		twi_send_stop();
		master_transfer.state = TWI_IDLE;
		master_transfer.status = STATUS_OK;
		twi_master_busy = false;
	}
}
Exemple #14
0
unsigned char twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop){
  unsigned int i;
  if(!twi_write_start()) return 4;//line busy
  if(!twi_write_byte(((address << 1) | 0) & 0xFF)) {
    if (sendStop) twi_write_stop();
    return 2; //received NACK on transmit of address
  }
  for(i=0; i<len; i++) {
    if(!twi_write_byte(buf[i])) {
      if (sendStop) twi_write_stop();
      return 3;//received NACK on transmit of data
    }
  }
  if(sendStop) twi_write_stop();
  i = 0;
  while(SDA_READ() == 0 && (i++) < 10){
    SCL_LOW();
    twi_delay(twi_dcount);
    SCL_HIGH();
    unsigned int t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit
    twi_delay(twi_dcount);
  }
  return 0;
}
Exemple #15
0
void rtc_set_date (uint8_t y, uint8_t m, uint8_t d,uint8_t wd) {
	twi_send_start();
	twi_write_byte(RTC_ADDR & 0xFE);
	twi_write_byte(RTC_DAY_OFFSET);
	twi_write_byte(((d/10) << 4) | (d%10));
	twi_write_byte(wd);
	twi_write_byte(((m/10) << 4) | (m%10));
	twi_write_byte(((y/10) << 4) | (y%10));
	twi_send_stop();
}
Exemple #16
0
/**
 * \brief Sending internal device address to twi bus.
 *
 * \param none.
 */
static void twi_master_internal_addr_write(void)
{
	uint8_t data;

	data = master_transfer.pkg->addr[master_transfer.addr_count];
	master_transfer.addr_count++;
	twi_write_byte(data);

	if (master_transfer.pkg->addr_length == master_transfer.addr_count) {
		if (TWI_WRITE_IADDR_WRITE_DATA == master_transfer.state) {
			master_transfer.state = TWI_WRITE_DATA;
		} else {
			master_transfer.state = TWI_READ_DATA;
		}
	}
}
Exemple #17
0
//
//	Originally, 'endTransmission' was an f(void) function.
//	It has been modified to take one parameter indicating
//	whether or not a STOP should be performed on the bus.
//	Calling endTransmission(false) allows a sketch to
//	perform a repeated start.
//
//	WARNING: Nothing in the library keeps track of whether
//	the bus tenure has been properly ended with a STOP. It
//	is very possible to leave the bus in a hung state if
//	no call to endTransmission(true) is made. Some I2C
//	devices will behave oddly if they do not see a STOP.
//
uint8_t TwoWire::endTransmission(uint8_t sendStop) {
	// transmit buffer (blocking)
	TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]);
	TWI_WaitByteSent(twi, XMIT_TIMEOUT);
	int sent = 1;
	while (sent < txBufferLength) {
		twi_write_byte(twi, txBuffer[sent++]);
		TWI_WaitByteSent(twi, XMIT_TIMEOUT);
	}
	TWI_Stop( twi);
	TWI_WaitTransferComplete(twi, XMIT_TIMEOUT);

	// empty buffer
	txBufferLength = 0;

	status = MASTER_IDLE;
	return sent;
}
Exemple #18
0
unsigned char twi_readFrom(unsigned char address, unsigned char* buf, unsigned int len, unsigned char sendStop){
  unsigned int i;
  if(!twi_write_start()) return 4;//line busy
  if(!twi_write_byte(((address << 1) | 1) & 0xFF)) {
    if (sendStop) twi_write_stop();
    return 2;//received NACK on transmit of address
  }
  for(i=0; i<(len-1); i++) buf[i] = twi_read_byte(false);
  buf[len-1] = twi_read_byte(true);
  if(sendStop) twi_write_stop();
  i = 0;
  while(SDA_READ() == 0 && (i++) < 10){
    SCL_LOW();
    twi_delay(twi_dcount);
    SCL_HIGH();
    unsigned int t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit
    twi_delay(twi_dcount);
  }
  return 0;
}
Exemple #19
0
/**
 * \brief Starts a write operation on the TWI to access the selected slave, then
 *  returns immediately. A byte of data must be provided to start the write;
 * other bytes are written next.
 * after that to send the remaining bytes.
 * \param pTwi  Pointer to an Twi instance.
 * \param address  Address of slave to acccess on the bus.
 * \param iaddress  Optional slave internal address.
 * \param isize  Number of internal address bytes.
 * \param byte  First byte to send.
 */
static void TWI_StartWrite(
    Twi *pTwi,
    uint8_t address,
    uint32_t iaddress,
    uint8_t isize,
    uint8_t byte)
{
//	assert( pTwi != NULL ) ;
//	assert( (address & 0x80) == 0 ) ;
//	assert( (iaddress & 0xFF000000) == 0 ) ;
//	assert( isize < 4 ) ;

    /* Set slave address and number of internal address bytes. */
    pTwi->TWI_MMR = 0;
    pTwi->TWI_MMR = (isize << 8) | (address << 16);

    /* Set internal address bytes. */
    pTwi->TWI_IADR = 0;
    pTwi->TWI_IADR = iaddress;

    /* Write first byte to send.*/
    twi_write_byte(pTwi, byte);
}
Exemple #20
0
/** Wpisuje kolejne zdarzenie do logu we wskazanym przez wskaźnik miejscu.
* @param logp wskaźnik rekordu
* @param type typ wpisu
* @param val1 warotść 1
* @param val2 warotść 2
* @param val3 warotść 3
*/
void log_write_record_at_pointer(uint16_t logp,uint8_t type,uint8_t val1,uint8_t val2, uint8_t val3) {
	twi_send_start();
	twi_write_byte(EXT_EEPROM_ADDR & 0xFE);
	twi_write_byte(FIRST_WORD(logp));
	twi_write_byte(SECOND_WORD(logp));
	twi_write_byte(year);
	twi_write_byte( month << 4 | (type & 0x0F) );
	twi_write_byte(day);
	twi_write_byte(hours);
	twi_write_byte(minutes);
	twi_write_byte(val1);
	twi_write_byte(val2);
	twi_write_byte(val3);
	twi_send_stop();
	_delay_ms(LOG_WRITE_DELAY);
}
Exemple #21
0
void set_io (uint8_t addr,uint8_t byte) {
	twi_send_start();
	twi_write_byte(addr);
	twi_write_byte(byte);
	twi_send_stop();
}
Exemple #22
0
static inline void write8(uint8_t reg, uint8_t value){
	twi_write_byte(TCS34725_ADDRESS, (TCS34725_COMMAND_BIT | reg), value);
}
Exemple #23
0
void BOARD_TWI_Handler(void)
{
	uint32_t status;

	status = twi_get_interrupt_status(BOARD_BASE_TWI_SLAVE);

	if (((status & TWI_SR_SVACC) == TWI_SR_SVACC)
			&& (emulate_driver.uc_acquire_address == 0)) {
		twi_disable_interrupt(BOARD_BASE_TWI_SLAVE, TWI_IDR_SVACC);
		twi_enable_interrupt(BOARD_BASE_TWI_SLAVE, TWI_IER_RXRDY | TWI_IER_GACC
				| TWI_IER_NACK | TWI_IER_EOSACC | TWI_IER_SCL_WS);
		emulate_driver.uc_acquire_address++;
		emulate_driver.us_page_address = 0;
		emulate_driver.us_offset_memory = 0;
	}

	if ((status & TWI_SR_GACC) == TWI_SR_GACC) {
		puts("General Call Treatment\n\r");
		puts("not treated");
	}

	if (((status & TWI_SR_SVACC) == TWI_SR_SVACC) && ((status & TWI_SR_GACC) == 0)
			&& ((status & TWI_SR_RXRDY) == TWI_SR_RXRDY)) {

		if (emulate_driver.uc_acquire_address == 1) {
			/* Acquire MSB address */
			emulate_driver.us_page_address =
					(twi_read_byte(BOARD_BASE_TWI_SLAVE) & 0xFF) << 8;
			emulate_driver.uc_acquire_address++;
		} else {
			if (emulate_driver.uc_acquire_address == 2) {
				/* Acquire LSB address */
				emulate_driver.us_page_address |=
						(twi_read_byte(BOARD_BASE_TWI_SLAVE) & 0xFF);
				emulate_driver.uc_acquire_address++;
			} else {
				/* Read one byte of data from master to slave device */
				emulate_driver.uc_memory[emulate_driver.us_page_address +
					emulate_driver.us_offset_memory] =
						(twi_read_byte(BOARD_BASE_TWI_SLAVE) & 0xFF);

				emulate_driver.us_offset_memory++;
			}
		}
	} else {
		if (((status & TWI_SR_TXRDY) == TWI_SR_TXRDY)
				&& ((status & TWI_SR_TXCOMP) == TWI_SR_TXCOMP)
				&& ((status & TWI_SR_EOSACC) == TWI_SR_EOSACC)) {
			/* End of transfer, end of slave access */
			emulate_driver.us_offset_memory = 0;
			emulate_driver.uc_acquire_address = 0;
			emulate_driver.us_page_address = 0;
			twi_enable_interrupt(BOARD_BASE_TWI_SLAVE, TWI_SR_SVACC);
			twi_disable_interrupt(BOARD_BASE_TWI_SLAVE,
					TWI_IDR_RXRDY | TWI_IDR_GACC |
					TWI_IDR_NACK | TWI_IDR_EOSACC | TWI_IDR_SCL_WS);
		} else {
			if (((status & TWI_SR_SVACC) == TWI_SR_SVACC)
					&& ((status & TWI_SR_GACC) == 0)
					&& (emulate_driver.uc_acquire_address == 3)
					&& ((status & TWI_SR_SVREAD) == TWI_SR_SVREAD)
					&& ((status & TWI_SR_NACK) == 0)) {
				/* Write one byte of data from slave to master device */
				twi_write_byte(BOARD_BASE_TWI_SLAVE,
						emulate_driver.uc_memory[emulate_driver.us_page_address
						+ emulate_driver.us_offset_memory]);
				emulate_driver.us_offset_memory++;
			}
		}
	}
}
/**
 * \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;
}
Exemple #25
0
void TwoWire::onService(void) {
	// Retrieve interrupt status
	uint32_t sr = twi_get_interrupt_status(twi);

	if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) {
		twi_disable_interrupt(twi, TWI_IDR_SVACC);
		twi_enable_interrupt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK
				| TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP);

		srvBufferLength = 0;
		srvBufferIndex = 0;

		// Detect if we should go into RECV or SEND status
		// SVREAD==1 means *master* reading -> SLAVE_SEND
		if (!TWI_STATUS_SVREAD(sr)) {
			status = SLAVE_RECV;
		} else {
			status = SLAVE_SEND;

			// Alert calling program to generate a response ASAP
			if (onRequestCallback)
				onRequestCallback();
			else
				// create a default 1-byte response
				write((uint8_t) 0);
		}
	}

	if (status != SLAVE_IDLE) {
		if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) {
			if (status == SLAVE_RECV && onReceiveCallback) {
				// Copy data into rxBuffer
				// (allows to receive another packet while the
				// user program reads actual data)
				for (uint8_t i = 0; i < srvBufferLength; ++i)
					rxBuffer[i] = srvBuffer[i];
				rxBufferIndex = 0;
				rxBufferLength = srvBufferLength;

				// Alert calling program
				onReceiveCallback( rxBufferLength);
			}

			// Transfer completed
			twi_enable_interrupt(twi, TWI_SR_SVACC);
			twi_disable_interrupt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
					| TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
			status = SLAVE_IDLE;
		}
	}

	if (status == SLAVE_RECV) {
		if (TWI_STATUS_RXRDY(sr)) {
			if (srvBufferLength < BUFFER_LENGTH)
			{
				srvBuffer[srvBufferLength++] = twi_read_byte(twi);
			}
		}
	}

	if (status == SLAVE_SEND) {
		if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) {
			uint8_t c = 'x';
			if (srvBufferIndex < srvBufferLength)
			{
				c = srvBuffer[srvBufferIndex++];
			}
			twi_write_byte(twi, c);
		}
	}
}
Exemple #26
0
__interrupt void INT_timer1_comp_A(void)
{
  TCNT1 = 0x00;
  keyboard = PINC & 0x0F;
  
  if(keyboard == 0x0F)
  {
    set_display(DISPLAY_TIME);
    OCR1A = keyboard_poll;
  }
  else
  {
    OCR1A = keyboard_delay;
    switch(keyboard)
    {
      case 0x0E:  // date button pressed
        set_display(DISPLAY_DATE);
        break;
        
      case 0x0D:
        set_display(DISPLAY_TIME);
        clock.hours = bcd_inc(clock.hours);
        if(clock.hours == 0x24)
          clock.hours = 0;
        q = twi_write_byte(2,clock.hours);
        break;

      case 0x0B:
        set_display(DISPLAY_TIME);
        clock.minutes = bcd_inc(clock.minutes);
        if(clock.minutes == 0x60)
          clock.minutes = 0;
        q = twi_write_byte(1,clock.minutes);
        break;
        
      case 0x0C:
        set_display(DISPLAY_DATE);
        clock.date = bcd_inc(clock.date);
        switch(clock.month)
        {
          case 0x01: case 0x03: case 0x05: case 0x07: case 0x08: case 0x10: case 0x12:
            if(clock.date == 0x32)
              clock.date = 1;
            break;
          case 0x04: case 0x06: case 0x09: case 0x11:
            if(clock.date == 0x31)
              clock.date = 1;
            break;
          default :
            if(clock.date == 0x29)
              clock.date = 1;
            break;
        }
        q = twi_write_byte(4,clock.date);
        break;
        
      case 0x0A:
        set_display(DISPLAY_DATE);
        clock.month = bcd_inc(clock.month);
        if(clock.month == 0x13)
          clock.month = 1;
        q = twi_write_byte(5,clock.month);
        break;

      default :
        break;
    }
  }
}
/** \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;
}