//
//	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) {
	uint8_t error = 0;
	// transmit buffer (blocking)
	DBG_PRINTF("vAHI_SiMasterWriteSlaveAddr %x\r\n", txAddress);
	vAHI_SiMasterWriteSlaveAddr(txAddress, false);
	DBG_PRINTF("bAHI_SiMasterSetCmdReg\r\n");

	bool ret = bAHI_SiMasterSetCmdReg(E_AHI_SI_START_BIT, E_AHI_SI_NO_STOP_BIT,
			                  E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
					  E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK);
	
	DBG_PRINTF("bAHI_SiPollTransferInProgress\r\n");
	while(bAHI_SiPollTransferInProgress()); /* wait while busy */
	/* check to see if we get an ACK back*/
	DBG_PRINTF("bAHI_SiPollRxNack\r\n");
	if(bAHI_SiPollRxNack())
		error = 2;	// error, got NACK on address transmit
	
	if (error == 0) {
		uint16_t sent = 0;
		while (sent < txBufferLength) {
			DBG_PRINTF("sent %d\n", txBuffer[sent]);
			vAHI_SiMasterWriteData8(txBuffer[sent++]);
			if(sent == (txBufferLength) ) {
				vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_STOP_BIT,
						 E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
						 E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK);
			}
			else {
				vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_NO_STOP_BIT,
						 E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
						 E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK);

			}
			while(bAHI_SiPollTransferInProgress()); /* wait while busy */
			/* check to see if we get an ACK back*/
			if(bAHI_SiPollRxNack()) {
				error = 3;	// error, got NACK during data transmmit
				vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_STOP_BIT,
						 E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE,
						 E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK);
			}

			DBG_PRINTF("sent done %d\n", sent);
		}
	}
	
	//if (error == 0) {
	//	TWI_Stop(twi);
	//	if (!TWI_WaitTransferComplete(twi, XMIT_TIMEOUT))
	//		error = 4;	// error, finishing up
	//}

	txBufferLength = 0;		// empty buffer
	status = MASTER_IDLE;
	return error;
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
	if (quantity > BUFFER_LENGTH)
		quantity = BUFFER_LENGTH;

	DBG_PRINTF("vAHI_SiMasterWriteSlaveAddr %x\r\n", address);
	vAHI_SiMasterWriteSlaveAddr(address, true);
	vAHI_SiSetCmdReg(E_AHI_SI_START_BIT, E_AHI_SI_NO_STOP_BIT,
			 E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
			 E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK);
	while(bAHI_SiPollTransferInProgress()); /* wait while busy */

	// perform blocking read into buffer
	int readed = 0;

	do {
		if(readed == (quantity-1) ) {
			vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_STOP_BIT,
					 E_AHI_SI_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE,
					 E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK);
		}
		else {
			vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_NO_STOP_BIT,
					 E_AHI_SI_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE,
					 E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK);
		}

		while(bAHI_SiPollTransferInProgress()); /* wait while busy */

		rxBuffer[readed++] = u8AHI_SiMasterReadData8();
		DBG_PRINTF("u8AHI_SiMasterReadData8 %x\r\n", rxBuffer[readed-1]);
	} while (readed < quantity);

	// set rx buffer iterator vars
	rxBufferIndex = 0;
	rxBufferLength = readed;

	return readed;
}
Esempio n. 3
0
PROCESS_THREAD(i2c_process, ev, data)
{
  static size_t i;
#if (DEBUG==1)
  static u32_t i2c_ticks;
#endif

  PROCESS_BEGIN();

  vAHI_SiRegisterCallback(i2c_irq);
  vAHI_SiConfigure(true,true,I2C_400KHZ_FAST_MODE);

  while ((transaction=list_pop(transactions)))
  {
#if (DEBUG==1)
    printf("i2c: to 0x%x start, %d written, %d read\n",
           transaction->addr, transaction->wrlen, transaction->rdlen);
    i2c_ticks = u32AHI_TickTimerRead();
#endif

    if (transaction->wrlen) {
      /* send slave address, start condition */
      vAHI_SiWriteData8(transaction->addr);
      vAHI_SiSetCmdReg(E_AHI_SI_START_BIT,     E_AHI_SI_NO_STOP_BIT,
                       E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
                       E_AHI_SI_SEND_ACK,      E_AHI_SI_NO_IRQ_ACK);
      PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL);
      if (i2c_status==FAIL) { /* we only test for ACK on the first byte! */
        if (transaction->cb) transaction->cb(false);
#if (DEBUG==1)
        printf("i2c: to 0x%x failed, %d written, %d read in %d ticks\n",
               transaction->addr, transaction->wrlen, transaction->rdlen,
               u32AHI_TickTimerRead() - i2c_ticks);
#endif
        continue;
      }
    }

    /* send wr data. If repeated_start and there is something to read, send no
     * stop condition, else send a stop condition on the last byte. */
    for (i=0; i<transaction->wrlen; i++) {
      vAHI_SiWriteData8(transaction->buf[i]);
      vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT,
                       (transaction->wrlen!=0) ? E_AHI_SI_NO_STOP_BIT : transaction->rdlen,
                       E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
                       E_AHI_SI_SEND_ACK,      E_AHI_SI_NO_IRQ_ACK);
      PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL);
      if (i2c_status==FAIL) { /* we only test for ACK on the first byte! */
        if (transaction->cb) transaction->cb(false);
#if (DEBUG==1)
        printf("i2c: to 0x%x failed, %d written, %d read in %d ticks\n",
               transaction->addr, transaction->wrlen, transaction->rdlen,
               (uint32_t) u32AHI_TickTimerRead() - i2c_ticks);
#endif
        continue;
      }
    }

    if (transaction->rdlen) {
      /* send slave addr, start condition */
      vAHI_SiWriteData8(transaction->addr|1);
      vAHI_SiSetCmdReg(E_AHI_SI_START_BIT,     E_AHI_SI_NO_STOP_BIT,
                       E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
                       E_AHI_SI_SEND_ACK,      E_AHI_SI_NO_IRQ_ACK);
      PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL);
    }

    /* read data, send stop condition on last byte, send nak on last byte when
     * end_of_transmission is set.*/
    for (i=0; i<transaction->rdlen; i++) {
      vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, i==transaction->rdlen-1,
                       E_AHI_SI_SLAVE_READ,   E_AHI_SI_NO_SLAVE_WRITE,
                       (i==transaction->rdlen-1) ? E_AHI_SI_SEND_NACK : E_AHI_SI_SEND_ACK,
                       E_AHI_SI_NO_IRQ_ACK);
      PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL);
      transaction->buf[transaction->wrlen+i] = u8AHI_SiReadData8();
    }

#if (DEBUG==1)
    printf("i2c: to 0x%x completed, %d written, %d read in %d ticks (rd:",
           transaction->addr, transaction->wrlen, transaction->rdlen,
           (u32_t) u32AHI_TickTimerRead() - i2c_ticks);
    for (i=0; i<transaction->rdlen+transaction->wrlen; i++)
      printf("0x%x,", transaction->buf[i]);
    printf(")\n");
#endif

    if (transaction->cb) transaction->cb(i2c_status==SUCCESS);
  }
  vAHI_SiConfigure(false,false,0);

  PROCESS_END();
}