int Types_RegisterTypedef(const char *Name, size_t NameLen, const tType *Type) { DEBUG_NL("(Name=%.*s, Type=", (int)NameLen, Name); IF_DEBUG( Types_Print(stdout, Type) ); DEBUG_S(")\n"); tTypedef **pnp = &gpTypedefs; for( tTypedef *td = gpTypedefs; td; pnp = &td->Next, td = td->Next ) { int cmp = strncmp(td->Name, Name, NameLen); if( cmp > 0 ) break; if( cmp == 0 && strlen(td->Name) == NameLen ) { if( Types_Compare(td->Base, Type) != 0 ) { // Error! Incompatible redefinition return -1; } // Compatible redefinition return 1; } } tTypedef *td = malloc( sizeof(tTypedef) + NameLen + 1 ); td->Name = (char*)(td + 1); memcpy(td+1, Name, NameLen); ((char*)(td+1))[NameLen] = 0; td->Base = Type; td->Next = *pnp; *pnp = td; return 0; }
tType *Types_Register(const tType *Type) { DEBUG("(Type=%p)", Type); DEBUG_NL("Type="); IF_DEBUG( Types_Print(stdout, Type) ); DEBUG_S("\n"); tType **retp = bsearch(&Type, gpTypeCache, giTypeCacheSize, sizeof(void*), Types_Compare_I); if(retp) { assert(*retp); DEBUG("RETURN %p (cached)", *retp); return *retp; } gpTypeCache = realloc(gpTypeCache, (giTypeCacheSize+1)*sizeof(void*)); assert(gpTypeCache); tType *ret = malloc( sizeof(tType) ); *ret = *Type; gpTypeCache[giTypeCacheSize] = ret; giTypeCacheSize ++; qsort(gpTypeCache, giTypeCacheSize, sizeof(void*), Types_Compare_I); DEBUG("RETURN %p (new)", ret); return ret; }
/** * Queries the mode and pid, and checks for given length */ bool query(int mode, int pid, int expectedLength) { DEBUG("query()"); //Flush invalid and echoed data flush(); //Reset rxPos rxPos = 0; //Send query if (mode < 16) serial->print("0"); serial->print(mode, HEX); if (pid < 16) serial->print("0"); serial->print(pid, HEX); serial->print( F("\r") ); //Loop until either expected size or timeout reached int len = fillBuffer(cbuf, 5000); //Evaluate buffer if (len > 0) { //Buffer filled, parse it int dataLen = parse(cbuf, len); DEBUG_1("dataLen == "); DEBUG_1(dataLen); DEBUG_NL(); //Check received bytes if (dataLen == expectedLength) { //size match DEBUG("query() size match"); return true; } else if (dataLen > expectedLength) { //oversized DEBUG("query() oversized"); return false; } } else return false; }
/** * fills the given buffer until the timeout is reached or eol char is received */ int fillBuffer(char* cbuf, long timeout) { int pos = 0; long then = millis() + timeout; DEBUG("Buffering: -->"); while (millis() < then && pos < (BUFFER_SIZE-1) ) { if (serial->available() > 0) { //Shove received byte into buffer char c = serial->read(); DEBUG_HEX(c); if (c != '\n' && c != '\r') { DEBUG_1(","); DEBUG_1(c); } DEBUG_1(":"); cbuf[pos++] = c; if (c == '\r' || c == '\n') { DEBUG_1( F("<-- DONE-OK: ") ); DEBUG_1(pos); DEBUG_NL(); return pos; } } } DEBUG("<-- DONE-FAIL!"); DEBUG_NL(); return -1; }
/** * Flushes all incoming data */ void flush() { DEBUG("Flush()"); while (serial->available() > 0) { char c = serial->read(); DEBUG_HEX(c); if (c != '\n' && c != '\r') { DEBUG_1(","); DEBUG_1(c); } DEBUG_1(":"); } DEBUG_NL(); }
/** * Parses a buffer and parses hexstrings: * 0-9/A-F + 0-9/A-F + ' '/'\r'/'\n' */ int parse(char* buf, int len) { DEBUG_1("Parse() len: "); DEBUG_1(len); DEBUG_NL(); for (int i=2; i<len; i++) { char upper = buf[i-2]; char lower = buf[i-1]; char trail = buf[i]; if ( ( trail == ' ' || trail == '\r' || trail == '\n' ) && ( (upper >= '0' && upper <= '9') || (upper >= 'A' && upper <= 'F') ) && ( (lower >= '0' && lower <= '9') || (lower >= 'A' && lower <= 'F') ) ){ DEBUG_1("hex value detected: "); //lower char could be a hex value byte value = 0; if (lower != '0') { //Parse lower hex value if (lower <= '9') //Numeric part value = ( lower - '0' ); else //alphanumeric part value = ( lower - 'A' + 10 ); DEBUG_1("low: "); DEBUG_1(value); } if (upper != '0') { //Parse upper hex value if (upper <= '9') //numeric part value += ( ( upper - '0' ) * 16 ); else //alphanumeric part value += ( ( upper - 'A' + 10 ) * 16 ); DEBUG_1(" high: "); DEBUG_1(value); } DEBUG_NL(); rx[rxPos++] = value; if (rxPos == RX_SIZE) //rx byte buffer filled, return return (rxPos); //shift index i += 2; } } DEBUG_1("parse() rxPos: "); DEBUG_1(rxPos); DEBUG_NL(); return (rxPos); }
void Light::task() { if(!initialized || !integrationActive) return; if(skipTask) return; if(paused) { lcd.backlight(255); wasPaused = 5; DEBUG_NL(); return; } if(wasPaused > 0) { lcd.backlight(0); wasPaused--; DEBUG_NL(); return; } if(lastSeconds == 0 || (clock.Seconds() > lastSeconds + (uint32_t)((integration * 60) / LIGHT_INTEGRATION_COUNT))) { lastSeconds = clock.Seconds(); for(uint8_t i = 0; i < LIGHT_INTEGRATION_COUNT - 1; i++) { iev[i] = iev[i + 1]; } iev[LIGHT_INTEGRATION_COUNT - 1] = readEv(); slope = readIntegratedSlopeMedian(); if(iev[LIGHT_INTEGRATION_COUNT - 1] <= NIGHT_THRESHOLD) { underThreshold = true; if(lockedSlope == 0.0 && slope) lockedSlope = slope; } else if(iev[LIGHT_INTEGRATION_COUNT - 1] > NIGHT_THRESHOLD + NIGHT_THRESHOLD_HYSTERESIS) { underThreshold = false; lockedSlope = 0.0; } median = arrayMedian50(iev, LIGHT_INTEGRATION_COUNT); float sum = 0.0; for(uint8_t i = 0; i < LIGHT_INTEGRATION_COUNT; i++) sum += iev[i]; integrated = sum / (float)(LIGHT_INTEGRATION_COUNT); if(conf.debugEnabled) { //DEBUG(STR("\r\nIEV: ")); //for(uint8_t i = 0; i < LIGHT_INTEGRATION_COUNT; i++) //{ // DEBUG(iev[i]); // DEBUG(STR(",")); //} //DEBUG_NL(); // //DEBUG(STR("#######LOCKED ")); //DEBUG(lockedSlope); //DEBUG(STR(" #######\r\n")); // //DEBUG(STR("####### SLOPE ")); //DEBUG(slope); //DEBUG(STR(" #######\r\n")); // // //DEBUG(STR("####### INT ")); //DEBUG(integrated); //DEBUG(STR(" #######\r\n")); // //DEBUG(STR("####### MED ")); //DEBUG(median); //DEBUG(STR(" #######\r\n")); // //DEBUG(STR("####### EV ")); //DEBUG(iev[LIGHT_INTEGRATION_COUNT - 1]); //DEBUG(STR(" #######\r\n")); } } }