diff --git a/src/sensor/pac193x/Pac193x.c b/src/sensor/pac193x/Pac193x.c index 23561420..9582d09f 100644 --- a/src/sensor/pac193x/Pac193x.c +++ b/src/sensor/pac193x/Pac193x.c @@ -1,4 +1,4 @@ -#define SOURCE_FILE "src/pac193x/pac193x.c" +#define SOURCE_FILE "PAC193X" #include #include @@ -30,11 +30,6 @@ static const float pac193xInternalUnipolarPowerDenominator = (float)(1ULL << 32) /*! Denominator for energy measurement: 2^28 = 268435456 */ static const float pac193xInternalEnergyDenominator = (float)(1ULL << 28); -/*! rate for samples per second# - * - * \Important Must be set using the ctrl register */ -static const float pac193xInternalSamplingRate = 1024; - /* endregion CONSTANTS */ /* region HEADER FUNCTION IMPLEMENTATIONS */ @@ -76,7 +71,7 @@ pac193xErrorCode_t pac193xInit(pac193xSensorConfiguration_t sensor) { return PAC193X_INIT_ERROR; } - return pac193xInternalRefresh(sensor); + return pac193xRefreshData(sensor); } pac193xErrorCode_t pac193xSetChannelsInUse(pac193xSensorConfiguration_t sensor) { @@ -93,19 +88,99 @@ pac193xErrorCode_t pac193xSetChannelsInUse(pac193xSensorConfiguration_t sensor) return PAC193X_INIT_ERROR; } - return pac193xInternalRefresh(sensor); + return pac193xRefreshData(sensor); } -/* endregion GENERAL FUNCTIONS */ +pac193xErrorCode_t pac193xStartAccumulation(pac193xSensorConfiguration_t sensor) { + /* samplerate = 1024, disable sleep, disable single-show-mode, + * enable alert, enable overflow alert + */ + if (PAC193X_NO_ERROR != + pac193xInternalSendConfigurationToSensor(sensor, PAC193X_CMD_CTRL, 0b00001010)) { + return PAC193X_INIT_ERROR; + } + + /* refresh sensor to apply changes */ + if (PAC193X_NO_ERROR != pac193xRefreshData(sensor)) { + return PAC193X_INIT_ERROR; + } + + return PAC193X_NO_ERROR; +} + +pac193xErrorCode_t pac193XStopAccumulation(pac193xSensorConfiguration_t sensor) { + pac193xErrorCode_t errorCode = pac193xInternalSetDefaultConfiguration(sensor); + if (errorCode != PAC193X_NO_ERROR) { + return errorCode; + } + + /* refresh sensor to apply changes */ + errorCode = pac193xRefreshData(sensor); + if (errorCode != PAC193X_NO_ERROR) { + return errorCode; + } + + return PAC193X_NO_ERROR; +} + +pac193xErrorCode_t pac193xSetSampleRate(pac193xSensorConfiguration_t sensor, + pac193xSampleRate_t sampleRate) { + pac193xErrorCode_t errorCode; + + uint8_t ctrlRegister; + errorCode = pac193xInternalGetDataFromSensor(sensor, &ctrlRegister, 1, PAC193X_CMD_CTRL); + if (errorCode != PAC193X_NO_ERROR) { + return PAC193X_RECEIVE_DATA_ERROR; + } + + ctrlRegister = (ctrlRegister & 0x3F) | (sampleRate << 6); + + errorCode = pac193xInternalSendConfigurationToSensor(sensor, PAC193X_CMD_CTRL, ctrlRegister); + if (errorCode != PAC193X_NO_ERROR) { + return PAC193X_INIT_ERROR; + } + + sensor.sampleRate = sampleRate; + + return PAC193X_NO_ERROR; +} -/* region SINGLE SHOT MEASUREMENTS */ +pac193xErrorCode_t pac193xRefreshData(pac193xSensorConfiguration_t sensor) { + /* essentially performing a REFRESH_V command*/ + + PRINT_DEBUG("send pac193xInternalRefreshV signal to sensor"); + pac193xErrorCode_t errorCode = + pac193xInternalSendRequestToSensor(sensor, PAC193X_CMD_REFRESH_V); + if (errorCode != PAC193X_NO_ERROR) { + PRINT_DEBUG("pac193xInternalRefreshV send failed, error was %02X", errorCode); + return errorCode; + } + + PRINT_DEBUG("pac193xInternalRefreshV successful"); + return PAC193X_NO_ERROR; +} + +pac193xErrorCode_t pac193xRefreshDataAndResetAccumulator(pac193xSensorConfiguration_t sensor) { + /* essentially performing a REFRESH command*/ + + PRINT_DEBUG("send refresh signal to sensor"); + pac193xErrorCode_t errorCode = pac193xInternalSendRequestToSensor(sensor, PAC193X_CMD_REFRESH); + if (errorCode != PAC193X_NO_ERROR) { + PRINT_DEBUG("refresh send failed, error was %02X", errorCode); + return errorCode; + } + + PRINT_DEBUG("refresh successful"); + return PAC193X_NO_ERROR; +} +/* endregion GENERAL FUNCTIONS */ pac193xErrorCode_t pac193xGetSensorInfo(pac193xSensorConfiguration_t sensor, pac193xSensorId_t *info) { uint8_t sizeOfResponseBuffer = 1; /* needs to be called once before reading values to get the latest values*/ - pac193xErrorCode_t errorCode = pac193xInternalRefreshV(sensor); + pac193xErrorCode_t errorCode = pac193xRefreshData(sensor); if (errorCode != PAC193X_NO_ERROR) { return errorCode; } @@ -140,6 +215,8 @@ pac193xErrorCode_t pac193xGetSensorInfo(pac193xSensorConfiguration_t sensor, return PAC193X_NO_ERROR; } +/* region READ MEASUREMENTS */ + pac193xErrorCode_t pac193xGetMeasurementForChannel(pac193xSensorConfiguration_t sensor, pac193xChannel_t channel, pac193xValueToMeasure_t valueToMeasure, @@ -148,13 +225,7 @@ pac193xErrorCode_t pac193xGetMeasurementForChannel(pac193xSensorConfiguration_t return PAC193X_INVALID_CHANNEL; } - /* needs to be called once before reading values to get the latest values*/ - pac193xErrorCode_t errorCode = pac193xInternalRefreshV(sensor); - if (errorCode != PAC193X_NO_ERROR) { - return errorCode; - } - - errorCode = pac193xInternalGetData(sensor, channel, valueToMeasure, value); + pac193xErrorCode_t errorCode = pac193xInternalGetData(sensor, channel, valueToMeasure, value); if (errorCode != PAC193X_NO_ERROR) { *value = 0; return errorCode; @@ -163,26 +234,26 @@ pac193xErrorCode_t pac193xGetMeasurementForChannel(pac193xSensorConfiguration_t return PAC193X_NO_ERROR; } -pac193xErrorCode_t pac193xGetAllMeasurementsForChannel(pac193xSensorConfiguration_t sensor, - pac193xChannel_t channel, - pac193xMeasurements_t *measurements) { +pac193xErrorCode_t pac193xGetMeasurementsForChannel(pac193xSensorConfiguration_t sensor, + pac193xChannel_t channel, + pac193xMeasurements_t *measurements) { if (!pac193xInternalCheckChannelIsActive(sensor.usedChannels, channel)) { + measurements->voltageSource = 0; + measurements->voltageSense = 0; + measurements->currentSense = 0; + measurements->power = 0; return PAC193X_INVALID_CHANNEL; } - /* needs to be called once before reading values to get the latest values*/ - pac193xErrorCode_t errorCode = pac193xInternalRefreshV(sensor); - if (errorCode != PAC193X_NO_ERROR) { - return errorCode; - } + pac193xErrorCode_t errorCode; errorCode = pac193xInternalGetData(sensor, channel, PAC193X_VSOURCE, &measurements->voltageSource); if (errorCode != PAC193X_NO_ERROR) { measurements->voltageSource = 0; measurements->voltageSense = 0; - measurements->iSense = 0; - measurements->powerActual = 0; + measurements->currentSense = 0; + measurements->power = 0; return errorCode; } @@ -191,160 +262,49 @@ pac193xErrorCode_t pac193xGetAllMeasurementsForChannel(pac193xSensorConfiguratio if (errorCode != PAC193X_NO_ERROR) { measurements->voltageSource = 0; measurements->voltageSense = 0; - measurements->iSense = 0; - measurements->powerActual = 0; + measurements->currentSense = 0; + measurements->power = 0; return errorCode; } - errorCode = pac193xInternalGetData(sensor, channel, PAC193X_ISENSE, &measurements->iSense); + errorCode = + pac193xInternalGetData(sensor, channel, PAC193X_CURRENT, &measurements->currentSense); if (errorCode != PAC193X_NO_ERROR) { measurements->voltageSource = 0; measurements->voltageSense = 0; - measurements->iSense = 0; - measurements->powerActual = 0; + measurements->currentSense = 0; + measurements->power = 0; return errorCode; } - errorCode = pac193xInternalGetData(sensor, channel, PAC193X_POWER, &measurements->powerActual); + errorCode = pac193xInternalGetData(sensor, channel, PAC193X_POWER, &measurements->power); if (errorCode != PAC193X_NO_ERROR) { measurements->voltageSource = 0; measurements->voltageSense = 0; - measurements->iSense = 0; - measurements->powerActual = 0; - return errorCode; - } - - return PAC193X_NO_ERROR; -} - -/* endregion SINGLE SHOT MEASUREMENTS */ - -/* region CONTINUOUS MEASUREMENTS */ - -pac193xErrorCode_t pac193xStartAccumulation(pac193xSensorConfiguration_t sensor) { - /* disable single shot mode, set sample rate to 1024 samples/s, enable overflow alert - * enable alert pin -> not floating => if disable only 8 samples/s*/ - pac193xErrorCode_t errorCode = - pac193xInternalSendConfigurationToSensor(sensor, PAC193X_CMD_CTRL, 0b00001010); - if (errorCode != PAC193X_NO_ERROR) { - return PAC193X_INIT_ERROR; - } - - /* refresh sensor to apply changes */ - errorCode = pac193xInternalRefresh(sensor); - if (errorCode != PAC193X_NO_ERROR) { - return PAC193X_INIT_ERROR; - } - - return PAC193X_NO_ERROR; -} - -pac193xErrorCode_t pac193XStopAccumulation(pac193xSensorConfiguration_t sensor) { - pac193xErrorCode_t errorCode = pac193xInternalSetDefaultConfiguration(sensor); - if (errorCode != PAC193X_NO_ERROR) { - return errorCode; - } - - /* refresh sensor to apply changes */ - errorCode = pac193xInternalRefresh(sensor); - if (errorCode != PAC193X_NO_ERROR) { + measurements->currentSense = 0; + measurements->power = 0; return errorCode; } return PAC193X_NO_ERROR; } -pac193xErrorCode_t -pac193xReadAccumulatedPowerForAllChannels(pac193xSensorConfiguration_t sensor, - pac193xPowerMeasurements_t *measurements) { - /* needs to be called once before reading values to get the latest values*/ - pac193xErrorCode_t errorCode = pac193xInternalRefresh(sensor); - if (errorCode != PAC193X_NO_ERROR) { - return errorCode; - } - - // read accumulation counter (PAC193X_CMD_READ_ACC_COUNT) - uint8_t *responseBuffer = malloc(3); - errorCode = - pac193xInternalGetDataFromSensor(sensor, responseBuffer, 3, PAC193X_CMD_READ_ACC_COUNT); - if (errorCode != PAC193X_NO_ERROR) { - free(responseBuffer); - return PAC193X_RECEIVE_DATA_ERROR; - } - measurements->counterOfMeasurements = - (uint32_t)pac193xInternalTransformResponseBufferToUInt64(responseBuffer, 3); - free(responseBuffer); - - // read accumulated power value ( PAC193X_CMD_READ_VPOWER{1,2,3,4}_ACC ) - /* 6 bytes for each of the 4 channels */ - responseBuffer = malloc(24); - errorCode = - pac193xInternalGetDataFromSensor(sensor, responseBuffer, 24, PAC193X_CMD_READ_VPOWER1_ACC); - if (errorCode != PAC193X_NO_ERROR) { - free(responseBuffer); - return PAC193X_RECEIVE_DATA_ERROR; - } - measurements->powerChannel1 = pac193xInternalCalculateEnergy( - pac193xInternalTransformResponseBufferToUInt64(responseBuffer, 6), - sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(PAC193X_CHANNEL01)]); - measurements->powerChannel2 = pac193xInternalCalculateEnergy( - pac193xInternalTransformResponseBufferToUInt64(responseBuffer + 6, 6), - sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(PAC193X_CHANNEL02)]); - measurements->powerChannel3 = pac193xInternalCalculateEnergy( - pac193xInternalTransformResponseBufferToUInt64(responseBuffer + 12, 6), - sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(PAC193X_CHANNEL03)]); - measurements->powerChannel4 = pac193xInternalCalculateEnergy( - pac193xInternalTransformResponseBufferToUInt64(responseBuffer + 18, 6), - sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(PAC193X_CHANNEL04)]); - free(responseBuffer); - - return pac193xInternalRefresh(sensor); -} - -pac193xErrorCode_t pac193xReadAverageMeasurement(pac193xSensorConfiguration_t sensor, - pac193xChannel_t channel, - pac193xValueToMeasure_t valueToMeasure, - float *value) { +pac193xErrorCode_t pac193xGetAveragesForChannel(pac193xSensorConfiguration_t sensor, + pac193xChannel_t channel, + pac193xMeasurements_t *measurements) { if (!pac193xInternalCheckChannelIsActive(sensor.usedChannels, channel)) { return PAC193X_INVALID_CHANNEL; } - /* needs to be called before reading values to get the latest values*/ - pac193xErrorCode_t errorCode = pac193xInternalRefreshV(sensor); - if (errorCode != PAC193X_NO_ERROR) { - return errorCode; - } - - errorCode = pac193xInternalGetData(sensor, channel, valueToMeasure, value); - if (errorCode != PAC193X_NO_ERROR) { - *value = 0; - return errorCode; - } - - return PAC193X_NO_ERROR; -} - -pac193xErrorCode_t -pac193xReadAllAverageMeasurementsForChannel(pac193xSensorConfiguration_t sensor, - pac193xChannel_t channel, - pac193xMeasurements_t *measurements) { - if (!pac193xInternalCheckChannelIsActive(sensor.usedChannels, channel)) { - return PAC193X_INVALID_CHANNEL; - } - - /* needs to be called once before reading values to get the latest values*/ - pac193xErrorCode_t errorCode = pac193xInternalRefreshV(sensor); - if (errorCode != PAC193X_NO_ERROR) { - return errorCode; - } + pac193xErrorCode_t errorCode; errorCode = pac193xInternalGetData(sensor, channel, PAC193X_VSOURCE_AVG, &measurements->voltageSource); if (errorCode != PAC193X_NO_ERROR) { measurements->voltageSource = 0; measurements->voltageSense = 0; - measurements->iSense = 0; - measurements->powerActual = 0; + measurements->currentSense = 0; + measurements->power = 0; return errorCode; } @@ -353,27 +313,64 @@ pac193xReadAllAverageMeasurementsForChannel(pac193xSensorConfiguration_t sensor, if (errorCode != PAC193X_NO_ERROR) { measurements->voltageSource = 0; measurements->voltageSense = 0; - measurements->iSense = 0; - measurements->powerActual = 0; + measurements->currentSense = 0; + measurements->power = 0; return errorCode; } - errorCode = pac193xInternalGetData(sensor, channel, PAC193X_ISENSE_AVG, &measurements->iSense); + errorCode = + pac193xInternalGetData(sensor, channel, PAC193X_CURRENT_AVG, &measurements->currentSense); if (errorCode != PAC193X_NO_ERROR) { measurements->voltageSource = 0; measurements->voltageSense = 0; - measurements->iSense = 0; - measurements->powerActual = 0; + measurements->currentSense = 0; + measurements->power = 0; return errorCode; } /* no average for power => set to zero */ - measurements->powerActual = 0; + measurements->power = 0; + + return PAC193X_NO_ERROR; +} + +pac193xErrorCode_t pac193xReadEnergyForAllChannels(pac193xSensorConfiguration_t sensor, + pac193xEnergyMeasurements_t *measurements) { + pac193xErrorCode_t errorCode; + + /* read values counter */ + uint8_t responseBuffer[28]; + errorCode = pac193xInternalGetDataFromSensor(sensor, responseBuffer, 3, PAC193X_CMD_CTRL); + if (errorCode != PAC193X_NO_ERROR) { + return PAC193X_RECEIVE_DATA_ERROR; + } + + measurements->overflow = responseBuffer[0] & 0x01; + + measurements->numberOfAccumulatedValues = + pac193xInternalTransformResponseBufferToUInt64(&responseBuffer[1], 3); + + measurements->energyChannel1 = pac193xInternalCalculateEnergy( + pac193xInternalTransformResponseBufferToUInt64(&responseBuffer[4], 6), + sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(PAC193X_CHANNEL01)], + sensor.sampleRate); + measurements->energyChannel2 = pac193xInternalCalculateEnergy( + pac193xInternalTransformResponseBufferToUInt64(&responseBuffer[10], 6), + sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(PAC193X_CHANNEL02)], + sensor.sampleRate); + measurements->energyChannel3 = pac193xInternalCalculateEnergy( + pac193xInternalTransformResponseBufferToUInt64(&responseBuffer[16], 6), + sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(PAC193X_CHANNEL03)], + sensor.sampleRate); + measurements->energyChannel4 = pac193xInternalCalculateEnergy( + pac193xInternalTransformResponseBufferToUInt64(&responseBuffer[22], 6), + sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(PAC193X_CHANNEL04)], + sensor.sampleRate); return PAC193X_NO_ERROR; } -/* endregion CONTINUOUS MEASUREMENTS*/ +/* endregion READ MEASUREMENTS*/ /* endregion HEADER FUNCTION IMPLEMENTATIONS */ @@ -400,11 +397,12 @@ pac193xInternalSetDefaultConfiguration(pac193xSensorConfiguration_t sensor) { return PAC193X_INIT_ERROR; } - /* enable single-shot mode, disables alert/overflow pin */ - errorCode = pac193xInternalSendConfigurationToSensor(sensor, PAC193X_CMD_CTRL, 0b00010000); + /* enable single-shot mode, enable slow mode, disable alert/overflow pin */ + errorCode = pac193xInternalSendConfigurationToSensor(sensor, PAC193X_CMD_CTRL, 0b11010000); if (errorCode != PAC193X_NO_ERROR) { return PAC193X_INIT_ERROR; } + sensor.sampleRate = PAC193X_8_SAMPLES_PER_SEC; /* sets measurement to unipolar mode */ errorCode = pac193xInternalSendConfigurationToSensor(sensor, PAC193X_CMD_NEG_PWR, 0b00000000); @@ -442,37 +440,6 @@ pac193xInternalSendConfigurationToSensor(pac193xSensorConfiguration_t sensor, return PAC193X_NO_ERROR; } -static pac193xErrorCode_t pac193xInternalRefresh(pac193xSensorConfiguration_t sensor) { - PRINT_DEBUG("send refresh signal to sensor"); - pac193xErrorCode_t errorCode = pac193xInternalSendRequestToSensor(sensor, PAC193X_CMD_REFRESH); - if (errorCode != PAC193X_NO_ERROR) { - PRINT_DEBUG("refresh send failed, error was %02X", errorCode); - return errorCode; - } - - /* sleep because the sensor is unreachable for 1ms after refresh */ - sleep_for_ms(1); - - PRINT_DEBUG("refresh successful"); - return PAC193X_NO_ERROR; -} - -static pac193xErrorCode_t pac193xInternalRefreshV(pac193xSensorConfiguration_t sensor) { - PRINT_DEBUG("send pac193xInternalRefreshV signal to sensor"); - pac193xErrorCode_t errorCode = - pac193xInternalSendRequestToSensor(sensor, PAC193X_CMD_REFRESH_V); - if (errorCode != PAC193X_NO_ERROR) { - PRINT_DEBUG("pac193xInternalRefreshV send failed, error was %02X", errorCode); - return errorCode; - } - - /* sleep because the sensor is unreachable for 1ms after refresh */ - sleep_for_ms(1); - - PRINT_DEBUG("pac193xInternalRefreshV successful"); - return PAC193X_NO_ERROR; -} - static pac193xErrorCode_t pac193xInternalSendRequestToSensor(pac193xSensorConfiguration_t sensor, pac193xRegisterAddress_t registerToRead) { @@ -556,7 +523,7 @@ static uint8_t pac193xInternalTranslateChannelToRSenseArrayIndex(pac193xChannel_ channelIndex = 3; break; default: - channelIndex = -1; + channelIndex = UINT8_MAX; } PRINT_DEBUG("channel: %i; index: %i", channel, channelIndex); @@ -579,14 +546,14 @@ pac193xInternalSetMeasurementProperties(pac193xMeasurementProperties_t *properti properties->calculationFunction = &pac193xInternalCalculateVoltageOfSense; properties->sizeOfResponseBuffer = 2; break; - case PAC193X_ISENSE: + case PAC193X_CURRENT: properties->startReadAddress += PAC193X_CMD_READ_VSENSE1; properties->calculationFunction = &pac193xInternalCalculateCurrentOfSense; properties->sizeOfResponseBuffer = 2; break; case PAC193X_POWER: properties->startReadAddress += PAC193X_CMD_READ_VPOWER1; - properties->calculationFunction = &pac193xInternalCalculateActualPower; + properties->calculationFunction = &pac193xInternalCalculatePower; properties->sizeOfResponseBuffer = 4; break; case PAC193X_VSOURCE_AVG: @@ -599,11 +566,19 @@ pac193xInternalSetMeasurementProperties(pac193xMeasurementProperties_t *properti properties->calculationFunction = &pac193xInternalCalculateVoltageOfSense; properties->sizeOfResponseBuffer = 2; break; - case PAC193X_ISENSE_AVG: + case PAC193X_CURRENT_AVG: properties->startReadAddress += PAC193X_CMD_READ_VSENSE1_AVG; properties->calculationFunction = &pac193xInternalCalculateCurrentOfSense; properties->sizeOfResponseBuffer = 2; + case PAC193X_ENERGY: + properties->startReadAddress += PAC193X_CMD_READ_VPOWER1_ACC; + properties->calculationFunction = &pac193xInternalCalculateEnergy; + properties->sizeOfResponseBuffer = 6; break; + case PAC193X_ACCUMULATOR: + properties->startReadAddress += PAC193X_CMD_READ_ACC_COUNT; + properties->calculationFunction = &pac193xInternalCalculateAccumulatorCount; + properties->sizeOfResponseBuffer = 3; default: PRINT_DEBUG("invalid properties"); return PAC193X_INVALID_MEASUREMENT; @@ -631,11 +606,10 @@ static pac193xErrorCode_t pac193xInternalGetData(pac193xSensorConfiguration_t se } /* retrieve data from sensor */ - uint8_t *responseBuffer = malloc(properties.sizeOfResponseBuffer); + uint8_t responseBuffer[properties.sizeOfResponseBuffer]; errorCode = pac193xInternalGetDataFromSensor( sensor, responseBuffer, properties.sizeOfResponseBuffer, properties.startReadAddress); if (errorCode != PAC193X_NO_ERROR) { - free(responseBuffer); return errorCode; } @@ -643,23 +617,22 @@ static pac193xErrorCode_t pac193xInternalGetData(pac193xSensorConfiguration_t se uint64_t rawValue = pac193xInternalTransformResponseBufferToUInt64( responseBuffer, properties.sizeOfResponseBuffer); *value = (*properties.calculationFunction)( - rawValue, sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(channel)]); + rawValue, sensor.rSense[pac193xInternalTranslateChannelToRSenseArrayIndex(channel)], + sensor.sampleRate); - free(responseBuffer); return PAC193X_NO_ERROR; } static uint64_t pac193xInternalTransformResponseBufferToUInt64(const uint8_t *responseBuffer, uint8_t sizeOfResponseBuffer) { PRINT_DEBUG("transforming buffer to uint64"); - uint64_t scalar = responseBuffer[0]; - for (uint8_t index = 1; index < sizeOfResponseBuffer; index++) { - scalar <<= 8; - scalar |= (uint64_t)(responseBuffer[index]); + pac193xInternalDataBuffer_t converter = {.value = 0}; + for (size_t index = 0; index < sizeOfResponseBuffer; index++) { + converter.raw[sizeOfResponseBuffer - 1 - index] = responseBuffer[index]; } - PRINT_DEBUG("output: %llu", scalar); - return scalar; + PRINT_DEBUG("output: %llu", converter.value); + return converter.value; } static float pac193xInternalConvertToFloat(uint64_t input) { @@ -668,8 +641,16 @@ static float pac193xInternalConvertToFloat(uint64_t input) { return (float)input; } +static float pac193xInternalCalculateAccumulatorCount(uint64_t input, + __attribute((__unused__)) float resistor, + __attribute((__unused__)) + uint8_t sampleRate) { + return pac193xInternalConvertToFloat(input); +} + static float pac193xInternalCalculateVoltageOfSource(uint64_t input, - __attribute__((unused)) float resistor) { + __attribute((__unused__)) float resistor, + __attribute((__unused__)) uint8_t sampleRate) { PRINT_DEBUG("calculating voltage of source"); float vSource = 32.0f * (pac193xInternalConvertToFloat(input) / pac193xInternalUnipolarVoltageDenominator); @@ -678,7 +659,8 @@ static float pac193xInternalCalculateVoltageOfSource(uint64_t input, } static float pac193xInternalCalculateVoltageOfSense(uint64_t input, - __attribute__((unused)) float resistor) { + __attribute((__unused__)) float resistor, + __attribute((__unused__)) uint8_t sampleRate) { PRINT_DEBUG("calculating voltage of sense"); float vSense = 0.1f * (pac193xInternalConvertToFloat(input) / pac193xInternalUnipolarVoltageDenominator); @@ -686,7 +668,8 @@ static float pac193xInternalCalculateVoltageOfSense(uint64_t input, return vSense; } -static float pac193xInternalCalculateCurrentOfSense(uint64_t input, float resistor) { +static float pac193xInternalCalculateCurrentOfSense(uint64_t input, float resistor, + __attribute((__unused__)) uint8_t sampleRate) { PRINT_DEBUG("calculating current of sense"); float fsc = 0.1f / resistor; float iSense = @@ -695,8 +678,9 @@ static float pac193xInternalCalculateCurrentOfSense(uint64_t input, float resist return iSense; } -static float pac193xInternalCalculateActualPower(uint64_t input, float resistor) { - PRINT_DEBUG("calculating actual power"); +static float pac193xInternalCalculatePower(uint64_t input, float resistor, + __attribute((__unused__)) uint8_t sampleRate) { + PRINT_DEBUG("calculating power"); float powerFSR = 3.2f / resistor; float powerConversionFactor = pac193xInternalConvertToFloat(input) / pac193xInternalUnipolarPowerDenominator; @@ -705,11 +689,25 @@ static float pac193xInternalCalculateActualPower(uint64_t input, float resistor) return powerActual; } -static float pac193xInternalCalculateEnergy(uint64_t input, float resistor) { +static float pac193xInternalGetSampleRate(uint8_t sampleRate) { + switch (sampleRate) { + case PAC193X_1024_SAMPLES_PER_SEC: + return 1024.0f; + case PAC193X_256_SAMPLES_PER_SEC: + return 256.0f; + case PAC193X_64_SAMPLES_PER_SEC: + return 64.0f; + case PAC193X_8_SAMPLES_PER_SEC: + return 8.0f; + default: + return 0.0f; + } +} +static float pac193xInternalCalculateEnergy(uint64_t input, float resistor, uint8_t sampleRate) { PRINT_DEBUG("calculating energy"); float powerFSR = 3.2f / resistor; float energy = pac193xInternalConvertToFloat(input) * powerFSR / - (pac193xInternalEnergyDenominator * pac193xInternalSamplingRate); + (pac193xInternalEnergyDenominator * pac193xInternalGetSampleRate(sampleRate)); PRINT_DEBUG("output: %f", energy); return energy; } diff --git a/src/sensor/pac193x/Pac193xInternal.h b/src/sensor/pac193x/Pac193xInternal.h index 941802f4..4c7f4c3b 100644 --- a/src/sensor/pac193x/Pac193xInternal.h +++ b/src/sensor/pac193x/Pac193xInternal.h @@ -5,6 +5,11 @@ #include #include +typedef union pac193xInternalDataBuffer { + uint64_t value; + uint8_t raw[8]; +} pac193xInternalDataBuffer_t; + /* region SENSOR COMMUNICATION */ static pac193xErrorCode_t pac193xInternalCheckSensorAvailable(pac193xSensorConfiguration_t sensor); @@ -12,7 +17,8 @@ static pac193xErrorCode_t pac193xInternalCheckSensorAvailable(pac193xSensorConfi static pac193xErrorCode_t pac193xInternalSetDefaultConfiguration(pac193xSensorConfiguration_t sensor); -/*! send configuration to the sensor +/*! + * @brief send configuration to the sensor * * @param registerToWrite[in] address of the register where the settings should * be stored @@ -24,31 +30,8 @@ pac193xInternalSendConfigurationToSensor(pac193xSensorConfiguration_t sensor, pac193xRegisterAddress_t registerToWrite, pac193xSettings_t settingsToWrite); -/*! triggers reload of configuration and freezes accumulator - * - * \Information - * 1. reloads configuration\n - * 2. store current values of accumulator until next execution of refresh()\n - * 3. resets the accumulator - * - * @param sensor[in] sensor to refresh - * @return returns the error code (0 if everything passed) - */ -static pac193xErrorCode_t pac193xInternalRefresh(pac193xSensorConfiguration_t sensor); - -/*! triggers reload of configuration and freezes accumulator - * - * \Information - * 1. reloads configuration\n - * 2. store current values of accumulator until next execution of refresh()\n - * 3. \b NOT resetting the accumulator - * - * @param sensor[in] sensor to refresh - * @return returns the error code (0 if everything passed) - */ -static pac193xErrorCode_t pac193xInternalRefreshV(pac193xSensorConfiguration_t sensor); - -/*! send request for register to read to sensor +/*! + * @brief send request for register to read to sensor * * @param registerToRead[in] address of register to read * @return return the error code (0 if everything passed) @@ -57,7 +40,8 @@ static pac193xErrorCode_t pac193xInternalSendRequestToSensor(pac193xSensorConfiguration_t sensor, pac193xRegisterAddress_t registerToRead); -/*! receive data from sensor +/*! + * @brief receive data from sensor * * @param responseBuffer[out] byte buffer where the received will be stored * @param sizeOfResponseBuffer[in] size of the buffer for the response @@ -68,8 +52,10 @@ static pac193xErrorCode_t pac193xInternalReceiveDataFromSensor(pac193xSensorConf uint8_t *responseBuffer, uint8_t sizeOfResponseBuffer); -/*! requests and receives data from the sensor\n - * combines: pac193xInternalSendRequestToSensor(...) and pac193xInternalReceiveDataFromSensor(...) +/*! + * @brief requests and receives data from the sensor + * + * combines: \a pac193xInternalSendRequestToSensor and \a pac193xInternalReceiveDataFromSensor * * @param responseBuffer[out] * @param sizeOfResponseBuffer[in] @@ -90,9 +76,10 @@ static bool pac193xInternalCheckChannelIsActive(pac193xUsedChannels_t usedChanne static uint8_t pac193xInternalTranslateChannelToRSenseArrayIndex(pac193xChannel_t channel); -/*! store adequate properties for the requested measurement +/*! + * @brief store adequate properties for the requested measurement * - * \Information + * @information * - register to start read\n * - function to convert raw data\n * - number of requested bytes @@ -119,17 +106,25 @@ static uint64_t pac193xInternalTransformResponseBufferToUInt64(const uint8_t *re static float pac193xInternalConvertToFloat(uint64_t input); +static float pac193xInternalCalculateAccumulatorCount(uint64_t input, + __attribute((__unused__)) float resistor, + __attribute((__unused__)) uint8_t sampleRate); + static float pac193xInternalCalculateVoltageOfSense(uint64_t input, - __attribute__((unused)) float resistor); + __attribute((__unused__)) float resistor, + __attribute((__unused__)) uint8_t sampleRate); static float pac193xInternalCalculateVoltageOfSource(uint64_t input, - __attribute__((unused)) float resistor); + __attribute((__unused__)) float resistor, + __attribute((__unused__)) uint8_t sampleRate); -static float pac193xInternalCalculateCurrentOfSense(uint64_t input, float resistor); +static float pac193xInternalCalculateCurrentOfSense(uint64_t input, float resistor, + __attribute((__unused__)) uint8_t sampleRate); -static float pac193xInternalCalculateActualPower(uint64_t input, float resistor); +static float pac193xInternalCalculatePower(uint64_t input, float resistor, + __attribute((__unused__)) uint8_t sampleRate); -static float pac193xInternalCalculateEnergy(uint64_t input, float resistor); +static float pac193xInternalCalculateEnergy(uint64_t input, float resistor, uint8_t sampleRate); /* endregion DATA TRANSFORMATION */ diff --git a/src/sensor/pac193x/README.md b/src/sensor/pac193x/README.md index e4933150..b2168237 100644 --- a/src/sensor/pac193x/README.md +++ b/src/sensor/pac193x/README.md @@ -33,7 +33,7 @@ int main(void) { // Example: Read Values from Channel pac193xMeasurements_t measurements; - errorCode = pac193xGetAllMeasurementsForChannel(sensor, PAC193X_CHANNEL01, &measurements); + errorCode = pac193xGetMeasurementsForChannel(sensor, PAC193X_CHANNEL01, &measurements); if (errordCode != PAC193X_NO_ERROR) { return errorCode; } diff --git a/src/sensor/pac193x/include/Pac193x.h b/src/sensor/pac193x/include/Pac193x.h index 22ecd56d..44d516da 100644 --- a/src/sensor/pac193x/include/Pac193x.h +++ b/src/sensor/pac193x/include/Pac193x.h @@ -6,11 +6,19 @@ #include // tag::prototypes[] +/* + * IMPORTANT: + * We highly recommend using the settings from the `enV5_hw_configuration`-library, + * to set up the sensor configuration struct! + */ + /* region GENERAL FUNCTIONS */ /*! * @brief power up the sensor by setting PWRDN Pin to HIGH - * @IMPORTANT We highly recommend using the "enV5_hw_configuration_rev_[x]" -library + * + * @warning needs ~1.5ms to reach idle state after power up + * * * @param sensor[in] configuration for sensor to use * @return returns the error code (0 if everything passed) @@ -19,8 +27,8 @@ pac193xErrorCode_t pac193xPowerUpSensor(pac193xSensorConfiguration_t sensor); /*! * @brief power down the sensor by setting PWRDN Pin to LOW - * @IMPORTANT - After powered up again all settings will be set to default! - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library + * + * @important After powered up again all settings will be set to default! * * @param sensor[in] configuration for sensor to use * @return returns the error code (0 if everything passed) @@ -29,12 +37,10 @@ pac193xErrorCode_t pac193xPowerDownSensor(pac193xSensorConfiguration_t sensor); /*! * @brief initializes the power sensor - * @IMPORTANT - * - function has to be called before the sensor can be used \n - * needs max 1.5ms for idle state after power up \n - * function pac193xPowerUpSensor(...) has to be called beforehand - * @IMPORTANT - * - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library + * + * @warning requires 1ms to reach idle state + * + * @important \a pac193xPowerUpSensor has to be called beforehand! * * @param sensor[in] configuration for sensor to use * @return returns the error code (0 if everything passed) @@ -43,20 +49,72 @@ pac193xErrorCode_t pac193xInit(pac193xSensorConfiguration_t sensor); /*! * @brief updates the number of used channels - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library * * @param sensor[in] sensor configuration with updated channels * @return returns the error code (0 if everything passed) */ pac193xErrorCode_t pac193xSetChannelsInUse(pac193xSensorConfiguration_t sensor); -/* endregion GENERAL FUNCTIONS */ +/*! + * @brief start continuous measurement as accumulator/average with 1024 samples/second + * + * @param sensor[in] configuration of the sensor to use + * @param sampleRate[in] sample rate to be used + * @return returns the error code (0 if everything passed) + */ +pac193xErrorCode_t pac193xStartAccumulation(pac193xSensorConfiguration_t sensor); + +/*! + * @brief stop continuous measurement and return to single shot mode + * + * @param sensor[in] configuration of the sensor to use + * @return returns the error code (0 if everything passed) + */ +pac193xErrorCode_t pac193XStopAccumulation(pac193xSensorConfiguration_t sensor); -/* region SINGLE SHOT MEASUREMENTS */ +/*! + * @brief set the sample rate for the sensor in accumulation mode + * + * @param sensor[in] configuration of the sensor to use + * @param sampleRate[in] sample rate to be used + * @return returns the error code (0 if everything passed) + * + */ +pac193xErrorCode_t pac193xSetSampleRate(pac193xSensorConfiguration_t sensor, + pac193xSampleRate_t sampleRate); + +/*! + * @brief this function transfers the latest accumulated values to the data register + * and \b resets all accumulating registers afterward. + * + * @important the values can be read from the data registers until another Refresh command is + * issued! + * + * @warning sensor needs 1ms to reach idle state + * + * @param sensor[in] configuration if the sensor to use + * @return returns the error code (0 if everything passed) + */ +pac193xErrorCode_t pac193xRefreshDataAndResetAccumulator(pac193xSensorConfiguration_t sensor); + +/*! + * @brief this function transfers the latest accumulated values to the data register + * \b without resetting the accumulating registers. + * + * @important the values can be read from the data registers until another Refresh command is + * issued! + * + * @warning sensor needs 1ms to reach idle state + * + * @param sensor[in] configuration if the sensor to use + * @return returns the error code (0 if everything passed) + */ +pac193xErrorCode_t pac193xRefreshData(pac193xSensorConfiguration_t sensor); + +/* endregion GENERAL FUNCTIONS */ /*! * @brief retrieve the production information from the sensor - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library * * @param sensor[in] configuration of the sensor to use * @param info[out] struct that holds the information read from the sensor @@ -65,9 +123,13 @@ pac193xErrorCode_t pac193xSetChannelsInUse(pac193xSensorConfiguration_t sensor); pac193xErrorCode_t pac193xGetSensorInfo(pac193xSensorConfiguration_t sensor, pac193xSensorId_t *info); +/* region READ MEASUREMENTS */ + /*! * @brief read a specific value from the sensor for a specific channel - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library + * + * @important + * \a pac193xRefreshDataAndResetAccumulator or \a pac193xRefreshData has to be called beforehand! * * @param sensor[in] configuration of the sensor to use * @param channel[in] channel where the measurement should be taken from @@ -82,79 +144,46 @@ pac193xErrorCode_t pac193xGetMeasurementForChannel(pac193xSensorConfiguration_t /*! * @brief read \b all available single shot values from the sensor for a specific channel - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library * * @param sensor[in] configuration of the sensor to use * @param channel[in] channel where the measurement should be taken from * @param measurements[out] memory where the struct with the measured values will be stored * @return returns the error code (0 if everything passed) */ -pac193xErrorCode_t pac193xGetAllMeasurementsForChannel(pac193xSensorConfiguration_t sensor, - pac193xChannel_t channel, - pac193xMeasurements_t *measurements); - -/* endregion SINGLE SHOT MEASUREMENTS */ - -/* region CONTINUOUS MEASUREMENTS */ +pac193xErrorCode_t pac193xGetMeasurementsForChannel(pac193xSensorConfiguration_t sensor, + pac193xChannel_t channel, + pac193xMeasurements_t *measurements); /*! - * @brief start continuous measurement as accumulator/average with 1024 samples/second - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library + * @brief read all rolling averages from sensor * - * @param sensor[in] configuration of the sensor to use - * @return returns the error code (o if everything passed) - */ -pac193xErrorCode_t pac193xStartAccumulation(pac193xSensorConfiguration_t sensor); - -/*! - * @brief stop continuous measurement and return to single shot mode - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library - * - * @param sensor[in] configuration of the sensor to use - * @return returns the error code (o if everything passed) - */ -pac193xErrorCode_t pac193XStopAccumulation(pac193xSensorConfiguration_t sensor); - -/*! - * @brief get the counter of accumulated values and the accumulated power values - * for all channels of the sensor - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library + * @important + * \a pac193xRefreshDataAndResetAccumulator or \a pac193xRefreshData has to be called beforehand! * * @param sensor[in] configuration of the sensor to use + * @param channel[in] channel where the measurement should be taken from * @param measurements[out] memory where the struct with the measured values will be stored - * @return returns the error code (o if everything passed) + * @return returns the error code (0 if everything passed) */ -pac193xErrorCode_t -pac193xReadAccumulatedPowerForAllChannels(pac193xSensorConfiguration_t sensor, - pac193xPowerMeasurements_t *measurements); +pac193xErrorCode_t pac193xGetAveragesForChannel(pac193xSensorConfiguration_t sensor, + pac193xChannel_t channel, + pac193xMeasurements_t *measurements); /*! - * @brief read an rolling average value of from sensor - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library + * @brief get the counter of accumulated values and the accumulated power values + * for all channels of the sensor * - * @param sensor[in] configuration of the sensor to use - * @param channel[in] channel where the measurement should be taken from - * @param valueToMeasure[in] value to be measured - * @param value[out] memory where the retrieved value will be stored - * @return returns the error code (o if everything passed) - */ -pac193xErrorCode_t pac193xReadAverageMeasurement(pac193xSensorConfiguration_t sensor, - pac193xChannel_t channel, - pac193xValueToMeasure_t valueToMeasure, - float *value); - -/*! - * @brief read an rolling average value of from sensor - * @IMPORTANT - We highly recommend using the "enV5_hw_configuration_rev_[x]" -library + * @important + * \a pac193xRefreshDataAndResetAccumulator or \a pac193xRefreshData has to be called beforehand! * * @param sensor[in] configuration of the sensor to use - * @param channel[in] channel where the measurement should be taken from * @param measurements[out] memory where the struct with the measured values will be stored - * @return returns the error code (o if everything passed) + * @return returns the error code (0 if everything passed) */ -pac193xErrorCode_t pac193xReadAllAverageMeasurementsForChannel(pac193xSensorConfiguration_t sensor, - pac193xChannel_t channel, - pac193xMeasurements_t *measurements); -/* endregion CONTINUOUS MEASUREMENTS */ +pac193xErrorCode_t pac193xReadEnergyForAllChannels(pac193xSensorConfiguration_t sensor, + pac193xEnergyMeasurements_t *measurements); + +/* endregion ACCUMULATED MEASUREMENTS */ // end::prototypes[] + #endif /* ENV5_PAC193X_HEADER */ diff --git a/src/sensor/pac193x/include/Pac193xTypedefs.h b/src/sensor/pac193x/include/Pac193xTypedefs.h index 933768c1..47eebd2c 100644 --- a/src/sensor/pac193x/include/Pac193xTypedefs.h +++ b/src/sensor/pac193x/include/Pac193xTypedefs.h @@ -1,11 +1,12 @@ #ifndef ENV5_PAC193X_TYPEDEFS #define ENV5_PAC193X_TYPEDEFS +#include #include typedef struct i2c_inst i2c_inst_t; -union pac193xUsedChannels { +typedef union pac193xUsedChannels { struct { uint8_t channel1 : 1; uint8_t channel2 : 1; @@ -14,10 +15,9 @@ union pac193xUsedChannels { uint8_t : 4; } struct_channelsInUse; uint8_t uint_channelsInUse; -}; -typedef union pac193xUsedChannels pac193xUsedChannels_t; +} pac193xUsedChannels_t; -enum { +typedef enum pac193xI2cAddress { PAC193X_I2C_ADDRESS_GND = 0x10, PAC193X_I2C_ADDRESS_499R = 0x11, PAC193X_I2C_ADDRESS_806R = 0x12, @@ -34,58 +34,63 @@ enum { PAC193X_I2C_ADDRESS_140000R = 0x1D, PAC193X_I2C_ADDRESS_226000R = 0x1E, PAC193X_I2C_ADDRESS_VDD = 0x1F, -}; -typedef uint8_t pac193xI2cAddress_t; +} pac193xI2cAddress_t; + +typedef enum pac193xSampleRate { + PAC193X_1024_SAMPLES_PER_SEC = 0x00, + PAC193X_256_SAMPLES_PER_SEC = 0x01, + PAC193X_64_SAMPLES_PER_SEC = 0x02, + PAC193X_8_SAMPLES_PER_SEC = 0x03, +} pac193xSampleRate_t; typedef struct pac193xSensorConfiguration { i2c_inst_t *i2c_host; pac193xI2cAddress_t i2c_slave_address; uint8_t powerPin; float rSense[4]; - pac193xUsedChannels_t usedChannels; /*!< Channels to be used. \Note Some channels might be - disabled by the ctrl-register. */ + pac193xUsedChannels_t + usedChannels; /*!< Channels to be used. + * \Note Some channels might be disabled by the ctrl-register. + */ + pac193xSampleRate_t sampleRate; } pac193xSensorConfiguration_t; -enum { +typedef enum pac193xChannel { PAC193X_CHANNEL01 = 0, PAC193X_CHANNEL02 = 1, PAC193X_CHANNEL03 = 2, PAC193X_CHANNEL04 = 3, -}; -typedef uint8_t pac193xChannel_t; +} pac193xChannel_t; -struct pac193xSensorId { +typedef struct pac193xSensorId { uint8_t product_id; uint8_t manufacturer_id; uint8_t revision_id; -}; -typedef struct pac193xSensorId pac193xSensorId_t; +} pac193xSensorId_t; -struct pac193xMeasurements { - float voltageSource; - float voltageSense; - float iSense; - float powerActual; -}; -typedef struct pac193xMeasurements pac193xMeasurements_t; +typedef struct pac193xMeasurements { + float voltageSource; //!< Voltage on SENSE+ pin + float voltageSense; //!< Voltage on SENSE- pin + float currentSense; + float power; +} pac193xMeasurements_t; -struct pac193xPowerMeasurements { - uint32_t counterOfMeasurements; - float powerChannel1; - float powerChannel2; - float powerChannel3; - float powerChannel4; -}; -typedef struct pac193xPowerMeasurements pac193xPowerMeasurements_t; +typedef struct pac193xEnergyMeasurements { + uint32_t numberOfAccumulatedValues; + bool overflow; + float energyChannel1; + float energyChannel2; + float energyChannel3; + float energyChannel4; +} pac193xEnergyMeasurements_t; -struct pac193xMeasurementProperties { +typedef struct pac193xMeasurementProperties { uint8_t startReadAddress; - float (*calculationFunction)(uint64_t value, float resistor); + float (*calculationFunction)(uint64_t value, float resistor, uint8_t sampleRate); uint8_t sizeOfResponseBuffer; -}; -typedef struct pac193xMeasurementProperties pac193xMeasurementProperties_t; +} pac193xMeasurementProperties_t; -enum { +typedef enum pac193xRegisterAddress { PAC193X_CMD_REFRESH = 0x00, PAC193X_CMD_CTRL = 0x01, PAC193X_CMD_READ_ACC_COUNT = 0x02, @@ -127,22 +132,22 @@ enum { PAC193X_CMD_READ_PRODUCT_ID = 0xFD, PAC193X_CMD_READ_MANUFACTURER_ID = 0xFE, PAC193X_CMD_READ_REVISION_ID = 0xFF, -}; -typedef uint8_t pac193xRegisterAddress_t; +} pac193xRegisterAddress_t; typedef uint8_t pac193xSettings_t; -enum { +typedef enum pac193xValueToMeasure { PAC193X_VSOURCE, PAC193X_VSENSE, - PAC193X_ISENSE, + PAC193X_CURRENT, PAC193X_POWER, PAC193X_VSOURCE_AVG, PAC193X_VSENSE_AVG, - PAC193X_ISENSE_AVG -}; -typedef uint8_t pac193xValueToMeasure_t; + PAC193X_CURRENT_AVG, + PAC193X_ENERGY, + PAC193X_ACCUMULATOR, +} pac193xValueToMeasure_t; -enum { +typedef enum pac193xErrorCode { PAC193X_NO_ERROR = 0x00, PAC193X_SEND_COMMAND_ERROR = 0x01, PAC193X_RECEIVE_DATA_ERROR = 0x02, @@ -152,7 +157,6 @@ enum { PAC193X_INVALID_MEASUREMENT = 0x12, PAC193X_INVALID_CHANNEL = 0x13, PAC193X_UNDEFINED_ERROR = 0x20, -}; -typedef uint8_t pac193xErrorCode_t; +} pac193xErrorCode_t; #endif /* ENV5_PAC193X_TYPEDEFS */ diff --git a/test/hardware/Sensors/CMakeLists.txt b/test/hardware/Sensors/CMakeLists.txt index 1a80dfc1..47e75262 100644 --- a/test/hardware/Sensors/CMakeLists.txt +++ b/test/hardware/Sensors/CMakeLists.txt @@ -33,9 +33,24 @@ target_link_libraries(hardware-test_pac193x pico_bootrom pico_time i2c_interface + enV5_hw_configuration sensor_lib_pac193x) create_enV5_executable(hardware-test_pac193x) ############################################## +## hardware-test_pac193x_stream +add_executable(hardware-test_pac193x_stream HardwaretestPac193xAccumulator.c) +target_link_libraries(hardware-test_pac193x_stream + common_lib + pico_stdlib + pico_stdio_usb + pico_bootrom + pico_time + i2c_interface + enV5_hw_configuration + enV5_hw_controller + sensor_lib_pac193x) +create_enV5_executable(hardware-test_pac193x_stream) +############################################## ## hardware-test_dualpac193x add_executable(hardware-test_dualpac193x HardwaretestDualPac193x.c) target_link_libraries(hardware-test_dualpac193x @@ -45,6 +60,7 @@ target_link_libraries(hardware-test_dualpac193x pico_bootrom pico_time i2c_interface + enV5_hw_configuration sensor_lib_pac193x) create_enV5_executable(hardware-test_dualpac193x) ############################################## @@ -57,6 +73,7 @@ target_link_libraries(hardware-test_pac193xbuffer pico_bootrom pico_time i2c_interface + enV5_hw_configuration sensor_lib_pac193x) create_enV5_executable(hardware-test_pac193xbuffer) ############################################## diff --git a/test/hardware/Sensors/HardwaretestDualPac193x.c b/test/hardware/Sensors/HardwaretestDualPac193x.c index 790959c0..dd0277dd 100644 --- a/test/hardware/Sensors/HardwaretestDualPac193x.c +++ b/test/hardware/Sensors/HardwaretestDualPac193x.c @@ -1,12 +1,15 @@ #define SOURCE_FILE "DUAL-PAC193X-Test" -#include "Common.h" -#include "I2c.h" -#include "Pac193x.h" +#include + #include #include #include -#include + +#include "Common.h" +#include "EnV5HwConfiguration.h" +#include "I2c.h" +#include "Pac193x.h" /* region HELPER */ @@ -26,20 +29,20 @@ static void measureValue(pac193xSensorConfiguration_t sensor, pac193xChannel_t c /* region I2C DEFINITION */ i2cConfiguration_t i2cConfig = { - .i2cInstance = i2c1, - .frequency = 400000, - .sdaPin = 6, - .sclPin = 7, + .i2cInstance = I2C_INSTANCE, + .frequency = I2C_FREQUENCY_IN_HZ, + .sdaPin = I2C_SDA_PIN, + .sclPin = I2C_SCL_PIN, }; /* endregion I2C DEFINITION */ /* region SENSOR DEFINITIONS */ static pac193xSensorConfiguration_t sensor1 = { - .i2c_host = i2c1, - .i2c_slave_address = PAC193X_I2C_ADDRESS_499R, - .powerPin = -1, - .usedChannels = {.uint_channelsInUse = 0b00001111}, - .rSense = {0.82f, 0.82f, 0.82f, 0.82f}, + .i2c_host = PAC_ONE_HOST, + .i2c_slave_address = PAC_ONE_SLAVE, + .powerPin = PAC_ONE_POWER_PIN, + .usedChannels = PAC_ONE_USED_CHANNELS, + .rSense = PAC_ONE_R_SENSE, }; #define PAC193X_CHANNEL_SENSORS PAC193X_CHANNEL01 #define PAC193X_CHANNEL_RAW PAC193X_CHANNEL02 @@ -47,11 +50,11 @@ static pac193xSensorConfiguration_t sensor1 = { #define PAC193X_CHANNEL_WIFI PAC193X_CHANNEL04 static pac193xSensorConfiguration_t sensor2 = { - .i2c_host = i2c1, - .i2c_slave_address = PAC193X_I2C_ADDRESS_806R, - .powerPin = -1, - .usedChannels = {.uint_channelsInUse = 0b00001111}, - .rSense = {0.82f, 0.82f, 0.82f, 0.82f}, + .i2c_host = PAC_TWO_HOST, + .i2c_slave_address = PAC_TWO_SLAVE, + .powerPin = PAC_TWO_POWER_PIN, + .usedChannels = PAC_TWO_USED_CHANNELS, + .rSense = PAC_TWO_R_SENSE, }; #define PAC193X_CHANNEL_FPGA_IO PAC193X_CHANNEL01 #define PAC193X_CHANNEL_FPGA_1V8 PAC193X_CHANNEL02 diff --git a/test/hardware/Sensors/HardwaretestPac193x.c b/test/hardware/Sensors/HardwaretestPac193x.c index 7d367800..ae5baec4 100644 --- a/test/hardware/Sensors/HardwaretestPac193x.c +++ b/test/hardware/Sensors/HardwaretestPac193x.c @@ -1,12 +1,15 @@ #define SOURCE_FILE "PAC193X-Test" -#include "Common.h" -#include "I2c.h" -#include "Pac193x.h" +#include + #include #include #include -#include + +#include "Common.h" +#include "EnV5HwConfiguration.h" +#include "I2c.h" +#include "Pac193x.h" /* region HELPER */ @@ -26,44 +29,45 @@ _Bool compareFloatsWithinRange(float expected, float actual, float epsilon) { /* region I2C DEFINITION */ i2cConfiguration_t i2cConfig = { - .i2cInstance = i2c1, - .frequency = 400000, - .sdaPin = 6, - .sclPin = 7, + .i2cInstance = I2C_INSTANCE, + .frequency = I2C_FREQUENCY_IN_HZ, + .sdaPin = I2C_SDA_PIN, + .sclPin = I2C_SCL_PIN, }; /* endregion I2C DEFINITION */ /* region SENSOR DEFINITION */ -#define PAC193X_CHANNEL_SENSORS PAC193X_CHANNEL01 -#define PAC193X_CHANNEL_WIFI PAC193X_CHANNEL04 - static pac193xSensorConfiguration_t sensor1 = { - .i2c_host = i2c1, - .i2c_slave_address = PAC193X_I2C_ADDRESS_499R, - .powerPin = -1, - .usedChannels = {.uint_channelsInUse = 0b00001111}, - .rSense = {0.82f, 0.82f, 0.82f, 0.82f}, + .i2c_host = PAC_ONE_HOST, + .i2c_slave_address = PAC_ONE_SLAVE, + .powerPin = PAC_ONE_POWER_PIN, + .usedChannels = PAC_ONE_USED_CHANNELS, + .rSense = PAC_ONE_R_SENSE, }; -/* endregion SENSOR DEFINTION */ + +#define PAC193X_CHANNEL_SENSORS PAC193X_CHANNEL01 +#define PAC193X_CHANNEL_WIFI PAC193X_CHANNEL04 +/* endregion SENSOR DEFINITION */ static void getValuesOfChannelWifi() { pac193xMeasurements_t measurements; PRINT("Requesting measurements for wifi board."); pac193xErrorCode_t errorCode = - pac193xGetAllMeasurementsForChannel(sensor1, PAC193X_CHANNEL_WIFI, &measurements); + pac193xGetMeasurementsForChannel(sensor1, PAC193X_CHANNEL_WIFI, &measurements); if (errorCode != PAC193X_NO_ERROR) { PRINT(" \033[0;31mFAILED\033[0m; pac193x_ERROR: %02X", errorCode); return; } PRINT(" Measurements:\tVSource=%4.6fV\tVSense=%4.6fmV\tISense=%4.6fmA", - measurements.voltageSource, measurements.voltageSense * 1000, measurements.iSense * 1000); + measurements.voltageSource, measurements.voltageSense * 1000, + measurements.currentSense * 1000); PRINT(" RSense_expected=%4.2fOhm, RSense_actual=%4.2fOhm:", sensor1.rSense[1], - measurements.voltageSense / (measurements.iSense)); - if (compareFloatsWithinRange(sensor1.rSense[0], measurements.voltageSense / measurements.iSense, - 0.1f)) { + measurements.voltageSense / (measurements.currentSense)); + if (compareFloatsWithinRange(sensor1.rSense[0], + measurements.voltageSense / measurements.currentSense, 0.1f)) { PRINT(" \033[0;32mPASSED\033[0m"); } else { PRINT(" \033[0;31mFAILED\033[0m; Resistance values do not match!"); @@ -71,9 +75,9 @@ static void getValuesOfChannelWifi() { PRINT( " Measured Power => %4.6fW; Calculated Power = Voltage_source * Current_Sense => %4.6fW:", - measurements.powerActual, measurements.iSense * measurements.voltageSource); - if (compareFloatsWithinRange(measurements.powerActual, - measurements.iSense * measurements.voltageSource, 0.001f)) { + measurements.power, measurements.currentSense * measurements.voltageSource); + if (compareFloatsWithinRange(measurements.power, + measurements.currentSense * measurements.voltageSource, 0.001f)) { PRINT(" \033[0;32mPASSED\033[0m"); } else { PRINT(" \033[0;31mFAILED\033[0m; Values do not match!"); @@ -85,19 +89,20 @@ static void getValuesOfChannelSensors() { PRINT("Requesting measurements for sensors."); pac193xErrorCode_t errorCode = - pac193xGetAllMeasurementsForChannel(sensor1, PAC193X_CHANNEL_SENSORS, &measurements); + pac193xGetMeasurementsForChannel(sensor1, PAC193X_CHANNEL_SENSORS, &measurements); if (errorCode != PAC193X_NO_ERROR) { PRINT(" \033[0;31mFAILED\033[0m; pac193x_ERROR: %02X", errorCode); return; } PRINT(" Measurements:\tVSource=%4.6fV;\tVSense=%4.6fmV;\tISense=%4.6fmA", - measurements.voltageSource, measurements.voltageSense * 1000, measurements.iSense * 1000); + measurements.voltageSource, measurements.voltageSense * 1000, + measurements.currentSense * 1000); PRINT(" RSense_expected=%4.2fOhm, RSense_actual=%4.2fOhm:", sensor1.rSense[1], - measurements.voltageSense / (measurements.iSense)); - if (compareFloatsWithinRange(sensor1.rSense[0], measurements.voltageSense / measurements.iSense, - 0.1f)) { + measurements.voltageSense / (measurements.currentSense)); + if (compareFloatsWithinRange(sensor1.rSense[0], + measurements.voltageSense / measurements.currentSense, 0.1f)) { PRINT(" \033[0;32mPASSED\033[0m"); } else { PRINT(" \033[0;31mFAILED\033[0m; Resistance values do not match!"); @@ -105,9 +110,9 @@ static void getValuesOfChannelSensors() { PRINT( " Measured Power => %4.6fW; Calculated Power = Voltage_Source * Current_Sense => %4.6fW:", - measurements.powerActual, measurements.iSense * measurements.voltageSource); - if (compareFloatsWithinRange(measurements.powerActual, - measurements.iSense * measurements.voltageSource, 0.001f)) { + measurements.power, measurements.currentSense * measurements.voltageSource); + if (compareFloatsWithinRange(measurements.power, + measurements.currentSense * measurements.voltageSource, 0.001f)) { PRINT(" \033[0;32mPASSED\033[0m"); } else { PRINT(" \033[0;31mFAILED\033[0m; Values do not match!"); diff --git a/test/hardware/Sensors/HardwaretestPac193xAccumulator.c b/test/hardware/Sensors/HardwaretestPac193xAccumulator.c new file mode 100644 index 00000000..3903abc8 --- /dev/null +++ b/test/hardware/Sensors/HardwaretestPac193xAccumulator.c @@ -0,0 +1,105 @@ +#define SOURCE_FILE "HW-PAC193X-STREAM" + +#include + +#include +#include + +#include "Common.h" +#include "EnV5HwConfiguration.h" +#include "EnV5HwController.h" +#include "I2c.h" +#include "Pac193x.h" +#include "Sleep.h" + +/* region I2C DEFINITION */ +i2cConfiguration_t i2cConfig = { + .i2cInstance = I2C_INSTANCE, + .frequency = I2C_FREQUENCY_IN_HZ, + .sdaPin = I2C_SDA_PIN, + .sclPin = I2C_SCL_PIN, +}; +/* endregion I2C DEFINITION */ + +/* region SENSOR DEFINITION */ +static pac193xSensorConfiguration_t sensor = { + .i2c_host = PAC_TWO_HOST, + .i2c_slave_address = PAC_TWO_SLAVE, + .powerPin = PAC_TWO_POWER_PIN, + .usedChannels = PAC_TWO_USED_CHANNELS, + .rSense = PAC_TWO_R_SENSE, +}; +#define PAC193X_CHANNEL_FPGA_IO PAC193X_CHANNEL01 +#define PAC193X_CHANNEL_FPGA_1V8 PAC193X_CHANNEL02 +#define PAC193X_CHANNEL_FPGA_1V PAC193X_CHANNEL03 +#define PAC193X_CHANNEL_FPGA_SRAM PAC193X_CHANNEL04 +/* endregion SENSOR DEFINITION */ + +static void initHardware(void) { + env5HwControllerInit(); + + /* enable print to console */ + stdio_init_all(); + while ((!stdio_usb_connected())) { + // wait for user console to connect + } + sleep_ms(500); + + /* initialize I2C */ + PRINT("===== START I2C INIT ====="); + i2cErrorCode_t i2cErrorCode; + while (1) { + i2cErrorCode = i2cInit(&i2cConfig); + if (i2cErrorCode == I2C_NO_ERROR) { + PRINT("Initialised I2C."); + break; + } + PRINT("Initialise I2C failed; i2c_ERROR: %02X", i2cErrorCode); + sleep_ms(500); + } + + /* initialize PAC193X sensor */ + PRINT("===== START PAC193X INIT ====="); + pac193xErrorCode_t errorCode; + while (1) { + errorCode = pac193xInit(sensor); + if (errorCode == PAC193X_NO_ERROR) { + PRINT("Initialised PAC193X.\n"); + break; + } + PRINT("Initialise PAC193X failed; pac193x_ERROR: %02X\n", errorCode); + sleep_ms(500); + } +} + +_Noreturn static void runTest(void) { + PRINT("===== START TEST ====="); + pac193xStartAccumulation(sensor); + pac193xSetSampleRate(sensor, PAC193X_256_SAMPLES_PER_SEC); + pac193xRefreshDataAndResetAccumulator(sensor); + + sleep_for_ms(1000); + + while (true) { + pac193xRefreshData(sensor); + sleep_for_ms(10); + pac193xEnergyMeasurements_t measurements; + pac193xErrorCode_t error = pac193xReadEnergyForAllChannels(sensor, &measurements); + if (PAC193X_NO_ERROR != error) { + PRINT("Error occurred: 0x%02X", error); + } else { + PRINT("Overflow: %b", measurements.overflow); + PRINT("Got %lu values:\n\t%f\n\t%f\n\t%f\n\t%f", measurements.numberOfAccumulatedValues, + measurements.energyChannel1, measurements.energyChannel2, + measurements.energyChannel3, measurements.energyChannel4); + } + + PRINT("Sleeping for 2 seconds"); + sleep_for_ms(2000); + } +} + +int main(void) { + initHardware(); + runTest(); +} diff --git a/test/hardware/Sensors/HardwaretestPac193xBuffer.c b/test/hardware/Sensors/HardwaretestPac193xBuffer.c index b75e6310..95ac3b1b 100644 --- a/test/hardware/Sensors/HardwaretestPac193xBuffer.c +++ b/test/hardware/Sensors/HardwaretestPac193xBuffer.c @@ -1,31 +1,34 @@ #define SOURCE_FILE "PAC193X-BUFFER" +#include + +#include +#include +#include + #include "Common.h" +#include "EnV5HwConfiguration.h" #include "I2c.h" #include "Pac193x.h" #include "Pac193xTypedefs.h" -#include -#include -#include -#include /* region I2C DEFINITION */ i2cConfiguration_t i2cConfig = { - .i2cInstance = i2c1, - .frequency = 400000, - .sdaPin = 6, - .sclPin = 7, + .i2cInstance = I2C_INSTANCE, + .frequency = I2C_FREQUENCY_IN_HZ, + .sdaPin = I2C_SDA_PIN, + .sclPin = I2C_SCL_PIN, }; /* endregion I2C DEFINITION */ /* region SENSOR DEFINITIONS */ static pac193xSensorConfiguration_t sensor1 = { - .i2c_host = i2c1, - .i2c_slave_address = PAC193X_I2C_ADDRESS_499R, - .powerPin = -1, - .usedChannels = {.uint_channelsInUse = 0b00001111}, - .rSense = {0.82f, 0.82f, 0.82f, 0.82f}, + .i2c_host = PAC_ONE_HOST, + .i2c_slave_address = PAC_ONE_SLAVE, + .powerPin = PAC_ONE_POWER_PIN, + .usedChannels = PAC_ONE_USED_CHANNELS, + .rSense = PAC_ONE_R_SENSE, }; #define PAC193X_CHANNEL_SENSORS PAC193X_CHANNEL01 #define PAC193X_CHANNEL_RAW PAC193X_CHANNEL02 @@ -33,11 +36,11 @@ static pac193xSensorConfiguration_t sensor1 = { #define PAC193X_CHANNEL_WIFI PAC193X_CHANNEL04 static pac193xSensorConfiguration_t sensor2 = { - .i2c_host = i2c1, - .i2c_slave_address = PAC193X_I2C_ADDRESS_806R, - .powerPin = -1, - .usedChannels = {.uint_channelsInUse = 0b00001111}, - .rSense = {0.82f, 0.82f, 0.82f, 0.82f}, + .i2c_host = PAC_TWO_HOST, + .i2c_slave_address = PAC_TWO_SLAVE, + .powerPin = PAC_TWO_POWER_PIN, + .usedChannels = PAC_TWO_USED_CHANNELS, + .rSense = PAC_TWO_R_SENSE, }; #define PAC193X_CHANNEL_FPGA_IO PAC193X_CHANNEL01 #define PAC193X_CHANNEL_FPGA_1V8 PAC193X_CHANNEL02 @@ -56,8 +59,8 @@ static void sensorTest(pac193xSensorConfiguration_t sensor) { /* wait to gather samples */ sleep_ms(2000); - pac193xPowerMeasurements_t measurements; - errorCode = pac193xReadAccumulatedPowerForAllChannels(sensor, &measurements); + pac193xEnergyMeasurements_t measurements; + errorCode = pac193xReadEnergyForAllChannels(sensor, &measurements); if (errorCode != PAC193X_NO_ERROR) { PRINT(" \033[0;31mFAILED\033[0m; pac193x_ERROR: %02X", errorCode); return; @@ -68,11 +71,11 @@ static void sensorTest(pac193xSensorConfiguration_t sensor) { return; } - PRINT("Performed %lu Measurements:", measurements.counterOfMeasurements); - PRINT(" Channel 1: %4.6fWs", measurements.powerChannel1); - PRINT(" Channel 2: %4.6fWs", measurements.powerChannel2); - PRINT(" Channel 3: %4.6fWs", measurements.powerChannel3); - PRINT(" Channel 4: %4.6fWs", measurements.powerChannel4); + PRINT("Performed %lu Measurements:", measurements.numberOfAccumulatedValues); + PRINT(" Channel 1: %4.6fWs", measurements.energyChannel1); + PRINT(" Channel 2: %4.6fWs", measurements.energyChannel2); + PRINT(" Channel 3: %4.6fWs", measurements.energyChannel3); + PRINT(" Channel 4: %4.6fWs", measurements.energyChannel4); } static void enterBootMode() { @@ -132,6 +135,4 @@ int main(void) { break; } } - - return 0; } diff --git a/test/unit/UnittestPac193x.c b/test/unit/UnittestPac193x.c index 4212d07e..7c2607a6 100644 --- a/test/unit/UnittestPac193x.c +++ b/test/unit/UnittestPac193x.c @@ -1,3 +1,4 @@ +#include "Common.h" #include "I2cUnitTest.h" #include "Pac193x.h" @@ -20,16 +21,12 @@ static const float pac193xInternalUnipolarPowerDenominator = (float)(1ULL << 32) /*! Denominator for energy measurement: 2^28 = 268435456 */ static const float pac193xInternalEnergyDenominator = (float)(1ULL << 28); -/*! rate for samples per second# - * - * \Important Must be set using the ctrl register */ -static const float pac193xInternalSamplingRate = 1024; - static pac193xSensorConfiguration_t SENSOR = { .usedChannels = {.uint_channelsInUse = 0b00000010}, .rSense = {0, 0.82f, 0, 0}, .powerPin = -1, .i2c_slave_address = 0x11, + .sampleRate = PAC193X_8_SAMPLES_PER_SEC, }; static uint8_t usedChannelIndex = 1; @@ -115,6 +112,15 @@ void pac193xMemoryNotPassedToGetSensorInfoRemainsUntouched(void) { /* endregion */ /* region pac193x_GetMeasurementForChannel */ +void testAssertUint64tEquals(void) { + uint64_t expected = 0x0000BEBEBEBEBEBE; + uint64_t actual = ((uint64_t)byteZero << 40) | ((uint64_t)byteZero << 32) | + ((uint64_t)byteZero << 24) | ((uint64_t)byteZero << 16) | + ((uint64_t)byteZero << 8) | (uint64_t)byteZero; + + TEST_ASSERT_EQUAL_UINT64(expected, actual); +} + void pac193xGetMeasurementForChannelReturnSendCommandErrorIfHardwareFails(void) { float result; i2cUnittestWriteCommand = i2cUnittestWriteCommandHardwareDefect; @@ -165,6 +171,7 @@ void pac193xGetMeasurementForChannelReturnInvalidChannelErrorIfChannelWrong(void TEST_ASSERT_EQUAL_UINT8(PAC193X_INVALID_CHANNEL, errorCode); } +/* region V_SOURCE */ void pac193xGetMeasurementForChannelReadSuccessfulValueVsource(void) { float result; @@ -185,7 +192,9 @@ void pac193xGetMeasurementForChannelReadCorrectValueVsource(void) { TEST_ASSERT_EQUAL_FLOAT(expectedValue, actualValue); } +/* endregion V_SOURCE */ +/* region V_SENSE */ void pac193xGetMeasurementForChannelReadSuccessfulValueVsense(void) { float result; @@ -205,38 +214,42 @@ void pac193xGetMeasurementForChannelReadCorrectValueVsense(void) { TEST_ASSERT_EQUAL_FLOAT(expectedValue, actualValue); } +/* endregion V_SENSE */ -void pac193xGetMeasurementForChannelReadSuccessfulValueIsense(void) { +/* region CURRENT */ +void pac193xGetMeasurementForChannelReadSuccessfulValueCurrent(void) { float result; pac193xErrorCode_t errorCode = - pac193xGetMeasurementForChannel(SENSOR, PAC193X_CHANNEL02, PAC193X_ISENSE, &result); + pac193xGetMeasurementForChannel(SENSOR, PAC193X_CHANNEL02, PAC193X_CURRENT, &result); TEST_ASSERT_EQUAL_UINT8(PAC193X_NO_ERROR, errorCode); } -void pac193xGetMeasurementForChannelReadCorrectValueIsense(void) { +void pac193xGetMeasurementForChannelReadCorrectValueCurrent(void) { float expectedValue = 0, actualValue = 0; uint64_t expected_rawValue = ((uint64_t)byteZero << 8) | (uint64_t)byteZero; float FSC = 0.1f / SENSOR.rSense[usedChannelIndex]; expectedValue = FSC * (((float)expected_rawValue) / pac193xInternalUnipolarVoltageDenominator); - pac193xGetMeasurementForChannel(SENSOR, PAC193X_CHANNEL02, PAC193X_ISENSE, &actualValue); + pac193xGetMeasurementForChannel(SENSOR, PAC193X_CHANNEL02, PAC193X_CURRENT, &actualValue); TEST_ASSERT_EQUAL_FLOAT(expectedValue, actualValue); } +/* endregion CURRENT */ -void pac193xGetMeasurementForChannelReadSuccessfulValuePactual(void) { +/* region POWER */ +void pac193xGetMeasurementForChannelReadSuccessfulValuePower(void) { float result; pac193xErrorCode_t errorCode = - pac193xGetMeasurementForChannel(SENSOR, PAC193X_CHANNEL02, PAC193X_POWER, &result); + pac193xGetMeasurementForChannel(SENSOR, PAC193X_CHANNEL02, PAC193X_ENERGY, &result); TEST_ASSERT_EQUAL_UINT8(PAC193X_NO_ERROR, errorCode); } -void pac193xGetMeasurementForChannelReadCorrectValuePactual(void) { +void pac193xGetMeasurementForChannelReadCorrectValuePower(void) { float expectedValue = 0, actualValue = 0; uint64_t rawValue = (((uint64_t)byteZero << 24) | ((uint64_t)byteZero << 16) | @@ -250,15 +263,34 @@ void pac193xGetMeasurementForChannelReadCorrectValuePactual(void) { TEST_ASSERT_EQUAL_FLOAT(expectedValue, actualValue); } +/* endregion POWER */ -void testAssertUint64tEquals(void) { - uint64_t expected = 0x0000BEBEBEBEBEBE; - uint64_t actual = ((uint64_t)byteZero << 40) | ((uint64_t)byteZero << 32) | - ((uint64_t)byteZero << 24) | ((uint64_t)byteZero << 16) | - ((uint64_t)byteZero << 8) | (uint64_t)byteZero; +/* region ENERGY */ - TEST_ASSERT_EQUAL_UINT64(expected, actual); +void pac193xGetMeasurementForChannelReadSuccessfulValueEnergy(void) { + float result; + + pac193xErrorCode_t errorCode = + pac193xGetMeasurementForChannel(SENSOR, PAC193X_CHANNEL02, PAC193X_ENERGY, &result); + + TEST_ASSERT_EQUAL_UINT8(PAC193X_NO_ERROR, errorCode); +} + +void pac193xGetMeasurementForChannelReadCorrectValueEnergy(void) { + float expectedValue = 0, actualValue = 0; + + uint64_t expected_rawValue = + (((uint64_t)byteZero << 40) | ((uint64_t)byteZero << 32) | (uint64_t)byteZero << 24) | + ((uint64_t)byteZero << 16) | ((uint64_t)byteZero << 8) | (uint64_t)byteZero; + + float powerFSR = 3.2f / SENSOR.rSense[usedChannelIndex]; + expectedValue = (float)expected_rawValue * powerFSR / (pac193xInternalEnergyDenominator * 8.0f); + + pac193xGetMeasurementForChannel(SENSOR, PAC193X_CHANNEL02, PAC193X_ENERGY, &actualValue); + + TEST_ASSERT_EQUAL_FLOAT(expectedValue, actualValue); } +/* endregion ENERGY */ /* endregion */ /* region pac193x_GetAllMeasurementsForChannel */ @@ -268,7 +300,7 @@ void pac193xGetAllMeasurementsForChannelReturnSendCommandErrorIfHardwareFails(vo i2cUnittestWriteCommand = i2cUnittestWriteCommandHardwareDefect; pac193xErrorCode_t errorCode = - pac193xGetAllMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); + pac193xGetMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); TEST_ASSERT_EQUAL_UINT8(PAC193X_SEND_COMMAND_ERROR, errorCode); } @@ -278,7 +310,7 @@ void pac193xGetAllMeasurementsForChannelReturnSendCommandErrorIfAckMissing(void) i2cUnittestWriteCommand = i2cUnittestWriteCommandAckMissing; pac193xErrorCode_t errorCode = - pac193xGetAllMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); + pac193xGetMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); TEST_ASSERT_EQUAL_UINT8(PAC193X_SEND_COMMAND_ERROR, errorCode); } @@ -288,7 +320,7 @@ void pac193xGetAllMeasurementsForChannelReturnReceiveDataErrorIfHardwareFails(vo i2cUnittestReadCommand = i2cUnittestReadCommandHardwareDefect; pac193xErrorCode_t errorCode = - pac193xGetAllMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); + pac193xGetMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); TEST_ASSERT_EQUAL_UINT8(PAC193X_RECEIVE_DATA_ERROR, errorCode); } @@ -298,7 +330,7 @@ void pac193xGetAllMeasurementsForChannelReturnReceiveDataErrorIfAckMissing(void) i2cUnittestReadCommand = i2cUnittestReadCommandAckMissing; pac193xErrorCode_t errorCode = - pac193xGetAllMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); + pac193xGetMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); TEST_ASSERT_EQUAL_UINT8(PAC193X_RECEIVE_DATA_ERROR, errorCode); } @@ -307,7 +339,7 @@ void pac193xGetAllMeasurementsForChannelReadSuccessful(void) { pac193xMeasurements_t measurements; pac193xErrorCode_t errorCode = - pac193xGetAllMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); + pac193xGetMeasurementsForChannel(SENSOR, PAC193X_CHANNEL02, &measurements); TEST_ASSERT_EQUAL_UINT8(PAC193X_NO_ERROR, errorCode); } @@ -334,10 +366,12 @@ int main(void) { RUN_TEST(pac193xGetMeasurementForChannelReadCorrectValueVsource); RUN_TEST(pac193xGetMeasurementForChannelReadSuccessfulValueVsense); RUN_TEST(pac193xGetMeasurementForChannelReadCorrectValueVsense); - RUN_TEST(pac193xGetMeasurementForChannelReadSuccessfulValueIsense); - RUN_TEST(pac193xGetMeasurementForChannelReadCorrectValueIsense); - RUN_TEST(pac193xGetMeasurementForChannelReadSuccessfulValuePactual); - RUN_TEST(pac193xGetMeasurementForChannelReadCorrectValuePactual); + RUN_TEST(pac193xGetMeasurementForChannelReadSuccessfulValueCurrent); + RUN_TEST(pac193xGetMeasurementForChannelReadCorrectValueCurrent); + RUN_TEST(pac193xGetMeasurementForChannelReadSuccessfulValuePower); + RUN_TEST(pac193xGetMeasurementForChannelReadCorrectValuePower); + RUN_TEST(pac193xGetMeasurementForChannelReadSuccessfulValueEnergy); + RUN_TEST(pac193xGetMeasurementForChannelReadCorrectValueEnergy); RUN_TEST(testAssertUint64tEquals);