// The task to process Console events static void btn_task(iptr_t timer) { ticks_t start = timer_clock(); ticks_t elapsed; (void)timer; DB2(LOG_INFO("Button timer...\r\n")); // LightUp all LEDS to notify calibration/reset pending LED_NOTIFY_ON(); // Wait for button release or reset timeout while (!signal_status(SIGNAL_PLAT_BUTTON)) { elapsed = timer_clock() - start; if ( ms_to_ticks(BTN_RESET_SEC*1000) <= elapsed ) { // Button pressed fot t > BTN_CHECK_SEC+BTN_RESET_SEC reset_board(); } DELAY(100); } // Button pressed BTN_CHECK_SEC < t < BTN_CHECK_SEC+BTN_RESET_SEC LED_NOTIFY_OFF(); ERR_OFF(); controlCalibration(); }
static void _Init_Semaphore(void) { DB2(bug("%s()\n", __FUNCTION__)); InitSemaphore(&sema_sem); NEWLIST(&semaphores); }
/** @brief Get a Power measure and return the measured channel */ static uint8_t sampleChannel(void) { uint16_t activeChs; // Get powered on (and enabled) channels activeChs = (getActiveChannels() & chEnabled & ~chSuspended); if (!activeChs) return MAX_CHANNELS; // If some _active_ channels are in fault mode: focus just on them only // This allows to reduce FAULTS DETECTION time perhaps also avoiding channel // switching if (chLossy && (activeChs & chLossy)) { LOG_INFO("Lossy CHs [0x%02X]\r\n", chLossy); activeChs &= chLossy; // Remain on current channel if it is _active_ and _faulty_ if (activeChs & BV16(curCh)) goto sample; // Switch to the next _active_ abd _faulty_ channel goto select; } // If some _active_ channels are in calibration mode: focus just on them only // This allows to reduce CALIBRATION time perhaps also avoiding channel // switching if (!CalibrationDone() && (activeChs & chCalib)) { DB2(LOG_INFO("Uncalibrated CHs [0x%02X]\r\n", chCalib)); activeChs &= chCalib; // Remain on current channel if it is _active_ and _uncalibrated_ if (activeChs & BV16(curCh)) goto sample; // Switch to the next _active_ abd _uncalibrated_ channel goto select; } select: // Select next active channel (max one single scan) // TODO optimize selection considering the board schematic for (uint8_t i = 0; i<MAX_CHANNELS; i++) { curCh++; if (curCh>15) curCh=0; if (BV16(curCh) & activeChs) break; } // Switch the analog MUX switchAnalogMux(curCh); sample: // Read power from ADE7753 meter readMeter(curCh); return curCh; }
static void checkSignals(void) { // Check for UNIT IRQ if (signal_pending(SIGNAL_UNIT_IRQ) && signal_status(SIGNAL_UNIT_IRQ)) { // Notify only on transitionn to LOW value notifyFault(); } // Checking for BUTTON if (signal_pending(SIGNAL_PLAT_BUTTON)) { DB2(LOG_INFO("USR BUTTON [%d]\r\n\n", signal_status(SIGNAL_PLAT_BUTTON))); buttonHandler(); } }
/** @brief Get the bitmaks of powered-on channels */ static inline uint16_t getActiveChannels(void) { static uint16_t acm = 0x0000; // Active Channels Maks // TODO put here the code to get powered on channels // NOTE: this code is on the critical path, maybe we should exploit the // I2C interrupt to handle updates just once required... if (signal_pending(SIGNAL_PLAT_I2C)) { pca9555_in(&i2c_bus, &pe, &acm); acm = ~acm; DB2(LOG_INFO("Active Channels: 0x%04X\r\n", acm)); } return acm; }
void test3(void) { printf("\nCreating an ADBList...\n"); ADBList DB1(DBTable, DBName, DBUser, DBPass, DBHost); ADBList DB2(DBTable, DBName, DBUser, DBPass, DBHost); DB1.setEncryptedColumn("blobfield"); DB2.setEncryptedColumn("blobfield"); DB1.getList(); for (long liNo = DB1.first(); liNo != 0; liNo = DB1.next()) { printf("Got row %ld from the list...blobfield = '%s'\n", liNo, DB1.getStr("blobfield")); } DB2.getList("order by InternalID desc"); for (long liNo = DB1.first(); liNo != 0; liNo = DB1.next()) { printf("Descending - Got row %ld from the list...blobfield = '%s'\n", liNo, DB1.getStr("blobfield")); } }
static inline void switchAnalogMux(uint8_t ch) { // Set an invalid channel to force actual initialization at first call static uint8_t prevAmuxCh = 0xFF; uint8_t chSel; // Avoid unnecessary switch if channel has not changed if (ch == prevAmuxCh) return; prevAmuxCh = ch; chSel = (0xF0 & PORTA); chSel |= chSelectionMap[ch]; PORTA = chSel; DB2(LOG_INFO("Switch Ch: %d => 0x%02X\r\n", ch, chSelectionMap[ch])); // Read one sample to trow away fauly ready from previous channel readMeter(ch); }
/** @brief Defines the calibration policy for each channel */ static void calibrate(uint8_t ch) { chLoad_t var; if (!chGetMoreSamples(ch) && chUncalibrated(ch)) { // Mark channel as calibrated DB(LOG_INFO("CH[%02hd] Calibration DONE, %c(cal,rms)=(%08ld,%08ld)\r\n", ch+1, CONFIG_MONITOR_POWER ? 'P' : 'I', chGetPmax(ch), chGetPrms(ch))); chMarkCalibrated(ch); return; } DB2(LOG_INFO("CH[%02hd] %c(cal,rms)=(%08ld, %08ld)...\r\n", ch+1, CONFIG_MONITOR_POWER ? 'P' : 'I', chGetPmax(ch), chGetPrms(ch))); // Decrease calibration samples required chMrkSample(ch); // Update load measure (by half of the variation) if (chGetPmax(ch) >= chGetPrms(ch)) { var = chGetPmax(ch)-chGetPrms(ch); chGetPmax(ch) -= (var/2); } else { var = chGetPrms(ch)-chGetPmax(ch); chGetPmax(ch) += (var/2); } // Mark calibration if measure is too noise if (var > (ee_getFaultLevel()/ee_getFlCalibrationDiv())) { DB(LOG_INFO("CH[%02hd] Calibrating...\r\n", ch+1)); chData[ch].calSamples = ee_getFaultSamples(); } // Keep track of others RMS values chSetImax(ch, chGetIrms(ch)); chSetVmax(ch, chGetVrms(ch)); }
LONG GetChunkHeader(struct IFFHandle *iff, struct IFFParseBase_intern *IFFParseBase) { LONG type, id, size; LONG scan = 0; LONG bytesread; D(bug("GetChunkHeader (iff=%p)\n", iff)); /* Reads in the appropriate stuff from a chunk and makes a contextnode of it */ /* Read chunk ID */ bytesread = ReadStreamLong ( iff, &id, IFFParseBase ); /* We may have an IFF Error */ if (bytesread < 0) ReturnInt ("GetChunkHeader",LONG,bytesread); /* Read chunk size */ bytesread = ReadStreamLong ( iff, &size, IFFParseBase ); if (bytesread < 0) ReturnInt ("GetChunkHeader",LONG,bytesread); /* We must see if we have a IFF header ("FORM", "CAT" or "LIST" */ if ( id == ID_FORM || id == ID_CAT || id == ID_LIST || id == ID_PROP ) { /* Read chunk size */ bytesread = ReadStreamLong ( iff, &type, IFFParseBase ); if (bytesread < 0) ReturnInt ("GetChunkHeader",LONG,bytesread); DB2(bug(" Found Chunk %c%c%c%c size=%d type %c%c%c%c\n", dmkid(id), size, dmkid(type) )); /* Type is inside chunk so we had to add its size to the scancount. */ scan = sizeof (LONG); } else { type = 0L; DB2(bug(" Found Chunk %c%c%c%c size=%d\n", dmkid(id), size )); } ReturnInt ( "GetChunkHeader", LONG, PushContextNode ( iff, type, id, size, scan, IFFParseBase ) ); }