Index: firmware/App/Controllers/LoadCell.c =================================================================== diff -u -rebbb1f85550a1f9b8f946655f7b2b63f76fbf67d -r76f413c7bde4ca9d12cc61e0191daddb1e86e9f1 --- firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision ebbb1f85550a1f9b8f946655f7b2b63f76fbf67d) +++ firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 76f413c7bde4ca9d12cc61e0191daddb1e86e9f1) @@ -20,6 +20,7 @@ #include "FPGA.h" #include "LoadCell.h" #include "NVDataMgmt.h" +#include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "TaskPriority.h" @@ -33,15 +34,17 @@ // TODO check the maximum weight on the load cells in tare. There was 1500 grams limit // but it has been removed. Check the load cells data sheet. -#define LOAD_CELL_REPORT_PERIOD (100 / TASK_PRIORITY_INTERVAL) ///< Broadcast load cell values message every 100 ms. +#define LOAD_CELL_REPORT_PERIOD (100 / TASK_PRIORITY_INTERVAL) ///< Broadcast load cell values message every 100 ms. /// Conversion factor from ADC counts to grams. static const F32 ADC2GRAM = (0.0894 * 1.1338); -#define LOAD_CELL_ZERO_OFFSET -1500.0 ///< Zero offset (in grams). TODO - right now, this is empty reservoir weight. -#define LOAD_CELL_FILTER_ALPHA 0.05 ///< Alpha factor for the alpha filter used on load cell readings. +#define LOAD_CELL_ZERO_OFFSET -1500.0 ///< Zero offset (in grams). TODO - right now, this is empty reservoir weight. +#define LOAD_CELL_FILTER_ALPHA 0.05 ///< Alpha factor for the alpha filter used on load cell readings. -#define SIZE_OF_SMALL_LOAD_CELL_AVG 100 ///< Small load cell moving average has 100 raw samples @ 10ms intervals (1-second). -#define SIZE_OF_LARGE_LOAD_CELL_AVG 40 ///< Large load cell moving average has 40 samples from small filter @ 100ms intervals (4-second). +#define SIZE_OF_SMALL_LOAD_CELL_AVG 100 ///< Small load cell moving average has 100 raw samples @ 10ms intervals (1-second). +#define SIZE_OF_LARGE_LOAD_CELL_AVG 40 ///< Large load cell moving average has 40 samples from small filter @ 100ms intervals (4-second). +#define LOAD_CELL_ADC_ERROR_PERSISTENCE 500 ///< Alarm persistence period (in ms) for load cell ADC errors. + /// Load cell data structure. typedef struct { @@ -131,6 +134,9 @@ loadCellsCalRecord.loadCells[ cell ].gain = 1.0; loadCellsCalRecord.loadCells[ cell ].offset = 0.0; } + + // Initialize persistent alarm(s) + initPersistentAlarm( ALARM_ID_DG_LOAD_CELL_ADC_ERROR, 0, LOAD_CELL_ADC_ERROR_PERSISTENCE ); } /*********************************************************************//** @@ -144,13 +150,27 @@ void execLoadCell( void ) { U32 ii; + U32 a1 = getFPGALoadCellA1(); + U32 a2 = getFPGALoadCellA2(); + U32 b1 = getFPGALoadCellB1(); + U32 b2 = getFPGALoadCellB2(); // update sums for load cell average calculations - loadcells[ LOAD_CELL_RESERVOIR_1_PRIMARY ].rawReading = getFPGALoadCellA1(); - loadcells[ LOAD_CELL_RESERVOIR_1_BACKUP ].rawReading = getFPGALoadCellA2(); - loadcells[ LOAD_CELL_RESERVOIR_2_PRIMARY ].rawReading = getFPGALoadCellB1(); - loadcells[ LOAD_CELL_RESERVOIR_2_BACKUP ].rawReading = getFPGALoadCellB2(); + loadcells[ LOAD_CELL_RESERVOIR_1_PRIMARY ].rawReading = a1 & MASK_OFF_U32_MSB; + loadcells[ LOAD_CELL_RESERVOIR_1_BACKUP ].rawReading = a2 & MASK_OFF_U32_MSB; + loadcells[ LOAD_CELL_RESERVOIR_2_PRIMARY ].rawReading = b1 & MASK_OFF_U32_MSB; + loadcells[ LOAD_CELL_RESERVOIR_2_BACKUP ].rawReading = b2 & MASK_OFF_U32_MSB; + // Check error bits from new readings + a1 = ( a1 >> 31 ) << SHIFT_24_BITS; + a2 = ( a2 >> 31 ) << SHIFT_16_BITS_FOR_WORD_SHIFT; + b1 = ( b1 >> 31 ) << SHIFT_8_BITS_FOR_BYTE_SHIFT; + b2 = ( b2 >> 31 ); + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DG_LOAD_CELL_ADC_ERROR, ( ( a1 > 0 ) || ( a2 > 0 ) || ( b1 > 0 ) || ( b2 > 0 ) ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_LOAD_CELL_ADC_ERROR, ( a1 | a2 | b1 | b2 ) ) + } + // Rolling average of last 100 raw samples in small filter for ( ii = 0; ii < NUM_OF_LOAD_CELLS; ++ii ) {