예제 #1
0
uint8_t I2C::read(uint8_t address, uint8_t registerAddress, uint8_t numberBytes, uint8_t *dataBuffer)
{
  bytesAvailable = 0;
  bufferIndex = 0;
  if(numberBytes == 0){numberBytes++;}
  nack = numberBytes - 1;
  returnStatus = 0;
  returnStatus = start();
  if(returnStatus){return(returnStatus);}
  returnStatus = sendAddress(SLA_W(address));
  if(returnStatus)
  {
    if(returnStatus == 1){return(2);}
    return(returnStatus);
  }
  returnStatus = sendByte(registerAddress);
  if(returnStatus)
  {
    if(returnStatus == 1){return(3);}
    return(returnStatus);
  }
  returnStatus = start();
  if(returnStatus)
  {
    if(returnStatus == 1){return(4);}
    return(returnStatus);
  }
  returnStatus = sendAddress(SLA_R(address));
  if(returnStatus)
  {
    if(returnStatus == 1){return(5);}
    return(returnStatus);
  }
  for(uint8_t i = 0; i < numberBytes; i++)
  {
    if( i == nack )
    {
      returnStatus = receiveByte(0);
      if(returnStatus == 1){return(6);}
      if(returnStatus != MR_DATA_NACK){return(returnStatus);}
    }
    else
    {
      returnStatus = receiveByte(1);
      if(returnStatus == 1){return(6);}
      if(returnStatus != MR_DATA_ACK){return(returnStatus);}
    }
    dataBuffer[i] = TWDR;
    bytesAvailable = i+1;
    totalBytes = i+1;
  }
  returnStatus = stop();
  if(returnStatus)
  {
    if(returnStatus == 1){return(7);}
    return(returnStatus);
  }
  return(returnStatus);
}
예제 #2
0
uint8_t I2C::write(uint8_t address, uint8_t registerAddress, uint8_t *data, uint8_t numberBytes)
{
  returnStatus = 0;
  returnStatus = start();
  if(returnStatus){return(returnStatus);}
  returnStatus = sendAddress(SLA_W(address));
  if(returnStatus)
  {
    if(returnStatus == 1){return(2);}
    return(returnStatus);
  }
  returnStatus = sendByte(registerAddress);
  if(returnStatus)
  {
    if(returnStatus == 1){return(3);}
    return(returnStatus);
  }
  for (uint8_t i = 0; i < numberBytes; i++)
  {
    returnStatus = sendByte(data[i]);
    if(returnStatus)
      {
        if(returnStatus == 1){return(3);}
        return(returnStatus);
      }
  }
  returnStatus = stop();
  if(returnStatus)
  {
    if(returnStatus == 1){return(7);}
    return(returnStatus);
  }
  return(returnStatus);
}
예제 #3
0
uint8_t I2C::write(uint8_t address, uint8_t registerAddress, uint8_t data)
{
  returnStatus = 0;
  returnStatus = start(); 
  if(returnStatus){return(returnStatus);}
  returnStatus = sendAddress(SLA_W(address));
  if(returnStatus)
  {
    if(returnStatus == 1){return(2);}
    return(returnStatus);
  }
  returnStatus = sendByte(registerAddress);
  if(returnStatus)
  {
    if(returnStatus == 1){return(3);}
    return(returnStatus);
  }
  returnStatus = sendByte(data);
  if(returnStatus)
  {
    if(returnStatus == 1){return(3);}
    return(returnStatus);
  }
  returnStatus = stop();
  if(returnStatus)
  {
    if(returnStatus == 1){return(7);}
    return(returnStatus);
  }
  return(returnStatus);
}
예제 #4
0
파일: stm32boot.c 프로젝트: swetland/m3dev
int jumpToAddress(int fd, unsigned addr)
{
	if (sendCommand(fd, 0x21))
		return -1;
	if (sendAddress(fd, addr))
		return -1;
	return 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)
{
    /* Set direction to send for sending of address and data. */
    uint8_t result = (uint8_t)getWriteError();
    if(result != 0)
    {
        // reset tx buffer iterator vars
        txBufferIndex = 0;
        txBufferLength = 0;
        // indicate that we are done transmitting
        transmitting_master = false;
        return 1;
    }

    uint32_t t0 = millis();

    while(I2C_HAL_GetStatusFlag(instance, kI2CBusBusy) && !I2C_HAL_IsMaster(instance))
    {
        if(millis() - t0 >= 25)
            return 4; //timeout
    }

    uint16_t slaveAddress;
    slaveAddress = (txAddress << 1U) & 0x00FFU;
    bool sent = sendAddress(slaveAddress);
    //tx buffer also sent by interrupt

    // reset tx buffer iterator vars
    txBufferIndex = 0;
    txBufferLength = 0;
    // indicate that we are done transmitting
    transmitting_master = false;
    clearWriteError();

    result = 4;

    if(sent) //sent without timeout
    {
        if(master_state == MASTER_STATE_COMPLETE)
        {
            result = 0;
        }
        else if(master_state == MASTER_STATE_TX_NAK) //failed
        {
            result = (txBufferIndex == 0) ? 2 : 3; //address or data fail
            sendStop = true;
        }

        if(sendStop)
        {
            I2C_HAL_SendStop(instance);
        }
    }
    I2C_HAL_SetDirMode(instance, kI2CReceive);

    return result;
}
예제 #6
0
파일: I2C.cpp 프로젝트: bubgum/crw-cmu
uint8_t I2C::beginTransmission(uint8_t address)
{
  returnStatusWire = 0;
  returnStatus = 0;
  returnStatus = start();
  returnStatusWire = returnStatus;
  if(returnStatus){return(returnStatus);}
  returnStatus = sendAddress(SLA_W(address));
  returnStatusWire = returnStatus;
  return(returnStatus);
}
예제 #7
0
파일: stm32boot.c 프로젝트: swetland/m3dev
int writeMemory(int fd, unsigned addr, void *ptr, int len)
{
	unsigned char *data = ptr;
	while (len > 0) {
		int xfer = (len > 256) ? 256 : len;
		if (sendCommand(fd, 0x31))
			return -1;
		if (sendAddress(fd, addr))
			return -1;
		if (sendData(fd, data, xfer))
			return -1;
		data += xfer;
		len -= xfer;
		addr += xfer;
	}
	return 0;
}
예제 #8
0
파일: stm32boot.c 프로젝트: swetland/m3dev
int readMemory(int fd, unsigned addr, void *ptr, int len)
{
	unsigned char *data = ptr;
	while (len > 0) {
		int xfer = (len > 256) ? 256 : len;
		fprintf(stderr,"read %04x at %08x -> %p\n", xfer, addr, data);
		if (sendCommand(fd, 0x11))
			return -1;
		if (sendAddress(fd, addr))
			return -1;
		if (sendLength(fd, xfer))
			return -1;
		if (readData(fd, data, xfer))
			return -1;
		data += xfer;
		len -= xfer;
		addr += xfer;
	}
	return 0;
}
예제 #9
0
int I2C::ping(uint8_t addr)
{
    returnStatus = 0;
    returnStatus = start();
    if (!returnStatus)
    { 
      returnStatus = sendAddress(SLA_W(addr));
    }
    if (returnStatus)
    {
      if(returnStatus == 1)
      {
        return -1;
      } else
      {
        return 0;               // no response
      }
    }
    stop();

    return 1;
}
예제 #10
0
파일: I2C.cpp 프로젝트: qqli/EC544_Group9
void I2C::scan()
{
    uint16_t tempTime = timeOutDelay;
    timeOut(80);
    uint8_t totalDevicesFound = 0;
    Serial.println("Scanning for devices...please wait");
    Serial.println();
    for(uint8_t s = 0; s <= 0x7F; s++)
    {
        returnStatus = 0;
        returnStatus = start();
        if(!returnStatus)
        {
            returnStatus = sendAddress(SLA_W(s));
        }
        if(returnStatus)
        {
            if(returnStatus == 1)
            {
                Serial.println("There is a problem with the bus, could not complete scan");
                timeOutDelay = tempTime;
                return;
            }
        }
        else
        {
            Serial.print("Found device at address - ");
            Serial.print(" 0x");
            Serial.println(s,HEX);
            totalDevicesFound++;
        }
        stop();
    }
    if(!totalDevicesFound) {
        Serial.println("No devices found");
    }
    timeOutDelay = tempTime;
}
예제 #11
0
uint8_t I2C::write(uint8_t address, uint16_t registerAddress, uint8_t data, boolean mode)
{
  returnStatus = 0;
  returnStatus = start(); 
  if(returnStatus){return(returnStatus);}
  returnStatus = sendAddress(SLA_W(address));
  if(returnStatus)
  {
    if(returnStatus == 1){return(2);}
    return(returnStatus);
  }
  if (!mode) returnStatus = sendByte(registerAddress);
  else 
    {
      returnStatus = sendByte((registerAddress >> 8) & 0x00FF);
      returnStatus = sendByte(registerAddress & 0x00FF);
    }
  if(returnStatus)
  {
    if(returnStatus == 1){return(3);}
    return(returnStatus);
  }
  returnStatus = sendByte(data);
  if(returnStatus)
  {
    if(returnStatus == 1){return(3);}
    return(returnStatus);
  }
  returnStatus = stop();
  if(returnStatus)
  {
    if(returnStatus == 1){return(7);}
    return(returnStatus);
  }
  return(returnStatus);
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
    if(quantity == 0) return 0;

    uint32_t t0 = millis();

    while(I2C_HAL_GetStatusFlag(instance, kI2CBusBusy) && !I2C_HAL_IsMaster(instance))
    {
        if(millis() - t0 >= 25)
            return 4; //timeout
    }

    if(quantity > BUFFER_LENGTH){
        quantity = BUFFER_LENGTH;
    }

    rxBufferQuantity = quantity;
    rxBufferIndex = 0;
    rxBufferLength = 0;

    uint16_t slaveAddr = (address << 1U) | 1;

    if(!sendAddress(slaveAddr) || master_state != MASTER_STATE_READ_READY)
    {
        I2C_HAL_SendStop(instance);
        I2C_HAL_SetDirMode(instance, kI2CReceive);
        return 0;
    }

    master_send_stop = sendStop;

    master_state = MASTER_STATE_IDLE;

    I2C_HAL_SetDirMode(instance, kI2CReceive);

    /* Send NAK if only one byte to read. */
    if (rxBufferQuantity == 0x1U)
    {
        I2C_HAL_SendNak(instance);
    }
    else
    {
        I2C_HAL_SendAck(instance);
    }

    I2C_HAL_ReadByte(instance);

    t0 = millis();

    while(master_state == MASTER_STATE_IDLE)
    {
        if(millis() - t0 >= 25)
        {
            rxBufferIndex = 0;
            rxBufferLength = 0;
            I2C_HAL_SendStop(instance);
            I2C_HAL_SetDirMode(instance, kI2CReceive);
            return 0; //timeout
        }
    }

    if(master_state == MASTER_STATE_COMPLETE)
    {
        rxBufferIndex = 0;
        return rxBufferLength;
    }
    else
    {
        rxBufferIndex = 0;
        rxBufferLength = 0;
        rxBufferQuantity = 0;
        I2C_HAL_SendStop(instance);
        I2C_HAL_SetDirMode(instance, kI2CReceive);
        return 0; //timeout
    }
}
예제 #13
0
void i2cCheckPort(i2cPortData *pPort)
{
    switch(pPort->i2cState)
    {
        case I2C_STATE_START:
            if(!pPort->pConBits->SEN)
            {   // start done - send a read or write address
                sendAddress(pPort);
            }
            break;

        case I2C_STATE_ADDR:
            if(!pPort->pStatBits->TRSTAT)
            {   // address send done - did the device ack?
                if(!pPort->pStatBits->ACKSTAT)
                {   // device ack'd
                    if(pPort->writeSize)
                    {   // start writing
                        writeNextByte(pPort);
                    }
                    else
                    {   // start reading
                        readNextByte(pPort);
                    }
                }
                else
                {   // no ack - do a stop and give up
                    noAck(pPort);
                }
            }
            break;

        case I2C_STATE_WRITE:
            if(!pPort->pStatBits->TRSTAT)
            {   // write done - did the device ack?
                if(!pPort->pStatBits->ACKSTAT)
                { 
                    if(pPort->i2cIndex < pPort->writeSize)
                    {
                        writeNextByte(pPort);
                    }
                    else
                    {   // done writing - might need to read
                        if(pPort->readSize)
                        {   // repeat start
                            pPort->pConBits->RSEN = 1;
                            pPort->i2cState = I2C_STATE_R_START;
                        }
                        else
                        {
                            i2cStop(pPort);
                        }
                    }
                }
                else
                {
                    noAck(pPort);
                }
            }
            break;

        case I2C_STATE_R_START:
            if(!pPort->pConBits->RSEN)
            {   // Repeat start done - back to the address
                pPort->writeSize = 0;  // force a read
                sendAddress(pPort);
            }
            break;

        case I2C_STATE_READ:
            if(!pPort->pConBits->RCEN)
            {   // done reading, now do ack
                pPort->readBuffer[pPort->i2cIndex] = *pPort->pRxReg;
                pPort->i2cIndex++;
                pPort->pConBits->ACKDT = (pPort->i2cIndex == pPort->readSize);    // NACK on last byte
                pPort->pConBits->ACKEN = 1;
                pPort->i2cState = I2C_STATE_READ_ACK;
            }
            break;

        case I2C_STATE_READ_ACK:
            if(!pPort->pConBits->ACKEN)
            {   // done read ack
                if(pPort->i2cIndex >= pPort->readSize)
                {   // done receiving
                    i2cStop(pPort);
                }
                else
                {
                    readNextByte(pPort);
                }
            }
            break;

        case I2C_STATE_STOP:
            if(!pPort->pConBits->PEN)
            {   // stop condition done
                pPort->i2cState = I2C_STATE_IDLE;
                *pPort->pConReg  = I2CCON_OFF;       // Turn off the I2C
            }
            break;

        default:
            pPort->i2cState = I2C_STATE_IDLE;
            break;
    }
}