// This is an interrupts routine that handles the button press. // It has a 300ms debounce void button_handler() { int8_t v; // Make sure button is depressed for at least 50 us nrk_spin_wait_us(50); v=nrk_gpio_get(NRK_PORTD_0); if(v!=0) return; nrk_time_get(&button_cur_press); nrk_time_sub(&button_tmp_press, button_cur_press, button_last_press ); if(button_tmp_press.secs>=1 || button_tmp_press.nano_secs>=(300*NANOS_PER_MS)) { // Reboot the node... socket_0_disable(); power_socket_disable(0); nrk_int_disable(); while(1); if(socket_0_active==1) { plug_led_green_clr(); power_socket_disable(0); } else { plug_led_green_set(); power_socket_enable(0); } button_last_press.secs=button_cur_press.secs; button_last_press.nano_secs=button_cur_press.nano_secs; } }
void tdma_error(void) { static uint16_t debounce; debounce++; if(debounce>50) debounce=50; if(debounce==50 ) { if((PIND & 0x1) == 0 ) { debounce=0; if(socket_0_active==1) { plug_led_green_clr(); power_socket_disable(0); } else { plug_led_green_set(); power_socket_enable(0); } } } if(tdma_sync_ok()==0) plug_led_red_set(); else plug_led_red_clr(); }
void io_task() { DDRD=0; while(cal_done==0) nrk_wait_until_next_period(); // Crappy polling IO task that reads the button to toggle the outlet while(1) { if(tdma_sync_ok()==0) plug_led_red_set(); else plug_led_red_clr(); if((PIND & 0x1) == 0 ) { if(socket_0_active==1) { plug_led_green_clr(); power_socket_disable(0); } else { plug_led_green_set(); power_socket_enable(0); } // After press, wait until user lets go do { nrk_wait_until_next_period(); } while((PIND & 0x1) == 0 ); } nrk_wait_until_next_period(); } }
void tx_task () { uint8_t j, i, val, cnt; int8_t len; int8_t v; nrk_sig_t tx_done_signal; nrk_sig_mask_t ret; send_ack=0; cal_done=0; printf ("tx_task PID=%d\r\n", nrk_get_pid ()); // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that power_init (); #ifndef DISABLE_BUTTON nrk_gpio_direction(NRK_BUTTON,NRK_PIN_INPUT ); nrk_ext_int_configure(NRK_EXT_INT_0, NRK_FALLING_EDGE, &button_handler ); nrk_ext_int_enable(NRK_EXT_INT_0); #endif v_center=((uint16_t)nrk_eeprom_read_byte(EEPROM_CAL_V_MSB_ADDR))<<8 | (uint16_t)nrk_eeprom_read_byte(EEPROM_CAL_V_LSB_ADDR); c_center=((uint16_t)nrk_eeprom_read_byte(EEPROM_CAL_C1_MSB_ADDR))<<8 | (uint16_t)nrk_eeprom_read_byte(EEPROM_CAL_C1_LSB_ADDR); c2_center=((uint16_t)nrk_eeprom_read_byte(EEPROM_CAL_C2_MSB_ADDR))<<8 | (uint16_t)nrk_eeprom_read_byte(EEPROM_CAL_C2_LSB_ADDR); if(((PIND & 0x1) == 0) || (v_center==0xffff) || (v_center==0x0) ) { // Get v_center and c_centers enough to grab calibration values v_center=512; c_center=512; c2_center=512; power_socket_enable(0); socket_0_disable(); plug_led_green_clr(); plug_led_red_clr(); for(i=0; i<3; i++ ) { plug_led_green_set(); nrk_wait_until_next_period(); plug_led_green_clr(); nrk_wait_until_next_period(); } plug_led_green_clr(); plug_led_red_clr(); for(i=0; i<5; i++ ) nrk_wait_until_next_period(); v_center=(v_p2p_high+v_p2p_low)/2; c_center=(c_p2p_high+c_p2p_low)/2; c2_center=(c_p2p_high2+c_p2p_low2)/2; nrk_eeprom_write_byte(EEPROM_CAL_V_MSB_ADDR, (uint8_t)(v_center>>8)); nrk_eeprom_write_byte(EEPROM_CAL_V_LSB_ADDR, (uint8_t)v_center&0xff); nrk_eeprom_write_byte(EEPROM_CAL_C1_MSB_ADDR, (uint8_t)(c_center>>8)); nrk_eeprom_write_byte(EEPROM_CAL_C1_LSB_ADDR, (uint8_t)c_center&0xff); nrk_eeprom_write_byte(EEPROM_CAL_C2_MSB_ADDR, (uint8_t)(c2_center>>8)); nrk_eeprom_write_byte(EEPROM_CAL_C2_LSB_ADDR, (uint8_t)c2_center&0xff); nrk_eeprom_write_byte(EEPROM_ENERGY1_0_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY1_1_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY1_2_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY1_3_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY1_4_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY1_5_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY1_6_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY1_7_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY2_0_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY2_1_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY2_2_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY2_3_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY2_4_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY2_5_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY2_6_ADDR, 0); nrk_eeprom_write_byte(EEPROM_ENERGY2_7_ADDR, 0); //plug_led_green_set(); //socket_0_enable(); //power_socket_enable(0); // Set default power threshold set_power_thresh(DEFAULT_POWER_THRESH); power_socket_disable(0); socket_0_disable(); }
void rx_task () { nrk_time_t t; uint16_t cnt; int8_t v; uint8_t len, i; uint8_t chan; cnt = 0; nrk_kprintf (PSTR ("Nano-RK Version ")); printf ("%d\r\n", NRK_VERSION); nrk_kprintf( PSTR( "RX Task PID=" )); printf ("%u\r\n", nrk_get_pid ()); t.secs = 5; t.nano_secs = 0; while (cal_done==0) nrk_wait_until_next_period (); chan = RADIO_CHANNEL; if (SET_MAC == 0x00) { v = read_eeprom_mac_address (&mac_address); if (v == NRK_OK) { v = read_eeprom_channel (&chan); v = read_eeprom_aes_key(aes_key); } else { while (1) { nrk_kprintf (PSTR ("* ERROR reading MAC address, run eeprom-set utility\r\n")); nrk_wait_until_next_period (); } } } else mac_address = SET_MAC; printf ("MAC ADDR: %x\r\n", mac_address & 0xffff); printf ("chan = %d\r\n", chan); len=0; for(i=0; i<16; i++ ) { len+=aes_key[i]; } printf ("AES checksum = %d\r\n", len); tdma_init (TDMA_CLIENT, chan, (mac_address)); tdma_aes_setkey(aes_key); tdma_aes_enable(); while (!tdma_started ()) nrk_wait_until_next_period (); v = tdma_tx_slot_add (mac_address&0xff); if (v != NRK_OK) nrk_kprintf (PSTR ("Could not add slot!\r\n")); // setup a software watch dog timer t.secs=30; t.nano_secs=0; nrk_sw_wdt_init(0, &t, NULL); nrk_sw_wdt_start(0); while (1) { // Update watchdog timer nrk_sw_wdt_update(0); v = tdma_recv (&rx_tdma_fd, &rx_buf, &len, TDMA_BLOCKING); if (v == NRK_OK) { // printf ("src: %u\r\nrssi: %d\r\n", rx_tdma_fd.src, rx_tdma_fd.rssi); // printf ("slot: %u\r\n", rx_tdma_fd.slot); // printf ("cycle len: %u\r\n", rx_tdma_fd.cycle_size); v=buf_to_pkt(&rx_buf, &rx_pkt); if(v==NRK_OK) { if(((rx_pkt.dst_mac&0xff) == (mac_address&0xff)) || ((rx_pkt.dst_mac&0xff)==0xff)) { if(rx_pkt.type==PING) { send_ack=1; nrk_led_clr(0); nrk_led_clr(1); if(rx_pkt.payload[0]==PING_1) { nrk_led_set(0); nrk_wait_until_next_period(); nrk_wait_until_next_period(); nrk_wait_until_next_period(); nrk_led_clr(0); } if(rx_pkt.payload[0]==PING_2) { nrk_led_set(1); nrk_wait_until_next_period(); nrk_wait_until_next_period(); nrk_wait_until_next_period(); nrk_led_clr(1); } if(rx_pkt.payload[0]==PING_PERSIST) { nrk_led_set(0); } } if(rx_pkt.type==APP) { // payload 1: Key if(rx_pkt.payload[1]==2) { send_ack=1; // payload 2: Outlet Number // payload 3: On/Off if(rx_pkt.payload[3]==0) { power_socket_disable(rx_pkt.payload[2]); plug_led_green_clr(); //printf( "Disable %d\r\n", rx_pkt.payload[2] ); } if(rx_pkt.payload[3]==1) { power_socket_enable(rx_pkt.payload[2]); //printf( "Enable %d\r\n", rx_pkt.payload[2] ); plug_led_green_set(); } } // payload 1: Key if(rx_pkt.payload[1]==3) { send_ack=1; true_power_thresh=((uint32_t)rx_pkt.payload[3])<<16 | ((uint32_t)rx_pkt.payload[4])<<8 | (uint32_t)rx_pkt.payload[5]; set_power_thresh(true_power_thresh); } } } } /* printf ("len: %u\r\npayload: ", len); for (i = 0; i < len; i++) printf ("%d ", rx_buf[i]); printf ("\r\n"); if(rx_buf[0]==(mac_address&0xff)) { if(rx_buf[2]==0) { power_socket_disable(rx_buf[1]); printf( "Disable %d\r\n", rx_buf[1] ); } if(rx_buf[2]==1) { power_socket_enable(rx_buf[1]); printf( "Enable %d\r\n", rx_buf[1] ); } } */ } tdma_rx_pkt_release(); // nrk_wait_until_next_period(); } }