int mon_rtc(int argc, char **argv){ int time_buf_size = MD_BUF_SIZE; char *time_buf; uint8_t yr, dt, mo, dw, hr, mn, sc; if(argc<2){ printf("wrong number of args to set time\n"); return -1; } if(strcmp(argv[1],"get")==0){ time_buf = membag_alloc(time_buf_size); if(time_buf==NULL) core_panic(); rtc_get_time_str(time_buf,time_buf_size); printf("Time: %s\n",time_buf); membag_free(time_buf); } else if(strcmp(argv[1],"set")==0){ if(argc!=9){ printf("please specify yr dt mo dw hr mn sc\n"); return -1; } yr = atoi(argv[2]); mo = atoi(argv[3]); dt = atoi(argv[4]); dw = atoi(argv[5]); hr = atoi(argv[6]); mn = atoi(argv[7]); sc = atoi(argv[8]); if(i2c_rtc_set_time(sc,mn,hr,dw,dt,mo,yr)!=0) printf("error setting RTC\n"); else{ time_buf = membag_alloc(time_buf_size); if(time_buf==NULL) core_panic(); rtc_get_time_str(time_buf,time_buf_size); printf("Set time to: %s\n",time_buf); membag_free(time_buf); } } else{ printf("bad arguments to rtc\n"); return -1; } return 0; }
// clock commands static void cmd_clock(void) { u08 cmd, value; u08 exit = 0; rtc_time t; while((cmd = get_char()) != 0) { switch(cmd) { case '?': // get time (raw) { rtc_get(t); for(int i=0;i<7;i++) { uart_send_hex_byte_space(t[i]); } uart_send_crlf(); set_result(0); } break; case 't': // get time { u08 *str = (u08 *)rtc_get_time_str(); uart_send_string(str); uart_send_crlf(); } break; case 'y': // set year value = parse_hex_byte(0); rtc_set_entry(RTC_INDEX_YEAR, value); break; case 'o': // set year value = parse_hex_byte(1); rtc_set_entry(RTC_INDEX_MONTH, value); break; case 'd': // set day value = parse_hex_byte(1); rtc_set_entry(RTC_INDEX_DAY, value); break; case 'h': // set hour value = parse_hex_byte(0); rtc_set_entry(RTC_INDEX_HOUR, value); break; case 'i': // set minute value = parse_hex_byte(1); rtc_set_entry(RTC_INDEX_MINUTE, value); break; case 's': // set seconds value = parse_hex_byte(1); rtc_set_entry(RTC_INDEX_SECOND, value); break; default: set_result(ERROR_SYNTAX); case '.': exit = 1; break; } if(exit) break; } }
int main(void) { // board setup stuff led_init(); uart_init(); floppy_low_init(); sdpin_init(); spi_low_cs_init(); spi_low_mst_init(); //timer_init(); // say hello uart_send_string((u08 *)"--- dfx-sampler sam7x/SPI ---"); uart_send_crlf(); // do initial setup rtc_init(); memory_init(); floppy_select_on(); track_init(); floppy_select_off(); net_init(); // print current RTC uart_send_string((u08 *)"rtc: "); uart_send_string((u08 *)rtc_get_time_str()); uart_send_crlf(); // show network info net_info(); while(1) { uart_send_string((u08 *)"> "); led_green(1); // get next command via SPI u08 *cmd; u08 len = cmd_uart_get_next(&cmd); led_green(0); if(len>0) { u08 result[CMD_MAX_SIZE]; u08 res_size = CMD_MAX_SIZE; // parse and execute command cmd_parse(len, cmd, &res_size, result); // report result if(res_size > 0) { uart_send_data(result, res_size); uart_send_crlf(); } } } }
///////////////////////// // core_log_power_data // Add a power_sample to the current power_pkt // When the pkt is full switch to the other pkt // (ping pong buffer). Throws an error if the // next buffer is not empty (still being TX'd) void core_log_power_data(power_sample *sample){ static int wemo_sample_idx = 0; static int dropped_pkt_count = 0; //reset wifi when this reaches MAX_DROPPED_PACKETS power_pkt *tmp_pkt; //check for error conditions switch(cur_pkt->status){ case POWER_PKT_EMPTY: if(wemo_sample_idx!=0){ printf("Error, empty packet but nonzero index\n"); return; } //set the timestamp for the packet with the first one rtc_get_time_str(cur_pkt->timestamp,PKT_TIMESTAMP_BUF_SIZE); break; case POWER_PKT_TX_IN_PROG: printf("Error, this packet is still being transmitted\n"); return; case POWER_PKT_TX_FAIL: printf("Error, this packet failed TX and isn't clean\n"); break; case POWER_PKT_READY: if(wemo_config.debug_level>=DEBUG_WARN) printf("Transmit this packet first!\n"); //see if the other buffer is ready, if so set this up for //transmission and start filling the other one if(tx_pkt->status==POWER_PKT_EMPTY){ tmp_pkt = cur_pkt; cur_pkt = tx_pkt; tx_pkt = tmp_pkt; wemo_sample_idx = 0; } return; } cur_pkt->status = POWER_PKT_FILLING; cur_pkt->vrms[wemo_sample_idx] = sample->vrms; cur_pkt->irms[wemo_sample_idx] = sample->irms; cur_pkt->watts[wemo_sample_idx] = sample->watts; cur_pkt->pavg[wemo_sample_idx] = sample->pavg; cur_pkt->freq[wemo_sample_idx] = sample->freq; cur_pkt->pf[wemo_sample_idx] = sample->pf; cur_pkt->kwh[wemo_sample_idx] = sample->kwh; wemo_sample_idx++; if(wemo_sample_idx==PKT_SIZE){ cur_pkt->status=POWER_PKT_READY; //save the packet to disk fs_write_power_pkt(cur_pkt); //see if we can switch buffers if(tx_pkt->status==POWER_PKT_EMPTY){ tmp_pkt = cur_pkt; cur_pkt = tx_pkt; tx_pkt = tmp_pkt; //reset dropped packet counter b/c successful transmission dropped_pkt_count = 0; } else { //other buffer is being TX'd, erase this one and refill cur_pkt->status=POWER_PKT_EMPTY; //if this happens [MAX_DROPPED_PACKETS] times in a row, reset the wifi //***Disable this for SmartEE since we aren't necessarily pinging it for data // all the time, if you set up a daemon to monitor the plugs, then this can be // enabled to act as a type of watchdog reset on the wifi *** if(dropped_pkt_count++ > MAX_DROPPED_PACKETS){ dropped_pkt_count = 0; core_log("lost NILM, load off and resetting WiFi"); printf("lost NILM, load off and resetting WiFi"); //turn off relay for safety (since we lost control of the plug) gpio_set_pin_low(RELAY_PIN); //restart the wifi wifi_init(); } //if(wemo_config.debug_level>=DEBUG_WARN) //printf("dropped packet before TX'd\n"); } //start filling the new buffer wemo_sample_idx = 0; } }
void core_process_wifi_data(void){ int BUF_SIZE=XL_BUF_SIZE; char *buf; int chan_num, data_size, r; unsigned int red,green,blue, blink; unsigned int yr,mo,dt,dw,hr,mn,sc; int time_buf_size = MD_BUF_SIZE; char *time_buf; //match against the data if(strlen(wifi_rx_buf)>BUF_SIZE){ printf("can't process rx'd packet, too large\n"); core_log("can't process rx'd packet, too large"); return; } //allocate memory buf = core_malloc(BUF_SIZE); r=sscanf(wifi_rx_buf,"\r\n+IPD,%d,%d:%s", &chan_num, &data_size, buf); if(r!=3){ printf("rx'd corrupt data, ignoring\n"); core_log("rx'd corrupt data, ignoring\n"); //free memory core_free(buf); return; } if(wemo_config.debug_level>DEBUG_INFO) printf("Got [%d] bytes on channel [%d]\n", data_size, chan_num); //discard responses from the NILM to power logging packets, but keep the response //if another core function has requested some data, this is done with the callback //function. The requesting core function registers a callback and this function calls //it and then resets the callback to NULL if(chan_num==4){ //close the socket wifi_send_cmd("AT+CIPCLOSE=4","Unlink",buf,BUF_SIZE,1); //execute the callback if(tx_callback!=NULL){ (*tx_callback)(wifi_rx_buf); tx_callback=NULL; } //clear the server buffer memset(wifi_rx_buf,0x0,WIFI_RX_BUF_SIZE); //free memory core_free(buf); return; } /////////////////// //this data must be inbound to the server port, process the command // // RELAY ON if(strcmp(buf,"relay_on")==0){ gpio_set_pin_high(RELAY_PIN); printf("relay ON\n"); //return "OK" to indicate success wifi_send_txt(0,"OK"); } // RELAY OFF else if(strcmp(buf,"relay_off")==0){ gpio_set_pin_low(RELAY_PIN); printf("relay OFF\n"); //return "OK" to indicate success wifi_send_txt(0,"OK"); } // LED SET else if(strstr(buf,"set_led")==buf){ if(sscanf(buf,"set_led_%u_%u_%u_%u.",&red,&green,&blue,&blink)!=4){ core_log("corrupt led_set request"); } else { rgb_led_set(red,green,blue,blink); if(wemo_config.echo) printf("set led: [%u, %u, %u, %u]\n",red,green,blue,blink); wifi_send_txt(0,"OK"); } } // RTC SET else if(strstr(buf,"set_rtc")==buf){ if(sscanf(buf,"set_rtc_%u_%u_%u_%u_%u_%u_%u.", &yr,&mo,&dt,&dw,&hr,&mn,&sc)!=7){ core_log("corrupt rtc_set request"); } else { if(i2c_rtc_set_time(sc,mn,hr,dw,dt,mo,yr)!=0) printf("error setting RTC\n"); else{ time_buf = membag_alloc(time_buf_size); if(time_buf==NULL) core_panic(); rtc_get_time_str(time_buf,time_buf_size); if(wemo_config.echo) printf("wifi set rtc to: %s\n",time_buf); core_log("wifi set rtc"); membag_free(time_buf); wifi_send_txt(0,"OK"); } } } // SEND DATA else if(strcmp(buf,"send_data")==0){ if(tx_pkt->status!=POWER_PKT_READY){ r = wifi_send_txt(chan_num,"error: no data"); if(r==TX_ERR_MODULE_RESET) while(wifi_init()!=0); //fail!!! anger!!!! reset the module } else { //send the data r=wifi_send_raw(chan_num,(uint8_t*)tx_pkt,sizeof(*tx_pkt)); if(r==TX_ERR_MODULE_RESET){ while(wifi_init()!=0); //fail!! anger!!! reset the module } else { //clear out the packet so we can start again memset(tx_pkt,0,sizeof(*tx_pkt)); tx_pkt->status=POWER_PKT_EMPTY; if(wemo_config.debug_level>=DEBUG_INFO) printf("sent data\n"); } } } else{ printf("unknown command: %s\n",buf); wifi_send_txt(chan_num,"error: unknown command"); //free memory core_free(buf); return; } //clear the server buffer memset(wifi_rx_buf,0x0,WIFI_RX_BUF_SIZE); //free the memory core_free(buf); return; }