/** * \brief Asynchronously reads data from a slave on the TWI bus. An optional * callback function is triggered when the transfer is complete. * \param pTwid Pointer to a Twid instance. * \param address TWI slave address. * \param iaddress Optional slave internal address. * \param isize Internal address size in bytes. * \param pData Data buffer for storing received bytes. * \param num Number of bytes to read. * \param pAsync Asynchronous transfer descriptor. * \return 0 if the transfer has been started; otherwise returns a TWI error code. */ uint8_t TWID_Read( Twi *pTwi, uint8_t address, uint32_t iaddress, uint8_t isize, uint8_t *pData, uint32_t num) { //Twi *pTwi; uint32_t timeout; assert( pTwi != NULL ) ; assert( (address & 0x80) == 0 ) ; assert( (iaddress & 0xFF000000) == 0 ) ; assert( isize < 4 ) ; /* Set STOP signal if only one byte is sent*/ if (num == 1) { TWI_Stop(pTwi); } /* Synchronous transfer*/ /* Start read*/ TWI_StartRead(pTwi, address, iaddress, isize); /* Read all bytes, setting STOP before the last byte*/ while (num > 0) { /* Last byte ?*/ if (num == 1) { TWI_Stop(pTwi); } /* Wait for byte then read and store it*/ timeout = 0; while( !TWI_ByteReceived(pTwi) && (++timeout<TWITIMEOUTMAX) ); if (timeout == TWITIMEOUTMAX) { TRACE_ERROR("TWID Timeout BR\n\r"); } *pData++ = TWI_ReadByte(pTwi); num--; } /* Wait for transfer to be complete */ timeout = 0; while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) ); if (timeout == TWITIMEOUTMAX) { TRACE_ERROR("TWID Timeout TC\n\r"); } return 0; }
tStatus TWI_RegisterWrite(uint8_t u8addr, uint8_t u8data, uint8_t slaveAddress) { TWI_Start(); // send a start code to begin the write uint8_t status = TWI_GetStatus(); if (status != START && status != REP_START) // start not sent/acknowledged { //Serial.print("TWI Write failed, start not sent."); //Serial.print(" Status code is: 0x"); Serial.println(status,HEX); return ERROR; } TWI_Write( (slaveAddress<<1) ); // write the address shifted so that last bit is 0, meaning write request status = TWI_GetStatus(); if (status != MT_SLA_ACK) // SLA+W was not acknowledged { TWI_Stop(); // send a stop to end failed transmission //Serial.print("TWI Write failed, sla address not sent."); //Serial.print(" Status code is: 0x"); Serial.println(status,HEX); return ERROR; } TWI_Write(u8addr); // send the address to write to status = TWI_GetStatus(); if (status != MT_DATA_ACK) // the address was not sent { // Serial.print("TWI Write failed, register address not sent"); // Serial.print(" Status code is: 0x"); Serial.println(status,HEX); return ERROR; } TWI_Write(u8data); // send the data to write status = TWI_GetStatus(); if (status != MT_DATA_ACK) { // Serial.print("TWI Write failed, data not sent"); // Serial.print(" Status code is: 0x"); Serial.println(status,HEX); return ERROR; } TWI_Stop(); return SUCCESS; }
// // 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) TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]); if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT)) error = 2; // error, got NACK on address transmit if (error == 0) { uint16_t sent = 1; while (sent < txBufferLength) { TWI_WriteByte(twi, txBuffer[sent++]); if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT)) error = 3; // error, got NACK during data transmmit } } 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; }
void PCA9634_Init() { // Enable internal oscillator. TWI_Start(); TWI_Write(PCA9634_ADDRESS); TWI_Write(PCA9634_REG_MODE1); TWI_Write(0b00001); TWI_Stop(); TWI_Start(); TWI_Write(PCA9634_ADDRESS); TWI_Write(PCA9634_REG_LEDOUT0 | PCA9634_AI_ALL); TWI_Write(0b10101010); // Enable PWM mode for PWM0 to PWM3. TWI_Write(0b10101010); // Enable PWM mode for PWM4 to PWM7. TWI_Stop(); }
//-------------------------------------------------------------------------------------------------------------------- void TWI_wr(unsigned char Saddress,unsigned char SRegSet, unsigned char data) { TWI_Start(); TWI_SendSLAW(Saddress); TWI_TransmitData(SRegSet); TWI_TransmitData(data); TWI_Stop(); }
/** * @ Brief Starts illuminance measurement. * @ Parameter mode: measurement mode. * @ Retval None */ void BH1750_Start(uint8_t mode) { mode_ = mode; TWI_Start(); TWI_Write_SLA(BH1750_SLA); TWI_WriteByte(mode_); TWI_Stop(); }
void TWI_WRITEBYTE(unsigned char address, unsigned char data) { TWI_Start(); TWI_Write(MPU6050_ADR); TWI_Write(address); TWI_Write(data); TWI_Stop(); }
void TWI_WriteBytes(uint8_t SLA, uint8_t address ,uint8_t size, uint8_t* buffer) { TWI_Start(); TWI_Write_SLA(SLA); TWI_WriteByte(address); while (size--) TWI_WriteByte(*buffer++); TWI_Stop(); }
unsigned char Write24C64_Byte(unsigned char devAddr, unsigned int regAddr, unsigned char value) { TWI_Start(); TWI_Write(_WRITE_MODE(devAddr)); TWI_Write(regAddr>>8); TWI_Write(regAddr); TWI_Write(value); TWI_Stop(); }
//------------------------------------------------------------------------------ /// Interrupt handler for a TWI peripheral. Manages asynchronous transfer /// occuring on the bus. This function MUST be called by the interrupt service /// routine of the TWI peripheral if asynchronous read/write are needed. /// \param pTwid Pointer to a Twid instance. //------------------------------------------------------------------------------ void TWID_Handler(Twid *pTwid) { unsigned char status; AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer; AT91S_TWI *pTwi = pTwid->pTwi; SANITY_CHECK(pTwid); // Retrieve interrupt status status = TWI_GetMaskedStatus(pTwi); // Byte received if (TWI_STATUS_RXRDY(status)) { pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi); pTransfer->transferred++; // Transfer finished ? if (pTransfer->transferred == pTransfer->num) { TWI_DisableIt(pTwi, AT91C_TWI_RXRDY); TWI_EnableIt(pTwi, AT91C_TWI_TXCOMP); } // Last byte ? else if (pTransfer->transferred == (pTransfer->num - 1)) { TWI_Stop(pTwi); } } // Byte sent else if (TWI_STATUS_TXRDY(status)) { // Transfer finished ? if (pTransfer->transferred == pTransfer->num) { TWI_DisableIt(pTwi, AT91C_TWI_TXRDY); TWI_EnableIt(pTwi, AT91C_TWI_TXCOMP); TWI_SendSTOPCondition(pTwi); } // Bytes remaining else { TWI_WriteByte(pTwi, pTransfer->pData[pTransfer->transferred]); pTransfer->transferred++; } } // Transfer complete else if (TWI_STATUS_TXCOMP(status)) { TWI_DisableIt(pTwi, AT91C_TWI_TXCOMP); pTransfer->status = 0; if (pTransfer->callback) { pTransfer->callback((Async *) pTransfer); } pTwid->pTransfer = 0; } }
/** * @ Brief Switches the sensor to power down mode. * @ Parameter None. * @ Retval None */ void BH1750_PowerDown() { //BH1750_DVI_PORT &= ~(BH1750_Power_OFF << BH1750_DVI_PIN); state_ = BH1750_Power_OFF; TWI_Start(); TWI_Write_SLA(BH1750_SLA); TWI_WriteByte(BH1750_Power_OFF); TWI_Stop(); }
/** * @ Brief Switches the sensor to power on mode. * @ Parameter None. * @ Retval None */ void BH1750_PowerOn() { _delay_us(5); //BH1750_DVI_PORT |= BH1750_Power_ON << BH1750_DVI_PIN; state_ = BH1750_Power_ON; TWI_Start(); TWI_Write_SLA(BH1750_SLA); TWI_WriteByte(BH1750_Power_ON); TWI_Stop(); }
/** * @ Brief Resets the BH1750 data register. After that, switches * sensor to power down mode. * @ Parameter None. * @ Retval None. */ void BH1750_ResetDR() { if(state_ == BH1750_Power_OFF) BH1750_PowerOn(); TWI_Start(); TWI_Write_SLA(BH1750_SLA); TWI_WriteByte(BH1750_RESET); TWI_Stop(); BH1750_PowerDown(); }
int TWI_READBYTE(unsigned char address) { signed int data = 0x00; TWI_Start(); TWI_Write(MPU6050_ADR); TWI_Write(address); TWI_Start(); TWI_Write(MPU6050_ADR | 0x01); data = TWI_Read_NACK(); TWI_Stop(); return data; }
void PCF_Read(uint8_t addr, uint8_t *data, uint8_t count) { TWI_Start(); TWI_Write(PCF8563_WRITE_ADDR); TWI_Write(addr); TWI_Stop(); TWI_Start(); TWI_Write(PCF8563_READ_ADDR); while (count) { count--; *data = TWI_Read(count); data++; } TWI_Stop(); }
/* * Liest "2" Register (aufeinander folgende Register e.g.: 0x01, 0x02) */ short TWI_readRegister2(uint8_t i2cAdr, uint8_t regAdr) { uint8_t reply[4]; uint8_t n_Byte = 2; if (TWI_Start() == 0) { //Error uart_writeString("TWI Error Start"); uart_writeAbsatz(); } if (TWI_Write_Addr(i2cAdr, TW_WRITE) == 0) { //Error uart_writeString("TWI Error i2cAdr Write"); uart_writeAbsatz(); } if (TWI_Write_Func(regAdr) == 0) { //Error uart_writeString("TWI Error regAdr Write"); uart_writeAbsatz(); } TWI_Stop(); if (TWI_Start() == 0) { //Error uart_writeString("TWI Error Start"); uart_writeAbsatz(); } if (TWI_Write_Addr(i2cAdr, TW_READ) == 0) { //Error uart_writeString("TWI Error i2cAdr Write"); uart_writeAbsatz(); } if (TWI_Read(reply, n_Byte) == 0) { //Error uart_writeString("TWI Error Read Int"); uart_writeAbsatz(); } TWI_Stop(); return (short) reply[0] << 8 | reply[1]; }
/* * Liest "1" Register */ char TWI_readRegister(uint8_t i2cAdr, uint8_t regAdr) { uint8_t reply[3]; uint8_t n_Byte = 1; if (TWI_Start() == 0) { //Error uart_writeString("TWI Error Start"); uart_writeAbsatz(); } if (TWI_Write_Addr(i2cAdr, TW_WRITE) == 0) { //Error uart_writeString("TWI Error i2cAdr Write"); uart_writeAbsatz(); } if (TWI_Write_Func(regAdr) == 0) { //Error uart_writeString("TWI Error regAdr Write"); uart_writeAbsatz(); } TWI_Stop(); if (TWI_Start() == 0) { //Error uart_writeString("TWI Error Start"); uart_writeAbsatz(); } if (TWI_Write_Addr(i2cAdr, TW_READ) == 0) { //Error uart_writeString("TWI Error i2cAdr Read"); uart_writeAbsatz(); } if (TWI_Read(reply, n_Byte) == 0) { //Error uart_writeString("TWI Error Read Byte"); uart_writeAbsatz(); } TWI_Stop(); return reply[0]; }
//-------------------------------------------------------------------------------------------------------------------- unsigned char TWI_rd(unsigned char Saddress,unsigned char SRegSet) { unsigned char data; TWI_Start(); TWI_SendSLAW(Saddress); TWI_TransmitData(SRegSet); TWI_ReStart(); TWI_SendSLAR(Saddress); data = TWI_ReceiveData(); TWI_SendNoAck(); TWI_Stop(); return data; }
unsigned char Read24C64_Byte(unsigned char devAddr, unsigned int regAddr) { unsigned char val; TWI_Start(); TWI_Write(0b10100000);//_WRITE_MODE(devAddr)); TWI_Write(regAddr>>8); // MSB Byte first TWI_Write(regAddr); // LSB Byte afterward TWI_Start(); // Repeated start TWI_Write(0b10100001);//_READ_MODE(devAddr)); val = TWI_Read(0u); TWI_Stop(); return val; }
void TWI_readRegisterN(uint8_t i2cAdr, uint8_t regAdr,uint8_t reply[], uint8_t n_Byte) { // uint8_t n_Byte = 6; // uint8_t reply[8]; if (TWI_Start() == 0) { //Error uart_writeString("TWI Error Start"); uart_writeAbsatz(); } if (TWI_Write_Addr(i2cAdr, TW_WRITE) == 0) { //Error uart_writeString("TWI Error i2cAdr Write"); uart_writeAbsatz(); } if (TWI_Write_Func(regAdr) == 0) { //Error uart_writeString("TWI Error regAdr Write"); uart_writeAbsatz(); } TWI_Stop(); if (TWI_Start() == 0) { //Error uart_writeString("TWI Error Start"); uart_writeAbsatz(); } if (TWI_Write_Addr(i2cAdr, TW_READ) == 0) { //Error uart_writeString("TWI Error i2cAdr Write"); uart_writeAbsatz(); } if (TWI_Read(reply, n_Byte) == 0) { //Error uart_writeString("TWI Error Read Int"); uart_writeAbsatz(); } TWI_Stop(); }
void i2c_scan() { uint8_t ret; for(uint8_t i=1;i<128;i++) { TWI_Stop(); ret = i2c_start(i); if( ret == 0 ) { printf_P(PSTR("Found i2c device: %02X\n"),i); } else { printf_P(PSTR("NA: %02X Ret: %02X\n"),i, ret); } } }
void PCF_Write(uint8_t addr, uint8_t *data, uint8_t count) { TWI_Start(); TWI_Write(PCF8563_WRITE_ADDR); TWI_Write(addr); while (count) { count--; TWI_Write(*data); data++; } TWI_Stop(); }
// i2c_eeprom_master_read/write are based on twid.c from atmels at91lib and // adapted for better handling when there is no eeprom present. // This handling is needed for the bricklet initialization bool i2c_eeprom_master_read(Twi *twi, const uint16_t internal_address, char *data, const uint16_t length) { uint32_t timeout; mutex_take(mutex_twi_bricklet, MUTEX_BLOCKING); // Start read TWI_StartRead(twi, bricklet_eeprom_address, internal_address, I2C_EEPROM_INTERNAL_ADDRESS_BYTES); for(uint16_t i = 0; i < length; i++) { // If last Byte -> send STOP if(i == length-1) { TWI_Stop(twi); } uint32_t timeout = 0; // Wait until byte is received, otherwise return false while(!TWI_ByteReceived(twi) && (++timeout < I2C_EEPROM_TIMEOUT)); if(timeout == I2C_EEPROM_TIMEOUT) { logieew("read timeout (nothing received)\n\r"); mutex_give(mutex_twi_bricklet); return false; } data[i] = TWI_ReadByte(twi); } timeout = 0; // Wait for transfer to be complete while(!TWI_TransferComplete(twi) && (++timeout < I2C_EEPROM_TIMEOUT)); if (timeout == I2C_EEPROM_TIMEOUT) { logieew("read timeout (transfer incomplete)\n\r"); mutex_give(mutex_twi_bricklet); return false; } mutex_give(mutex_twi_bricklet); return true; }
// // 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; }
/* extra use */ char TWI_Write(char address, char *data, char n) { unsigned int SLA_W = (address<<1) & 0XFE; char chk; chk=TWI_Start(); if(chk==1) return chk; //--------------------------- TWDR = SLA_W; TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); if (TWI_STATUS != TWI_MT_SLA_ACK) { TWI_ERROR(); return 3; } //--------------------------- for(char i=0;i<n;i++) { TWDR = *(data+i); TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); if (TWI_STATUS != TWI_MT_DATA_ACK) { TWI_ERROR(); return 4; } } if(n>1) { TWI_Stop(); } else write_to_read=1; return 0; }
/********************************************** * \brief * * * \return none */ result_t HalExpansionPortClass::writePcaPorts(uint32_t iRegister, uint8_t *pBuffer, uint32_t bufLength) { uint32_t bufCnt=bufLength; uint32_t breakOut_cnt=0; result_t retResult=SUCCESS; TWI_StartWrite(HW_ADDR_TWI_PCA9698,HW_PCA9698_TwiAddr, iRegister,HW_PCA9698_InternalAddrLen,*pBuffer); pBuffer++; bufCnt--; while(bufCnt >0) { //if no NACK and Byte sent, then transmit next one if (TWI_SR_NACK & TWI_GetStatus(HW_ADDR_TWI_PCA9698)) { dbgOut1(eDbgAll_errEvt,'B',"HalTwiPca Unexpected NACK ",bufCnt); retResult=FAIL; break; } if (!TWI_ByteSent(HW_ADDR_TWI_PCA9698)) { if (90000 < ++breakOut_cnt) { dbgOut1(eDbgAll_errEvt,'B',"HalTwiPca TWI_SR_TXRDY exceeded ",bufCnt); retResult=FAIL; break; //Out while } continue; } breakOut_cnt = 0; TWI_WriteByte(HW_ADDR_TWI_PCA9698,*pBuffer); pBuffer++; bufCnt--; } TWI_Stop(HW_ADDR_TWI_PCA9698); while (!TWI_TransferComplete(HW_ADDR_TWI_PCA9698)) { if (90000 < ++breakOut_cnt) { dbgOut(eDbgAll_errEvt,'B',"HalTwiPca TWI_SR_TXCOMP exceeded "); break; //Out while } } return retResult; }//portInit
/* * High Level * ************************************************************* */ void TWI_writeRegister(uint8_t i2cAdr, uint8_t regAdr, uint8_t val) { if (TWI_Start() == 0) { //Error uart_writeString("TWI Error Start"); uart_writeAbsatz(); } if (TWI_Write_Addr(i2cAdr, TW_WRITE) == 0) { //Error uart_writeString("TWI Error i2cAdr Write"); uart_writeAbsatz(); } if (TWI_Write_Func(regAdr) == 0) { //Error uart_writeString("TWI Error regAdr Write"); uart_writeAbsatz(); } if (TWI_Write_Func(val) == 0) { //Error uart_writeString("TWI Error val Write"); uart_writeAbsatz(); } TWI_Stop(); }
/** * @ Brief Reads measurement result (illuminance). * @ Parameter None. * @ Retval Illuminance in lux (lx) units. The highest resolution is 1lx. */ uint16_t BH1750_Read() { uint32_t result; uint8_t msb, lsb; uint16_t lux = 0; TWI_Start(); TWI_Write_SLA(BH1750_SLA + 1); msb = TWI_ReadByte_ACK(); lsb = TWI_ReadByte_NACK(); TWI_Stop(); result = ((msb << 8) | lsb) * 10; //Lux = Register / 1,2 == reg*10 / 12 lux = (uint16_t)(result / 12); if(((mode_ == BH1750_CHR_MODE2) || (mode_ == BH1750_OTHR_MODE2)) && ((result % 12 ) >= 6)) { lux++; } return lux; }
unsigned char ReadAccelData(unsigned int iaddress, char *bytes, unsigned int num) { unsigned int timeout; // wait for TWI bus to be ready while(!(TWI_TransferComplete(AT91C_BASE_TWI))) nop(); // Start Reading TWI_StartRead(AT91C_BASE_TWI, ACCELADDR,iaddress,1); while (num > 0) { // Last byte if(num == 1) TWI_Stop(AT91C_BASE_TWI); // wait for byte then read and store it timeout = 0; while(!TWI_ByteReceived(AT91C_BASE_TWI) && (++timeout<TWITIMEOUTMAX)) nop(); if(timeout == TWITIMEOUTMAX) return 2; *bytes++ = TWI_ReadByte(AT91C_BASE_TWI); num--; } return 0; }
/** * \brief Interrupt handler for a TWI peripheral. Manages asynchronous transfer * occuring on the bus. This function MUST be called by the interrupt service * routine of the TWI peripheral if asynchronous read/write are needed. * \param pTwid Pointer to a Twid instance. */ void TWID_Handler( Twid *pTwid ) { uint8_t status; AsyncTwi *pTransfer ; Twi *pTwi ; assert( pTwid != NULL ) ; pTransfer = (AsyncTwi*)pTwid->pTransfer ; assert( pTransfer != NULL ) ; pTwi = pTwid->pTwi ; assert( pTwi != NULL ) ; /* Retrieve interrupt status */ status = TWI_GetMaskedStatus(pTwi); /* Byte received */ if (TWI_STATUS_RXRDY(status)) { pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi); pTransfer->transferred++; /* check for transfer finish */ if (pTransfer->transferred == pTransfer->num) { TWI_DisableIt(pTwi, TWI_IDR_RXRDY); TWI_EnableIt(pTwi, TWI_IER_TXCOMP); } /* Last byte? */ else if (pTransfer->transferred == (pTransfer->num - 1)) { TWI_Stop(pTwi); } } /* Byte sent*/ else if (TWI_STATUS_TXRDY(status)) { /* Transfer finished ? */ if (pTransfer->transferred == pTransfer->num) { TWI_DisableIt(pTwi, TWI_IDR_TXRDY); TWI_EnableIt(pTwi, TWI_IER_TXCOMP); TWI_SendSTOPCondition(pTwi); } /* Bytes remaining */ else { TWI_WriteByte(pTwi, pTransfer->pData[pTransfer->transferred]); pTransfer->transferred++; } } /* Transfer complete*/ else if (TWI_STATUS_TXCOMP(status)) { TWI_DisableIt(pTwi, TWI_IDR_TXCOMP); pTransfer->status = 0; pTwid->pTransfer = 0; if (pTransfer->callback) { pTransfer->callback((Async *) pTransfer); } } }