// main program body int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT board_init(); // init oscilator and leds timer_init(); // init timer sht11_init(); // init sht sensor #ifdef DEBUG uart_init(); // init debug interface set_debug_value(0x0,0); // store value for debug interface set_debug_value(0x0,1); #endif while(1) { unsigned int Tval,Hval; int TvalC,HvalC; LED_GREEN_ON(); if ((sht_measure_check(&Tval,TEMP)==0) && (sht_measure_check(&Hval,HUMI)==0)) { sht2int(Tval,Hval,&TvalC,&HvalC); #ifdef DEBUG set_debug_value(int2bcd(TvalC),0); set_debug_value(int2bcd(HvalC),1); #endif } LED_GREEN_OFF(); __bis_SR_register(CPUOFF + GIE); // enter sleep mode (leave on timer interrupt) } return -1; }
void setSector(u8* sectorBuffer, s32 sectorNum) { memcpy(sectorBuffer[0], syncData, SYNC_SIZE); sectorBuffer[12] = int2bcd(sectorNum / (75 * 60)); // minutes sectorBuffer[13] = int2bcd(sectorNum / 75); // seconds sectorBuffer[14] = int2bcd(sectorNum % 75); // frames sectorBuffer[15] = 0x02; // mode2 memcpy(sectorBuffer[16], subHeader, SUB_HEADER_SIZE); }
int snapgear_rtc_settimeofday(const struct timeval *tv) { int retval = 0; int real_seconds, real_minutes, cmos_minutes; unsigned long nowtime; if (!use_ds1302) { sh_rtc_settimeofday(tv); return(0); } /* * This is called direct from the kernel timer handling code. * It is supposed to synchronize the kernel clock to the RTC. */ nowtime = tv->tv_sec; #if 1 printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime); #endif /* STOP RTC */ ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); cmos_minutes = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); /* * since we're only adjusting minutes and seconds, * don't interfere with hour overflow. This avoids * messing with unknown time zones but requires your * RTC not to be off by more than 15 minutes */ real_seconds = nowtime % 60; real_minutes = nowtime / 60; if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) real_minutes += 30; /* correct for half hour time zone */ real_minutes %= 60; if (abs(real_minutes - cmos_minutes) < 30) { ds1302_writebyte(RTC_ADDR_MIN, int2bcd(real_minutes)); ds1302_writebyte(RTC_ADDR_SEC, int2bcd(real_seconds)); } else { printk(KERN_WARNING "SnapGear RTC: can't update from %d to %d\n", cmos_minutes, real_minutes); retval = -1; } /* START RTC */ ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); return(0); }
/* * Program DS1307 with the specified time. * Must be called with tod_lock held. The TOD * chip supports date from 1969-2068 only. We must * reject requests to set date below 2000. */ static void todds1307_set(timestruc_t ts) { struct rtc_t rtc; todinfo_t tod = utc_to_tod(ts.tv_sec); int year; ASSERT(MUTEX_HELD(&tod_lock)); /* * Year is base 1900, valid year range 1969-2068 */ if ((tod.tod_year < 69) || (tod.tod_year > 168)) return; year = tod.tod_year; if (year >= 100) year -= 100; rtc.rtc_year = int2bcd(year); rtc.rtc_mon = int2bcd(tod.tod_month); rtc.rtc_dom = int2bcd(tod.tod_day); rtc.rtc_dow = int2bcd(tod.tod_dow); rtc.rtc_hrs = int2bcd(tod.tod_hour); rtc.rtc_min = int2bcd(tod.tod_min); rtc.rtc_sec = int2bcd(tod.tod_sec); todds1307_write_rtc(&rtc); }
//set RTC with unix timestamp int i2c_rtc_set_time(uint8_t sc, uint8_t mn, uint8_t hr, uint8_t dw, uint8_t dt, uint8_t mo, uint8_t yr){ //transmit the full RTC date, 7 registers // SC | MN | HR | DW | DT | MO | YR uint32_t r; uint8_t tx_data [8]; twi_packet_t packet_tx; tx_data[0] = int2bcd(sc); //sec tx_data[1] = int2bcd(mn); //min tx_data[2] = int2bcd(hr); //hour tx_data[3] = int2bcd(dw); //day of week tx_data[4] = int2bcd(dt); //date tx_data[5] = int2bcd(mo); //month tx_data[6] = int2bcd(yr); //year packet_tx.chip = RTC_ADDRESS; packet_tx.addr[0] = 0x0; packet_tx.addr_length = 1; packet_tx.buffer = tx_data; packet_tx.length = 7; if((r=twi_master_write(RTC_BASE_TWI, &packet_tx)) != TWI_SUCCESS){ printf("error setting RTC: %d\n",(int)r); return -1; } return 0; }
void rtc_set_time(uint32_t timestamp) { int16_t year, doy; int8_t hour, min, sec, day, mon, isdst, weekday; // 0 1 2 3 4 5 6 // seconds, minutes, hours, days, weekdays, months, years uint8_t date[7]; uint8_t control_status; // nach utc date_timestamp2human(timestamp, 0, &year, &doy, &hour, &min, &sec, &isdst); date_doy2daymon(doy, year, &day, &mon); weekday = date_wday(doy, year) + 1; date[0] = int2bcd(sec); date[1] = int2bcd(min); date[2] = int2bcd(hour); date[3] = int2bcd(day); date[4] = int2bcd(weekday); date[5] = int2bcd(mon); date[6] = int2bcd(year-2000); rtc_write_page(RTC_PAGE_CLOCK, date, 7); control_status = rtc_read(RTC_PAGE_CONTROL | RTC_CONTROL_INT_FLAGS); control_status &= ~(1 << 5); rtc_write(RTC_PAGE_CONTROL | RTC_CONTROL_INT_FLAGS, control_status); }
static void apm_set_timer(int fd, int delta) { time_t tmr; struct tm *tm; struct apm_bios_arg args; tmr = time(NULL) + delta; if (cmos_wall) tm = localtime(&tmr); else tm = gmtime(&tmr); bzero(&args, sizeof(args)); args.eax = (APM_BIOS) << 8 | APM_RESUMETIMER; args.ebx = PMDV_APMBIOS; if (delta > 0) { args.ecx = (int2bcd(tm->tm_sec) << 8) | 0x02; args.edx = (int2bcd(tm->tm_hour) << 8) | int2bcd(tm->tm_min); args.esi = (int2bcd(tm->tm_mon + 1) << 8) | int2bcd(tm->tm_mday); args.edi = int2bcd(tm->tm_year + 1900); } else { args.ecx = 0x0000; } if (ioctl(fd, APMIO_BIOS, &args)) { err(1,"set resume timer"); } }
/* Set the time in the RTC */ void pcf8583_set(struct tm *time) { union { uint8_t bytes[5]; uint16_t words[2]; } tmp; if (rtc_state == RTC_NOT_FOUND) return; i2c_write_register(PCF8583_ADDR, REG_CONTROL, CTL_STOP_CLOCK); tmp.bytes[0] = int2bcd(time->tm_sec); tmp.bytes[1] = int2bcd(time->tm_min); tmp.bytes[2] = int2bcd(time->tm_hour); tmp.bytes[3] = int2bcd(time->tm_mday) | ((time->tm_year & 3) << 6); tmp.bytes[4] = int2bcd(time->tm_mon+1)| ((time->tm_wday ) << 5); i2c_write_registers(PCF8583_ADDR, REG_SECONDS, 5, &tmp); tmp.words[0] = time->tm_year + 1900; tmp.words[1] = (time->tm_year + 1900) ^ 0xffffU; i2c_write_registers(PCF8583_ADDR, REG_YEAR1, 4, &tmp); i2c_write_register(PCF8583_ADDR, REG_CONTROL, CTL_START_CLOCK); rtc_state = RTC_OK; }
/* Set the time in the RTC */ void dsrtc_set(struct tm *time) { uint8_t tmp[7]; if (rtc_state == RTC_NOT_FOUND) return; tmp[REG_SECOND] = int2bcd(time->tm_sec); tmp[REG_MINUTE] = int2bcd(time->tm_min); tmp[REG_HOUR] = int2bcd(time->tm_hour); tmp[REG_DOW] = int2bcd(time->tm_wday+1); tmp[REG_DOM] = int2bcd(time->tm_mday); tmp[REG_MONTH] = int2bcd(time->tm_mon+1) | 0x80 * (time->tm_year >= 2100); tmp[REG_YEAR] = int2bcd(time->tm_year % 100); i2c_write_registers(RTC_ADDR, REG_SECOND, 7, tmp); i2c_write_register(RTC_ADDR, REG_CONTROL, 0); // 3231: enable oscillator on battery, interrupts off // 1307: disable SQW output #ifdef CONFIG_RTC_DS3231 i2c_write_register(RTC_ADDR, REG_CTLSTATUS, 0); // clear "oscillator stopped" flag #endif rtc_state = RTC_OK; }
/// test body int main(int argc, char *argv[]) { uint16_t tReg = 0; uint16_t hReg = 0; int16_t tVal = 0; int16_t hVal = 0; if (argc==3) // if reg values given in args - just compute one result { // get values from input args if (argv[2][strlen(argv[2])-1]=='h') sscanf(argv[2],"%X",(unsigned int*)&hReg); else sscanf(argv[2],"%d",(unsigned int*)&hReg); if (argv[1][strlen(argv[1])-1]=='h') sscanf(argv[1],"%X",(unsigned int*)&tReg); else sscanf(argv[1],"%d",(unsigned int*)&tReg); // show it printf("temp.reg.: 0x%04X; humi.reg.: 0x%04X\n",tReg,hReg); // convert sht2int_double(tReg,hReg,&tVal,&hVal); // show result printf("\nTemp(int): %d; Hum(int): %d\n",tVal,hVal); // test int2bcd function printf("Temp(bcd): %X; Hum(bcd): %X\n",int2bcd(tVal),int2bcd(hVal)); return 0; } int16_t tValF, hValF; uint16_t eTmax=0, eHmax=0; double eTavg=0, eHavg=0; double cnt=0.0; printf("Converting all 2^26 combinations ... "); clock_t start = clock(); while(1) { cnt+=1.0; // convert sht2int_double(tReg,hReg,&tVal,&hVal); // convert (other way) sht2int(tReg,hReg,&tValF,&hValF); int e = abs(tValF-tVal); eTavg+=e; if (eTmax<e) eTmax=e; e = abs(hValF-hVal); eHavg+=e; if (eHmax<e) eHmax=e; // values for next conversion hReg ++; if (hReg==4096) {hReg=0;tReg++;} if (tReg==16384) break; } eTavg/=cnt; eHavg/=cnt; printf ( "%.2fs\n", ( (double)clock() - start ) / CLOCKS_PER_SEC ); printf("Max errors T: %d, H: %d\n",eTmax,eHmax); printf("Avg error (%.0f samples) T: %f, H: %f",cnt,eTavg,eHavg); return 0; }