示例#1
0
void Si4703_Breakout::powerOn(){
  //To get the Si4703 inito 2-wire mode, SEN needs to be high and SDIO needs to be low after a reset
  //The breakout board has SEN pulled high, but also has SDIO pulled high. Therefore, after a normal power up
  //The Si4703 will be in an unknown state. RST must be controlled
    pinMode(_resetPin, OUTPUT);
    pinMode(_sdioPin, OUTPUT); //SDIO is connected to A4 for I2C
    digitalWrite(_sdioPin, LOW); //A low SDIO indicates a 2-wire interface
    digitalWrite(_resetPin, LOW); //Put Si4703 into reset
    delay(1); //Some delays while we allow pins to settle
    digitalWrite(_resetPin, HIGH); //Bring Si4703 out of reset with SDIO set to low and SEN pulled high with on-board resistor
    delay(1); //Allow Si4703 to come out of reset

    Wire.begin(); //Now that the unit is reset and I2C inteface mode, we need to begin I2C

    readRegisters(); //Read the current register set
    //si4703_registers[0x07] = 0xBC04; //Enable the oscillator, from AN230 page 9, rev 0.5 (DOES NOT WORK, wtf Silicon Labs datasheet?)
    si4703_registers[0x07] = 0x8100; //Enable the oscillator, from AN230 page 9, rev 0.61 (works)
    updateRegisters(); //Update

    delay(500); //Wait for clock to settle - from AN230 page 9

    readRegisters(); //Read the current register set
    si4703_registers[POWERCFG] = 0x4001; //Enable the IC
    //  si4703_registers[POWERCFG] |= (1<<SMUTE) | (1<<DMUTE); //Disable Mute, disable softmute
    si4703_registers[SYSCONFIG1] |= (1 << RDS); //Enable RDS

    si4703_registers[SYSCONFIG1] |= (1 << DE); //50kHz Europe setup
    si4703_registers[SYSCONFIG2] |= (1 << SPACE0); //100kHz channel spacing for Europe

    si4703_registers[SYSCONFIG2] &= 0xFFF0; //Clear volume bits
    si4703_registers[SYSCONFIG2] |= 0x0001; //Set volume to lowest
    updateRegisters(); //Update

    delay(110); //Max powerup time, from datasheet page 13
}
void Si4703_Breakout::setChannel(int channel)
{
  //Freq(MHz) = 0.200(in USA) * Channel + 87.5MHz
  //97.3 = 0.2 * Chan + 87.5
  //9.8 / 0.2 = 49
  int newChannel = channel * 10; //973 * 10 = 9730
  newChannel -= 8750; //9730 - 8750 = 980
  newChannel /= 10; //980 / 10 = 98

  //These steps come from AN230 page 20 rev 0.5
  readRegisters();
  si4703_registers[CHANNEL] &= 0xFE00; //Clear out the channel bits
  si4703_registers[CHANNEL] |= newChannel; //Mask in the new channel
  si4703_registers[CHANNEL] |= (1<<TUNE); //Set the TUNE bit to start
  updateRegisters();

  //delay(60); //Wait 60ms - you can use or skip this delay

  //Poll to see if STC is set
  while(1) {
    readRegisters();
    if( (si4703_registers[STATUSRSSI] & (1<<STC)) != 0) break; //Tuning complete!
  }

  readRegisters();
  si4703_registers[CHANNEL] &= ~(1<<TUNE); //Clear the tune after a tune has completed
  updateRegisters();

  //Wait for the si4703 to clear the STC as well
  while(1) {
    readRegisters();
    if( (si4703_registers[STATUSRSSI] & (1<<STC)) == 0) break; //Tuning complete!
  }
}
示例#3
0
int main(int argc, char *argv[])
{
	unsigned val;

	nf2.device_name = DEFAULT_IFACE;

	processArgs(argc, argv);

	// Open the interface if possible
	if (check_iface(&nf2))
	{
		exit(1);
	}
	if (openDescriptor(&nf2))
	{
		exit(1);
	}

	// Increment the argument pointer
	argc -= optind;
	argv += optind;

	// Read the registers
	readRegisters(argc, argv);

	closeDescriptor(&nf2);

	return 0;
}
void Si4703_Breakout::readRDS(char* buffer, long timeout)
{ 
	long endTime = millis() + timeout;
  boolean completed[] = {false, false, false, false};
  int completedCount = 0;
  while(completedCount < 4 && millis() < endTime) {
	readRegisters();
	if(si4703_registers[STATUSRSSI] & (1<<RDSR)){
		// ls 2 bits of B determine the 4 letter pairs
		// once we have a full set return
		// if you get nothing after 20 readings return with empty string
	  uint16_t b = si4703_registers[RDSB];
	  int index = b & 0x03;
	  if (! completed[index] && b < 500)
	  {
		completed[index] = true;
		completedCount ++;
	  	char Dh = (si4703_registers[RDSD] & 0xFF00) >> 8;
      	char Dl = (si4703_registers[RDSD] & 0x00FF);
		buffer[index * 2] = Dh;
		buffer[index * 2 +1] = Dl;
		// Serial.print(si4703_registers[RDSD]); Serial.print(" ");
		// Serial.print(index);Serial.print(" ");
		// Serial.write(Dh);
		// Serial.write(Dl);
		// Serial.println();
      }
      delay(40); //Wait for the RDS bit to clear
	}
示例#5
0
void Si4703_Breakout::setVolume(int volume){
    readRegisters(); //Read the current register set
    if (volume < 0) volume = 0;
    if (volume > 15) volume = 15;
    si4703_registers[SYSCONFIG2] &= 0xFFF0; //Clear volume bits
    si4703_registers[SYSCONFIG2] |= volume; //Set new volume
    updateRegisters(); //Update
}
示例#6
0
QModbusResponse QModbusServerPrivate::processReadWriteMultipleRegistersRequest(
    const QModbusRequest &request)
{
    CHECK_SIZE_LESS_THAN(request);
    quint16 readStartAddress, readQuantity, writeStartAddress, writeQuantity;
    quint8 byteCount;
    request.decodeData(&readStartAddress, &readQuantity,
                       &writeStartAddress, &writeQuantity, &byteCount);

    // byte count does not match number of data bytes following or register count
    if ((byteCount != (request.dataSize() - 9 )) || (byteCount != (writeQuantity * 2))) {
        return QModbusExceptionResponse(request.functionCode(),
                                        QModbusExceptionResponse::IllegalDataValue);
    }

    if ((readQuantity < 0x0001) || (readQuantity > 0x007B)
            || (writeQuantity < 0x0001) || (writeQuantity > 0x0079)) {
        return QModbusExceptionResponse(request.functionCode(),
                                        QModbusExceptionResponse::IllegalDataValue);
    }

    // According to spec, write operation is executed before the read operation
    // Get the requested range out of the registers.
    QModbusDataUnit writeRegisters(QModbusDataUnit::HoldingRegisters, writeStartAddress,
                                   writeQuantity);
    if (!q_func()->data(&writeRegisters)) {
        return QModbusExceptionResponse(request.functionCode(),
                                        QModbusExceptionResponse::IllegalDataAddress);
    }

    const QByteArray pduData = request.data().remove(0,9);
    QDataStream stream(pduData);

    QVector<quint16> values;
    quint16 tmp;
    for (int i = 0; i < writeQuantity; i++) {
        stream >> tmp;
        values.append(tmp);
    }

    writeRegisters.setValues(values);

    if (!q_func()->setData(writeRegisters)) {
        return QModbusExceptionResponse(request.functionCode(),
                                        QModbusExceptionResponse::ServerDeviceFailure);
    }

    // Get the requested range out of the registers.
    QModbusDataUnit readRegisters(QModbusDataUnit::HoldingRegisters, readStartAddress,
                                  readQuantity);
    if (!q_func()->data(&readRegisters)) {
        return QModbusExceptionResponse(request.functionCode(),
                                        QModbusExceptionResponse::IllegalDataAddress);
    }

    return QModbusResponse(request.functionCode(), quint8(readQuantity * 2),
                           readRegisters.values());
}
void Si4703_Breakout::setChannel(int channel)
{
  //Freq(MHz) = 0.200(in USA) * Channel + 87.5MHz
  //channel=(freq-87.5)/0.2;
  //Freq(MHz) = 0.100(in Europe) * Channel + 87.5MHz
  //channel=(freq-87.5)/0.1;
  
  int newChannel = channel * 10; 
  newChannel -= 8750; 

  if (_region==1){
    newChannel /= 20; // US
  } else {
    newChannel /= 10; // Europe
  }

  //These steps come from AN230 page 20 rev 0.5
  readRegisters();
  si4703_registers[CHANNEL] &= 0xFE00; //Clear out the channel bits
  si4703_registers[CHANNEL] |= newChannel; //Mask in the new channel
  si4703_registers[CHANNEL] |= (1<<TUNE); //Set the TUNE bit to start
  updateRegisters();

  //delay(60); //Wait 60ms - you can use or skip this delay

  //set timeout duration
  long endTime = millis() + 2000;
  //Poll to see if STC is set
  while(millis() < endTime) {
    readRegisters();
    if( (si4703_registers[STATUSRSSI] & (1<<STC)) != 0) break; //Tuning complete!
  }

  readRegisters();
  si4703_registers[CHANNEL] &= ~(1<<TUNE); //Clear the tune after a tune has completed
  updateRegisters();

  //set timeout duration
  endTime = millis() + 2000;
  //Wait for the si4703 to clear the STC as well
  while(millis() < endTime) { 
    readRegisters();
    if( (si4703_registers[STATUSRSSI] & (1<<STC)) == 0) break; //Tuning complete!
  }
}
char I2C_Base::readReg(char deviceAddress, char registerAddress)
{
    if(mDisableOperation) {
        return 0;
    }

    char byte = 0;
    readRegisters(deviceAddress, registerAddress, &byte, 1);
    return byte;
}
示例#9
0
bool I2C_Base::checkDeviceResponse(char deviceAddress)
{
    char dummyReg = 0;
    char notUsed = 0;

    // The I2C State machine will not continue after 1st state when length is set to 0
    unsigned int lenZeroToTestDeviceReady = 0;

    return readRegisters(deviceAddress, dummyReg, &notUsed, lenZeroToTestDeviceReady);
}
示例#10
0
/**
 * Function: updateReadings
 * @return None
 * @remark Records the current G-values from the sensor. Accumulation (low-pass)
 *  filtering will occur if USE_ACCUMULATOR is defined.
 * @author David Goodman
 * @date 2013.01.23  */
static void updateReadings() {
    uint8_t rawData[6];  // x/y/z accel register data stored here

    readRegisters(OUT_X_MSB_ADDRESS, 6, rawData);  // Read the six raw data registers into data array

    int i;
    // Loop to calculate 12-bit ADC and g value for each axis
    for(i = 0; i < 3 ; i++)
    {
        int16_t gCountI = (rawData[i*2] << 8) | rawData[(i*2)+1];  //Combine the two 8 bit registers into one 12-bit number
        gCountI >>= 4; //The registers are left align, here we right align the 12-bit integer

        // If the number is negative, we have to make it so manually (no 12-bit data type)
        if (rawData[i*2] > 0x7F)
        {
            gCountI = ~gCountI + 1;
            gCountI *= -1;  // Transform into negative 2's complement #
        }
        //Record this gCount into the struct or short ints
        switch (i) {
            #ifndef USE_ACCUMULATOR
            case 0:
                gCount.x = gCountI;
                break;
            case 1:
                gCount.y = gCountI;
                break;
            case 2:
                gCount.z = gCountI;
                break;
            #else
            case 0:
                gAccumulator.x += gCountI;
                break;
            case 1:
                gAccumulator.y += gCountI;
                break;
            case 2:
                gAccumulator.z += gCountI;
                break;
            #endif
        }
    }
    haveReading = TRUE;
    // Update gCounts if accumulating
    #ifdef USE_ACCUMULATOR
    accumulatorIndex++;
    if (accumulatorIndex >= ACCUMULATOR_LENGTH) {
        gCount.x = (uint16_t)(gAccumulator.x >> ACCUMULATOR_SHIFT);
        gCount.y = (uint16_t)(gAccumulator.y >> ACCUMULATOR_SHIFT);
        gCount.z = (uint16_t)(gAccumulator.z >> ACCUMULATOR_SHIFT);

        resetAccumulator();
    }
示例#11
0
char I2C_Base::isDevicePresent(char deviceAddress)
{
    if(mDisableOperation) {
        return 0;
    }

    char notUsed = 0;
    unsigned int lenZeroToTestDeviceReady = 0;

    // The I2C State machine will not continue after 1st state when length is set to 0
    return readRegisters(deviceAddress, 0, &notUsed, lenZeroToTestDeviceReady);
}
// READ ACCELERATION DATA
//  This function will read the acceleration values from the MMA8452Q. After
//	reading, it will update two triplets of variables:
//		* int's x, y, and z will store the signed 12-bit values read out
//		  of the acceleromter.
//		* floats cx, cy, and cz will store the calculated acceleration from
//		  those 12-bit values. These variables are in units of g's.
void MMA8452Q::read()
{
	byte rawData[6];  // x/y/z accel register data stored here

	readRegisters(OUT_X_MSB, rawData, 6);  // Read the six raw data registers into data array
	
	x = ((short)(rawData[0]<<8 | rawData[1])) >> 4;
	y = ((short)(rawData[2]<<8 | rawData[3])) >> 4;
	z = ((short)(rawData[4]<<8 | rawData[5])) >> 4;
	cx = (float) x / (float)(1<<11) * (float)(scale);
	cy = (float) y / (float)(1<<11) * (float)(scale);
	cz = (float) z / (float)(1<<11) * (float)(scale);
}
示例#13
0
void NXTCam::getBlobs(int *nblobs, uint8_t *color, uint8_t *left, uint8_t *top, uint8_t *right, uint8_t *bottom)
{
    *nblobs = readByte(Cam_Number_Objects);
	for (int i = 0; i < *nblobs; i++) {
	uint8_t* buf ;
	buf = readRegisters(Start_Reg +(i*5), 5);
	color[i]  = buf[0] & 0x00FF;
    left[i]   = buf[1] & 0x00FF;
    top[i]    = buf[2] & 0x00FF;
    right[i]  = buf[3] & 0x00FF;
    bottom[i] = buf[4] & 0x00FF;
	}
}
示例#14
0
bool TICC1100::crcOK()
{
	try
	{
		if(_fileDescriptor->descriptor == -1) return false;
		std::vector<uint8_t> result = readRegisters(Registers::Enum::LQI, 1);
		if((result.size() == 2) && (result.at(1) & 0x80)) return true;
	}
    catch(const std::exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
    return false;
}
void Si4703_Breakout::readPS(char* buffer){ 
	int timeout=2000;
	unsigned long  endTime = millis() + timeout;
	boolean completed[] = {false, false, false, false};
	int completedCount = 0;
	while(completedCount < 4 && millis() < endTime) {
		readRegisters();
		if(si4703_registers[STATUSRSSI] & (1<<RDSR)){

			uint16_t b = si4703_registers[RDSB];
			int index = b & 0x03;
			byte type_trame=(si4703_registers[RDSB] & 0xF000) >> 12;
			if (! completed[index] && type_trame==0x00)
			{
				completed[index] = true;
				completedCount ++;
				char Dh = (si4703_registers[RDSD] & 0xFF00) >> 8;
				char Dl = (si4703_registers[RDSD] & 0x00FF);
				buffer[index * 2] = Dh;
				buffer[index * 2 +1] = Dl;
			}
			delay(40); //Wait for the RDS bit to clear
		}
示例#16
0
void readAccelData(int *destination)
{
  char rawData[6];  // x/y/z accel register data stored here

  readRegisters(OUT_X_MSB, 6, rawData);  // Read the six raw data registers into data array

  // Loop to calculate 12-bit ADC and g value for each axis
  int i;
  for(i=0;i<3;i++)
  {
    int gCount = (rawData[i*2] << 8) | rawData[(i*2)+1];  //Combine the two 8 bit registers into one 12-bit number
    gCount >>= 4; //The registers are left align, here we right align the 12-bit integer

    // If the number is negative, we have to make it so manually (no 12-bit data type)
    if (rawData[i*2] > 0x7F)
    {
      gCount = ~gCount + 1;
      gCount *= -1;  // Transform into negative 2's complement #
    }

    destination[i] = gCount; //Record this gCount into the 3 int array
  }
}
示例#17
0
void setup() 
{
  Wire.begin();
  Serial.begin(9600);
  
  /* Setup the 8MHz PWM clock 
  * This will be on pin 11*/
  DDRB|=(1<<3);//pin 11 output
  ASSR &= ~(_BV(EXCLK) | _BV(AS2));
  TCCR2A=(1<<COM2A0)|(1<<WGM21)|(1<<WGM20);
  TCCR2B=(1<<WGM22)|(1<<CS20);
  delay(3000);
  
  //set up twi for 100khz
  TWSR&=~3;//disable prescaler for TWI
  TWBR=72;//set to 100khz
  
  //------- To debug TWI: freq = 10kHz
  //  TWSR|=2;//enable prescaler for TWI
  //  TWBR= (byte) (((F_CPU / 2000L) - 16) / 2 );
  //-------
  
  readRegisters(0x21);// OV-7670 has address 0x21
}
示例#18
0
int main( void ) {
	if ( !init() ) {
		return EXIT_FAILURE;
	}

	STATE state = S_init;
	STATE last_state;

	stop();

	while ( 1 ) {
		last_state = state;
		readRegisters();

		switch ( state ) {
		default:
		case S_init:
			if ( regs.STATUS1.bumperLeft ) {
				state = bumperLeft;
			} else if ( regs.STATUS1.bumperRight ) {
				state = bumperRight;
			} else if ( regs.STATUS1.obstacleLeft ) {
				state = obstacleLeft;
			} else if ( regs.STATUS1.obstacleRight ) {
				state = obstacleRight;
			} else {
				state = forward;
			}
			break;
		case forward:
			if ( regs.STATUS1.bumperLeft ) {
				state = bumperLeft;
			} else if ( regs.STATUS1.bumperRight ) {
				state = bumperRight;
			} else if ( regs.STATUS1.obstacleLeft ) {
				state = obstacleLeft;
			} else if ( regs.STATUS1.obstacleRight ) {
				state = obstacleRight;
			}
			break;
		case bumperLeft:
			if ( regs.STATUS3.movementComplete ) {
				state = bumperLeft2;
			}
			break;
		case bumperLeft2:
			if ( regs.STATUS3.movementComplete ) {
				state = forward;
			}
			break;
		case bumperRight:
			if ( regs.STATUS3.movementComplete ) {
				state = bumperRight2;
			}
			break;
		case bumperRight2:
			if ( regs.STATUS3.movementComplete ) {
				state = forward;
			}
			break;
		case obstacleLeft:
			if ( regs.STATUS1.bumperLeft ) {
				state = bumperLeft;
			} else if ( regs.STATUS1.bumperRight ) {
				state = bumperRight;
			} else if ( !regs.STATUS1.obstacleLeft ) {
				state = forward;
			}
			break;
		case obstacleRight:
			if ( regs.STATUS1.bumperLeft ) {
				state = bumperLeft;
			} else if ( regs.STATUS1.bumperRight ) {
				state = bumperRight;
			} else if ( !regs.STATUS1.obstacleRight ) {
				state = forward;
			}
			break;
		}

		if ( last_state != state ) {
			switch ( state ) {
			case forward:
				stop();
				changeDirection( RP6_FORWARD );
				moveAtSpeed( 80 , 80 );
				printf( "Change State: forward\n" );
				break;
			case bumperLeft:
				stop();
				move( 20 , RP6_BACKWARD , 600 );
				printf( "Change State: bumperLeft\n" );
				break;
			case bumperLeft2:
				rotate( 20 , RP6_RIGHT , 45 );
				printf( "Change State: bumperLeft2\n" );
				break;
			case bumperRight:
				stop();
				move( 20 , RP6_BACKWARD , 600 );
				printf( "Change State: bumperRight\n" );
				break;
			case bumperRight2:
				rotate( 20 , RP6_LEFT , 45 );
				printf( "Change State: bumperRight2\n" );
				break;
			case obstacleLeft:
				stop();
				changeDirection( RP6_RIGHT );
				moveAtSpeed( 20 , 20 );
				printf( "Change State: obstacleLeft\n" );
				break;
			case obstacleRight:
				stop();
				changeDirection( RP6_LEFT );
				moveAtSpeed( 20 , 20 );
				printf( "Change State: obstacleRight\n" );
				break;
			default:
				break;
			}
		}
	}
	linux_i2c->close( linux_i2c );
	return EXIT_SUCCESS;

}
示例#19
0
void Si4703_Breakout::toggleMute(){
  readRegisters();
  si4703_registers[POWERCFG] ^= (1<<DMUTE); //Toggle Mute bit
  updateRegisters();
}
示例#20
0
void ModbusMaster::readRegisterList(QList<quint16> registerList)
{
    QMap<quint16, ModbusResult> resultMap;

    quint32 success = 0;
    quint32 error = 0;

    /* Open port */
    modbus_t * pCtx = openPort(_pSettingsModel->ipAddress(), _pSettingsModel->port());
    if (pCtx)
    {
        /* Set modbus slave */
        modbus_set_slave(pCtx, _pSettingsModel->slaveId());

        // Disable byte time-out
        uint32_t sec = -1;
        uint32_t usec = 0;
        modbus_set_byte_timeout(pCtx, sec, usec);

        // Set response timeout
        sec = _pSettingsModel->timeout() / 1000;
        usec = (_pSettingsModel->timeout() % 1000) * 1000uL;
        modbus_set_response_timeout(pCtx, sec, usec);

        // Do optimized reads
        qint32 regIndex = 0;
        while (regIndex < registerList.size())
        {
            quint32 count = 0;

            // get number of subsequent registers
            if (
                    ((registerList.size() - regIndex) > 1)
                    && (_pSettingsModel->consecutiveMax() > 1)
                )
            {
                bool bSubsequent;
                do
                {
                    bSubsequent = false;

                    // if next is current + 1, dan subsequent = true
                    if (registerList.at(regIndex + count + 1) == registerList.at(regIndex + count) + 1)
                    {
                        bSubsequent = true;
                        count++;
                    }

                    // Break loop when end of list
                    if ((regIndex + count) >= ((uint)registerList.size() - 1))
                    {
                        break;
                    }

                    // Limit number of register in 1 read
                    if (count > (_pSettingsModel->consecutiveMax() - 1u - 1u))
                    {
                        break;
                    }

                } while(bSubsequent == true);
            }

            // At least one register
            count++;

            // Read registers
            QList<quint16> registerDataList;
            qint32 returnCode = readRegisters(pCtx, registerList.at(regIndex) - 40001, count, &registerDataList);
            if (returnCode == 0)
            {
                success++;
                for (uint i = 0; i < count; i++)
                {
                    const quint16 registerAddr = registerList.at(regIndex) + i;
                    const ModbusResult result = ModbusResult(registerDataList[i], true);
                    resultMap.insert(registerAddr, result);
                }
            }
            else
            {                
                /* only split on specific modbus exception (invalid value and invalid address) */
                if (
                        (returnCode == (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS))
                        || (returnCode == (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE))
                    )
                {

                    /* Consecutive read failed */
                    if (count == 1)
                    {
                        /* Log error */
                        error++;
                        const quint16 registerAddr = registerList.at(regIndex);
                        const ModbusResult result = ModbusResult(0, false);
                        resultMap.insert(registerAddr, result);
                    }
                    else
                    {
                        error++;

                        /* More than one => read all separately */
                        for (quint32 i = 0; i < count; i++)
                        {
                            const quint16 registerAddr = registerList.at(regIndex + i);
                            if (readRegisters(pCtx, registerAddr - 40001, 1, &registerDataList) == 0)
                            {
                                success++;
                                const ModbusResult result = ModbusResult(registerDataList[0], true);
                                resultMap.insert(registerAddr, result);
                            }
                            else
                            {
                                /* Log error */
                                error++;
                                const ModbusResult result = ModbusResult(0, false);
                                resultMap.insert(registerAddr, result);
                            }
                        }
                    }
                }
                else
                {
                    error++;

                    for (qint32 i = 0; i < registerList.size(); i++)
                    {

                        const quint16 registerAddr = registerList.at(i);
                        const ModbusResult result = ModbusResult(0, false);
                        resultMap.insert(registerAddr,result);
                    }

                    break;
                }
            }

            // Set register index to next register
            regIndex += count;
        }

        closePort(pCtx); /* Close port */
    }
    else
    {
        error++;

        for (qint32 i = 0; i < registerList.size(); i++)
        {
            const quint16 registerAddr = registerList.at(i);
            const ModbusResult result = ModbusResult(0, false);
            resultMap.insert(registerAddr,result);
        }
    }

    _pGuiModel->setCommunicationStats(_pGuiModel->communicationSuccessCount() + success, _pGuiModel->communicationErrorCount() + error);

    emit modbusPollDone(resultMap);
}
示例#21
0
void TICC1100::mainThread()
{
    try
    {
		int32_t pollResult;
		int32_t bytesRead;
		std::vector<char> readBuffer({'0'});

        while(!_stopCallbackThread && _fileDescriptor->descriptor > -1 && _gpioDescriptors[1]->descriptor > -1)
        {
        	if(_stopped)
        	{
        		std::this_thread::sleep_for(std::chrono::milliseconds(200));
        		continue;
        	}
        	pollfd pollstruct {
				(int)_gpioDescriptors[1]->descriptor,
				(short)(POLLPRI | POLLERR),
				(short)0
			};

			pollResult = poll(&pollstruct, 1, 100);
			/*if(pollstruct.revents & POLLERR)
			{
				_out.printWarning("Warning: Error polling GPIO. Reopening...");
				closeGPIO();
				std::this_thread::sleep_for(std::chrono::milliseconds(1000));
				openGPIO(_settings->gpio1);
			}*/
			if(pollResult > 0)
			{
				if(lseek(_gpioDescriptors[1]->descriptor, 0, SEEK_SET) == -1) throw BaseLib::Exception("Could not poll gpio: " + std::string(strerror(errno)));
				bytesRead = read(_gpioDescriptors[1]->descriptor, &readBuffer[0], 1);
				if(!bytesRead) continue;
				if(readBuffer.at(0) == 0x30)
				{
					if(!_sending) _txMutex.try_lock(); //We are receiving, don't send now
					continue; //Packet is being received. Wait for GDO high
				}
				if(_sending) endSending();
				else
				{
					//sendCommandStrobe(CommandStrobes::Enum::SIDLE);
					std::shared_ptr<MAXPacket> packet;
					if(crcOK())
					{
						uint8_t firstByte = readRegister(Registers::Enum::FIFO);
						std::vector<uint8_t> packetBytes = readRegisters(Registers::Enum::FIFO, firstByte + 1); //Read packet + RSSI
						packetBytes[0] = firstByte;
						if(packetBytes.size() >= 9) packet.reset(new MAXPacket(packetBytes, true, BaseLib::HelperFunctions::getTime()));
						else _out.printWarning("Warning: Too small packet received: " + BaseLib::HelperFunctions::getHexString(packetBytes));
					}
					else _out.printDebug("Debug: MAX! packet received, but CRC failed.");
					if(!_sendingPending)
					{
						sendCommandStrobe(CommandStrobes::Enum::SFRX);
						sendCommandStrobe(CommandStrobes::Enum::SRX);
					}
					if(packet)
					{
						if(_firstPacket) _firstPacket = false;
						else raisePacketReceived(packet);
					}
				}
				_txMutex.unlock(); //Packet sent or received, now we can send again
			}
			else if(pollResult < 0)
			{
				_txMutex.unlock();
				_out.printError("Error: Could not poll gpio: " + std::string(strerror(errno)) + ". Reopening...");
				closeGPIO(1);
				std::this_thread::sleep_for(std::chrono::milliseconds(1000));
				openGPIO(1, true);
			}
			//pollResult == 0 is timeout
        }
    }
    catch(const std::exception& ex)
    {
    	_txMutex.unlock();
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
    	_txMutex.unlock();
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
    	_txMutex.unlock();
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
    try
    {
		if(!_stopCallbackThread && (_fileDescriptor->descriptor == -1 || _gpioDescriptors[1]->descriptor == -1))
		{
			_out.printError("Connection to TI CC1101 closed inexpectedly... Trying to reconnect...");
			_stopCallbackThread = true; //Set to true, so that sendPacket aborts
			_txMutex.unlock(); //Make sure _txMutex is unlocked
			std::thread thread(&TICC1100::startListening, this);
			thread.detach();
		}
		else _txMutex.unlock(); //Make sure _txMutex is unlocked
	}
    catch(const std::exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
}
示例#22
0
char I2C_Base::readReg(char deviceAddress, char registerAddress)
{
    char byte = 0;
    readRegisters(deviceAddress, registerAddress, &byte, 1);
    return byte;
}
示例#23
0
void DS1307::updateTime() {
	readRegisters((byte) DS1307_SEC, (byte *) &time, 3);
	time &= ((unsigned long)BITS_HR<<16 | BITS_MIN<<8 | BITS_SEC);
}
示例#24
0
byte Si4703_Breakout::getVolume(){
  readRegisters();
  return si4703_registers[SYSCONFIG2] & 0x000F;
}
//检查uart0数据
void checkComm0Modbus(void)
{
	uint16 crcData;
	uint16 tempData;
	
	if(receCount > 4)
	{
		switch(receBuf[1])
		{
			case 1://读取线圈状态(读取点 16位以内)
			case 3://读取保持寄存器(一个或多个)
			case 5://强制单个线圈
			case 6://设置单个寄存器
					if(receCount >= 8)
					{//接收完成一组数据
						//应该关闭接收中断
						
						if(receBuf[0]==localAddr && checkoutError==0)
						{
							crcData = crc16(receBuf,6);
							if(crcData == receBuf[7]+(receBuf[6]<<8))
							{//校验正确
								if(receBuf[1] == 1)
								{//读取线圈状态(读取点 16位以内)
									readCoil();								
								}
								else if(receBuf[1] == 3)
								{//读取保持寄存器(一个或多个)
									readRegisters();
								}
								else if(receBuf[1] == 5)
								{//强制单个线圈
									forceSingleCoil();								
								}
								else if(receBuf[1] == 6)
								{
									//presetSingleRegister();								
								}

							}
						}						
						receCount = 0;	
						checkoutError = 0;
					}
					break;
			
			case 15://设置多个线圈
					tempData = receBuf[6]; 
					tempData += 9;	//数据个数
					if(receCount >= tempData)
					{
						if(receBuf[0]==localAddr && checkoutError==0)
						{
							crcData = crc16(receBuf,tempData-2);
							if(crcData == (receBuf[tempData-2]<<8)+ receBuf[tempData-1])
							{
								//forceMultipleCoils();			
							}
						}	
						receCount = 0;
						checkoutError = 0;
					}
					break;
			
			case 16://设置多个寄存器
					tempData = (receBuf[4]<<8) + receBuf[5];
					tempData = tempData * 2;	//数据个数
					tempData += 9;
					if(receCount >= tempData)
					{
						if(receBuf[0]==localAddr && checkoutError==0)
						{
							crcData = crc16(receBuf,tempData-2);
							if(crcData == (receBuf[tempData-2]<<8)+ receBuf[tempData-1])
							{
								presetMultipleRegisters();			
							}
						}	
						receCount = 0;
						checkoutError = 0;
					}
					break;
								
			default:
					break;			
		}
	}
}//void checkComm0(void)
示例#26
0
void DS1307::updateCalendar() {
	readRegisters((byte) DS1307_DATE, (byte *) &cal, 3);
	cal &= ((unsigned long)BITS_YR<<16 | (unsigned long)BITS_MTH<<8 | BITS_DATE);
}