void nrk_kernel_error_add (uint8_t n, uint8_t task) { error_num = n; error_task = task; #ifdef NRK_LOG_ERRORS _nrk_log_error(error_num, error_task); #endif #ifdef NRK_REPORT_ERRORS nrk_error_print (); #endif /* */ #ifdef NRK_SOFT_REBOOT_ON_ERROR #ifdef NRK_WATCHDOG nrk_watchdog_disable(); #endif asm volatile("jmp 0x0000\n\t" ::); #endif #ifdef NRK_REBOOT_ON_ERROR // wait for watchdog to kick in if(n!=NRK_WATCHDOG_ERROR && n!=NRK_BOD_ERROR && n!=NRK_EXT_RST_ERROR) { nrk_watchdog_enable(); nrk_int_disable(); while(1); } #endif #ifdef NRK_HALT_ON_ERROR uint8_t t; uint8_t i; while (1) { for(i=0; i<20; i++ ) { nrk_led_set (2); nrk_led_clr (3); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); nrk_led_set (3); nrk_led_clr (2); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); } nrk_led_clr (3); nrk_led_clr (2); blink_morse_code_error( task ); blink_morse_code_error( n ); } #endif /* */ }
int main () { nrk_setup_ports(); nrk_setup_uart(UART_BAUDRATE_115K2); DDRF=0xff; while(1) { PORTF=0xff; nrk_spin_wait_us(500); PORTF=0x00; nrk_spin_wait_us(500); } nrk_init(); nrk_led_clr(ORANGE_LED); nrk_led_clr(BLUE_LED); nrk_led_clr(GREEN_LED); nrk_led_clr(RED_LED); nrk_time_set(0,0); nrk_create_taskset (); nrk_start(); return 0; }
void rf_security_set_key(uint8_t *key) { uint8_t n,i; uint16_t key_buf; // Set AES key nrk_spin_wait_us(100); for(i=0; i<8; i++ ) { key_buf=(key[i]<<8)|key[i+1]; nrk_spin_wait_us(100); FASTSPI_WRITE_RAM_LE(&key_buf,(CC2420RAM_KEY0+(i*2)),2,n); } // Set AES nonce to all zeros nrk_spin_wait_us(100); for(i=0; i<7; i++ ) { key_buf=0; FASTSPI_WRITE_RAM_LE(&key_buf,(CC2420RAM_TXNONCE+(i*2)),2,n); FASTSPI_WRITE_RAM_LE(&key_buf,(CC2420RAM_RXNONCE+(i*2)),2,n); } // block counter set 1 key_buf=1; FASTSPI_WRITE_RAM_LE(&key_buf,(CC2420RAM_TXNONCE+14),2,n); FASTSPI_WRITE_RAM_LE(&key_buf,(CC2420RAM_RXNONCE+14),2,n); }
void rf_addr_decode_set_my_mac(uint16_t my_mac) { uint8_t n; rfSettings.myAddr = my_mac; nrk_spin_wait_us(500); cc2420WriteRamLE((uint8 *)&my_mac, CC2420RAM_SHORTADDR, 2); nrk_spin_wait_us(500); }
void rf_addr_decode_set_my_mac(uint16_t my_mac) { uint8_t n; rfSettings.myAddr = my_mac; nrk_spin_wait_us(500); FASTSPI_WRITE_RAM_LE(&my_mac, CC2420RAM_SHORTADDR, 2, n); nrk_spin_wait_us(500); }
void rf_carrier_on(void) { // Force RF FSM to Tx state to give channel activity mrf_write_short(RFCTL, 0x06); nrk_spin_wait_us(192); mrf_write_short(RFCTL, 0x02); nrk_spin_wait_us(192); }
void rf_carrier_off(void) { // Reset RF FSM to normal operation mrf_write_short(RFCTL, 0x04); nrk_spin_wait_us(192); mrf_write_short(RFCTL, 0x00); nrk_spin_wait_us(192); }
void mrf_test_mode(void) { mrf_write_long(0x22F, 0x08 | 5); // Put into single-tone test mode nrk_spin_wait_us(500); // Force RF FSM to Tx state mrf_write_short(RFCTL, 0x06); nrk_spin_wait_us(192); mrf_write_short(RFCTL, 0x02); nrk_spin_wait_us(192); }
void mrf_write_short(uint8_t addr, uint8_t data) { mrf_cs_set(0); nrk_spin_wait_us(1); mrf_spi_write(((addr << 1) & 0x7E) | 0x01); nrk_spin_wait_us(1); mrf_spi_write(data); nrk_spin_wait_us(1); mrf_cs_set(1); nrk_spin_wait_us(1); }
void mrf_data_mode(void) { mrf_write_long(0x22F, 0x08); // Put back into default mode nrk_spin_wait_us(500); // Reset RF FSM to normal operation mrf_write_short(RFCTL, 0x04); nrk_spin_wait_us(192); mrf_write_short(RFCTL, 0x00); nrk_spin_wait_us(192); }
void mrf_write_long(uint16_t addr, uint8_t data) { mrf_cs_set(0); nrk_spin_wait_us(1); mrf_spi_write((addr >> 3) | 0x80); nrk_spin_wait_us(1); mrf_spi_write(((addr << 5) & 0xE0) | 0x10); nrk_spin_wait_us(1); mrf_spi_write(data); nrk_spin_wait_us(1); mrf_cs_set(1); nrk_spin_wait_us(1); }
uint8_t mrf_read_short(uint8_t addr) { uint8_t result; mrf_cs_set(0); nrk_spin_wait_us(1); mrf_spi_write((addr << 1) & 0x7E); nrk_spin_wait_us(1); result = mrf_spi_write(0xFF); nrk_spin_wait_us(1); mrf_cs_set(1); nrk_spin_wait_us(1); return result; }
// 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; } }
static int8_t twi_tx(uint8_t *buf, uint8_t len) { uint8_t i; uint8_t waits = 0; const uint8_t max_waits = TIME_TO_MS(twi_tx_timeout) / TIME_TO_MS(twi_tx_poll_interval); LOG("TWI write: "); for (i = 0; i < len; ++i) LOGP("0x%x ", msg_buf[i]); LOGA("\r\n"); TWI_Start_Transceiver_With_Data(msg_buf, len); /* NOTE: can't use nrk_time_get because before nrk_start() */ while (TWI_Transceiver_Busy() && waits++ < max_waits) nrk_spin_wait_us(twi_tx_poll_interval.nano_secs / 1000); if (waits >= max_waits) { LOG("WARN: TWI write timed out\r\n"); return NRK_ERROR; } if (!TWI_statusReg.lastTransOK) { LOG("WARN: TWI write failed\r\n"); handle_error(TWI_Get_State_Info()); return NRK_ERROR; } return NRK_OK; }
int8_t _bmac_rx() { int8_t n; uint8_t cnt; rf_set_rx (&bmac_rfRxInfo, g_chan); rf_polling_rx_on (); cnt=0; while ((n = rf_rx_check_fifop()) == 0) { cnt++; nrk_wait(_bmac_check_period); if(cnt>2) { #ifdef DEBUG printf( "rx timeout 1 %d\r\n",cnt ); #endif if(rx_failure_cnt<65535) rx_failure_cnt++; rf_rx_off(); return 0; } } if (n != 0) { n = 0; // Packet on its way cnt=0; while ((n = rf_polling_rx_packet ()) == 0) { cnt++; nrk_spin_wait_us(100); if (cnt > 50) { #ifdef DEBUG printf( "rx timeout 2\r\n" ); #endif rx_failure_cnt++; rf_rx_off(); return 0; } } } rf_rx_off(); if (n == 1) { // CRC and checksum passed rx_buf_empty=0; #ifdef DEBUG printf( "BMAC: SNR= %d [",bmac_rfRxInfo.rssi ); for(uint8_t i=0; i<bmac_rfRxInfo.length; i++ ) printf( "%c", bmac_rfRxInfo.pPayload[i]); printf( "]\r\n" ); #endif return 1; } else { #ifdef DEBUG printf( "CRC failed!\r\n" ); #endif rx_failure_cnt++; return 0; } rx_failure_cnt++; return 0; }
void rf_power_up(void) { // Cycle REGWAKE bit 6 (remember to leave IMMWAKE set) mrf_write_short(WAKECON, 0xC0); mrf_write_short(WAKECON, 0x80); nrk_spin_wait_us(2*1000); // 2ms to stabilize main oscillator }
uint8_t mrf_read_long(uint16_t addr) { uint8_t value; mrf_cs_set(0); nrk_spin_wait_us(1); mrf_spi_write((addr >> 3) | 0x80); nrk_spin_wait_us(1); mrf_spi_write((addr << 5) & 0xE0); nrk_spin_wait_us(1); value = mrf_spi_write(0xFF); nrk_spin_wait_us(1); mrf_cs_set(1); nrk_spin_wait_us(1); //printf("value=%d",value); return value; }
void mrf_reset(void) { mrf_cs_set(1); mrf_reset_set(0); nrk_spin_wait_us(100); mrf_reset_set(1); nrk_spin_wait_us(100); // Software RF reset mrf_write_short(RFCTL, 0x04); mrf_write_short(RFCTL, 0x00); // Flush Rx FIFO mrf_write_short(RXFLUSH, 0x01); // Enable and configure radio mrf_write_long(RFCON0, 0xE3); // Set to channel 25 (2.475 GHz) mrf_write_long(RFCON1, 0x02); // Set VCO param to 2 mrf_write_long(RFCON2, 0x80); // Enable PLL mrf_write_long(RFCON3, 0x00); // Max Rx/Tx power mrf_write_long(RFCON6, 0x90); // Enable Tx filter, faster sleep recovery mrf_write_long(RFCON7, 0x80); // Set 100kHz internal clock as slpclk mrf_write_long(RFCON8, 0x10); // Enable VCO mrf_write_long(SLPCON1, 0x20); // Disable CLKOUT, set slpclk div to 1 mrf_write_short(RXMCR, 0x01); // Ignore address field mrf_write_short(BBREG2, 0x80); // Set CCA mode to energy detect mrf_write_short(BBREG6, 0x40); // Append RSSI to each packet mrf_write_short(CCAEDTH, 0x00); // Set RSSI threshold to minimum // Configure for ACK requests mrf_write_short(TXNCON, 0x04); // Enable ACK request // Interrupt configuration mrf_write_short(INTCON, ~(0x09)); // Enable Rx and Tx(N) interrupts (bits active-low) mrf_write_long(SLPCON0, 0x02); // Set interrupt polarity to rising edge // Sleep configuration mrf_write_short(WAKECON, 0x80); // Enable immediate wake-up // Software RF reset, with new settings mrf_write_short(RFCTL, 0x04); mrf_write_short(RFCTL, 0x00); }
void rf_power_up() { DISABLE_GLOBAL_INT(); FASTSPI_STROBE(CC2420_SXOSCON); nrk_spin_wait_us(OSC_STARTUP_DELAY); ENABLE_GLOBAL_INT(); }
void put_byte (uint8_t c) { if (g_delay > 0) nrk_spin_wait_us (g_delay * 1000); fputc (c, g_dv_out); if (g_echo) { // Not IMPLEMENTED } }
int8_t _bmac_channel_check() { int8_t val; rf_polling_rx_on(); nrk_spin_wait_us(250); val=CCA_IS_1; if(val) rf_rx_off(); return val; }
int8_t _bmac_channel_check() { int8_t val; rf_polling_rx_on(); nrk_spin_wait_us(250); rf_rx_check_cca(); // Run once to throw out (possibly) stale data val = rf_rx_check_cca(); if(val) rf_rx_off(); return val; }
void Task3 () { int8_t v; uint8_t pckts=0; printf ("radio stuff Task3 PID=%d\r\n", nrk_get_pid ()); while (slip_started () != 1) nrk_wait_until_next_period (); while (1) { v = slip_rx (slip_rx_buf, MAX_SLIP_BUF); printf("nanork@ bytesread %d\n",v); //for (i=0;i<v;i++) printf("<%d>",slip_rx_buf[i]); //printf("\n"); if (v > HDR_SIZE) { ack_buf[0] = 'Z'; ack_buf[1] = slip_rx_buf[1]; ack_buf[2] = slip_rx_buf[2]; while(uart_tx_busy==1) nrk_wait_until_next_period(); uart_tx_busy=1; slip_tx (ack_buf, 3); uart_tx_busy=0; rfTxInfo.pPayload = slip_rx_buf; rfTxInfo.length= v; rfTxInfo.destAddr = 0xFFFF; rfTxInfo.cca = 0; rfTxInfo.ackRequest = 0; nrk_led_toggle (RED_LED); pckts++; PORTG=0x1; if(rf_tx_packet(&rfTxInfo) != 1) { printf("--- RF_TX ERROR ---\r\n"); nrk_spin_wait_us(10000); } } } }
void rf_polling_rx_on(void) { #ifdef RADIO_PRIORITY_CEILING nrk_sem_pend (radio_sem); #endif rfSettings.receiveOn = TRUE; #ifdef CC2420_OSC_OPT FASTSPI_STROBE(CC2420_SXOSCON); nrk_spin_wait_us(OSC_STARTUP_DELAY); #endif FASTSPI_STROBE(CC2420_SRXON); FASTSPI_STROBE(CC2420_SFLUSHRX); rx_ready=0; #ifdef RADIO_PRIORITY_CEILING nrk_sem_post(radio_sem); #endif } // rf_rx_on()
// This function used to initialize the onchip ADC for interrupt mode. void initOnChipADC() { ADCSRA = BM(ADPS0) | BM(ADPS1) | BM(ADIE); // Enabling the interrupt as well. ADMUX = BM(REFS0); // we are setting the channel to zero initially. // enable the ADC now. ADC_ENABLE(); // Delay. nrk_spin_wait_us(ADC_SETUP_DELAY); ADC_SET_CHANNEL(ACCEL_CHANEL_Z); // start the ADC conversion; ADCSRA |= BM(ADSC); }
int main() { uint8_t led = 0; nrk_setup_ports(); nrk_led_clr(ORANGE_LED); nrk_led_clr(BLUE_LED); nrk_led_clr(GREEN_LED); nrk_led_clr(RED_LED); while (1) { nrk_led_toggle(ORANGE_LED); nrk_spin_wait_us(PERIOD); } return 0; }
void Task1() { uint16_t cnt; int8_t i,fd,val; uint16_t buf; printf( "My node's address is %d\r\n",NODE_ADDR ); printf( "Task1 PID=%d\r\n",nrk_get_pid()); cnt=0; while(1) { // Open ADC device as read fd=nrk_open(FIREFLY_SENSOR_BASIC,READ); if(fd==NRK_ERROR) nrk_kprintf(PSTR("Failed to open sensor driver\r\n")); nrk_led_toggle(BLUE_LED); // Example of setting a sensor val=nrk_set_status(fd,SENSOR_SELECT,BAT); // Read battery first while other sensors warm up val=nrk_read(fd,&buf,2); printf( "Task bat=%d",buf); val=nrk_set_status(fd,SENSOR_SELECT,LIGHT); val=nrk_read(fd,&buf,2); printf( " light=%d",buf); val=nrk_set_status(fd,SENSOR_SELECT,TEMP); val=nrk_read(fd,&buf,2); printf( " temp=%d",buf); val=nrk_set_status(fd,SENSOR_SELECT,ACC_X); val=nrk_read(fd,&buf,2); printf( " acc_x=%d",buf); val=nrk_set_status(fd,SENSOR_SELECT,ACC_Y); val=nrk_read(fd,&buf,2); printf( " acc_y=%d",buf); val=nrk_set_status(fd,SENSOR_SELECT,ACC_Z); val=nrk_read(fd,&buf,2); printf( " acc_z=%d",buf); val=nrk_set_status(fd,SENSOR_SELECT,AUDIO_P2P); nrk_spin_wait_us(60000); val=nrk_read(fd,&buf,2); printf( " audio=%d\r\n",buf); nrk_close(fd); nrk_wait_until_next_period(); cnt++; } }
/********************************************************** * start sending a carrier pulse * assumes wdrf_radio_test_mode() was called before doing this */ void rf_carrier_on() { #ifdef RADIO_PRIORITY_CEILING nrk_sem_pend(radio_sem); #endif #ifdef CC2420_OSC_OPT FASTSPI_STROBE(CC2420_SXOSCON); nrk_spin_wait_us(OSC_STARTUP_DELAY); #endif FASTSPI_STROBE(CC2420_STXON); // tell radio to start sending #ifdef RADIO_PRIORITY_CEILING nrk_sem_post(radio_sem); #endif }
void Task1() { nrk_kprintf( PSTR("Nano-RK Version ") ); printf( "%d\r\n",NRK_VERSION ); start_time.secs=0; start_time.nano_secs=0; end_time.secs=0; end_time.nano_secs=0; start_time_1.secs=0; start_time_1.nano_secs=0; end_time_1.secs=0; end_time_1.nano_secs=0; while (1) { // Measure time with code inbetween nrk_time_get(&start_time); nrk_time_get(&end_time); printf("####### NO WAIT BETWEEN READINGS #########\r\n"); printf("start: %lu %lu\r\n",start_time.secs,start_time.nano_secs); printf(" end: %lu %lu\r\n",end_time.secs,end_time.nano_secs); printf("end.nano - start.nano: %lu\r\n",end_time.nano_secs-start_time.nano_secs); //printf("start.nano - end.nano: %lu\r\n",start_time.nano_secs-end_time.nano_secs); // Measure time with code inbetween nrk_time_get(&start_time_1); nrk_spin_wait_us(200); nrk_time_get(&end_time_1); printf("####### 200us BETWEEN READINGS #########\r\n"); printf("start: %lu %lu\r\n",start_time_1.secs,start_time_1.nano_secs); printf(" end: %lu %lu\r\n",end_time_1.secs,end_time_1.nano_secs); printf("end.nano - start.nano: %lu\r\n",end_time_1.nano_secs-start_time_1.nano_secs); nrk_wait_until_next_period(); } }
void nrk_idle_task() { volatile unsigned char *stkc; // unsigned int *stk ; // 2 bytes while(1) { nrk_stack_check(); if(_nrk_get_next_wakeup()<=NRK_SLEEP_WAKEUP_TIME) { _nrk_cpu_state=1; nrk_idle(); } else { #ifndef NRK_NO_POWER_DOWN // Allow last UART byte to get out nrk_spin_wait_us(10); _nrk_cpu_state=2; nrk_sleep(); #else nrk_idle(); #endif } #ifdef NRK_STACK_CHECK if(nrk_idle_task_stk[0]!=STK_CANARY_VAL) nrk_error_add(NRK_STACK_SMASH); #ifdef KERNEL_STK_ARRAY if(nrk_kernel_stk[0]!=STK_CANARY_VAL) nrk_error_add(NRK_STACK_SMASH); #else stkc=(unsigned char*)(NRK_KERNEL_STK_TOP-NRK_KERNEL_STACKSIZE); if(*stkc!=STK_CANARY_VAL) nrk_error_add(NRK_STACK_SMASH); #endif #endif } }