//iD alarm proof-of-concept //(C) TechnicallyObsolete 2024 //These times are in microseconds #define ID_T_RESET 1000 #define ID_T_L1 200 #define ID_T_H_P1 150 //Sample point #define ID_T_H_P2 50 //Total delay to make up 200us #define ID_T_L_P1 150 #define ID_T_L_P2 50 typedef enum { ALARM_ID_LEVEL_OFF, ALARM_ID_LEVEL_RESET, ALARM_ID_LEVEL_LOW, ALARM_ID_LEVEL_HIGH } alarmId_level_e; //Provide these functions void delay_us(uint16_t us); uint16_t adc_read(); //Note - adc_read is presumed to be very quick. If it's not, the sample point timing above might need adjusting. void set_level(alarmId_level_e level); //Reads up to 32 devices. //Would be possible to modify to read more, but 30 devices is the common limit for an iD loop. int read_all(uint32_t deviceCount, uint32_t *alarm, uint32_t *tamper){ if ((alarm == NULL) || (tamper == NULL)) { return ERR_BAD_PARAM; } if (deviceCount > 32){ return ERR_BAD_PARAM; } uint16_t adcLevelsH[32]; uint16_t adcLevelsL[32]; uint16_t baseline; uint16_t threshold; *alarm = 0; *tamper = 0; set_level(ALARM_ID_LEVEL_RESET); delay_us(ID_T_RESET); //Measure the baseline level (current draw when not reading) and generate a threshold based on this baseline = adc_read(); threshold = baseline + 100; set_level(ALARM_ID_LEVEL_LOW); delay_us(ID_T_L1); for(uint32_t i = 0; i < deviceCount; i++){ set_level(ALARM_ID_LEVEL_HIGH); delay_us(ID_T_H_P1); adcLevelsH[i] = adc_read(); if (adcLevelsH[i] > threshold){ *tamper |= (1 << i); } delay_us(ID_T_H_P2); set_level(ALARM_ID_LEVEL_LOW); delay_us(ID_T_L_P1); adcLevelsL[i] = adc_read(); if (adcLevelsL[i] > threshold){ *alarm |= (1 << i); } delay_us(ID_T_L_P2); } //Not sure if required but makes debug easier set_level(ALARM_ID_LEVEL_OFF); for(uint32_t i = 0; i < deviceCount; i++){ syslog_logFnName(NULL, SYSLOG_LEVEL_INFO, "Slot %d ADC H=%d L=%d", i, adcLevelsH[i], adcLevelsL[i]); } syslog_logFnName(NULL, SYSLOG_LEVEL_INFO, "Returning: 0x%04X 0x%04X", *tamper, *alarm); return ERR_OK; } // TechnicallyObsolete [All rights reserved]. // // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: // // Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. // // THIS SOFTWARE IS PROVIDED BY TechnicallyObsolete “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, //BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // // IN NO EVENT SHALL TechnicallyObsolete BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, //OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; //OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.