/*---------------------------------------------------------------------------*/ static void set_rime_addr(void) { uint8_t *addr_long = NULL; uint16_t addr_short = 0; char i; __xdata unsigned char * macp = &X_IEEE_ADDR; PUTSTRING("Rime is 0x"); PUTHEX(sizeof(rimeaddr_t)); PUTSTRING(" bytes long\n"); PUTSTRING("Reading MAC from Info Page\n"); for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) { rimeaddr_node_addr.u8[i] = *macp; macp++; } /* Now the address is stored MSB first */ #if STARTUP_VERBOSE PUTSTRING("Rime configured with address "); for(i = 0; i < RIMEADDR_SIZE - 1; i++) { PUTHEX(rimeaddr_node_addr.u8[i]); PUTCHAR(':'); } PUTHEX(rimeaddr_node_addr.u8[i]); PUTCHAR('\n'); #endif cc2530_rf_set_addr(IEEE802154_PANID); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(border_router_process, ev, data) { static struct etimer et; PROCESS_BEGIN(); PUTSTRING("Border Router started\n"); prefix_set = 0; leds_on(LEDS_GREEN); /* Request prefix until it has been received */ while(!prefix_set) { leds_on(LEDS_RED); PUTSTRING("Prefix request.\n"); etimer_set(&et, CLOCK_SECOND); request_prefix(); leds_off(LEDS_RED); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); } /* We have created a new DODAG when we reach here */ PUTSTRING("On Channel "); PUTDEC(cc2530_rf_channel_get()); PUTCHAR('\n'); print_local_addresses(); leds_off(LEDS_GREEN); PROCESS_EXIT(); PROCESS_END(); }
/*---------------------------------------------------------------------------*/ uint8_t cc2530_rf_power_set(uint8_t new_power) { PUTSTRING("RF: Set Power\n"); /* off() */ TXPOWER = new_power; /* on() */ return TXPOWER; }
/*---------------------------------------------------------------------------*/ static int init(void) { PUTSTRING("RF: Init\n"); if(rf_flags & RF_ON) { return 0; } #ifdef CC2530_RF_LOW_POWER_RX /* Reduce RX power consumption current to 20mA at the cost of sensitivity */ RXCTRL = 0x00; FSCTRL = 0x50; #else RXCTRL = 0x3F; FSCTRL = 0x55; #endif /* CC2530_RF_LOW_POWER_RX */ CCACTRL0 = CC2530_RF_CCA_THRES; /* * According to the user guide, these registers must be updated from their * defaults for optimal performance * * Table 23-6, Sec. 23.15.1, p. 259 */ TXFILTCFG = 0x09; /* TX anti-aliasing filter */ AGCCTRL1 = 0x15; /* AGC target value */ FSCAL1 = 0x00; /* Reduce the VCO leakage */ /* Auto ACKs and CRC calculation, default RX and TX modes with FIFOs */ FRMCTRL0 = FRMCTRL0_AUTOCRC; #if CC2530_RF_AUTOACK FRMCTRL0 |= FRMCTRL0_AUTOACK; #endif /* Disable source address matching and autopend */ SRCMATCH = 0; /* investigate */ /* MAX FIFOP threshold */ FIFOPCTRL = CC2530_RF_MAX_PACKET_LEN; cc2530_rf_power_set(CC2530_RF_TX_POWER); cc2530_rf_channel_set(CC2530_RF_CHANNEL); RF_TX_LED_OFF(); RF_RX_LED_OFF(); rf_flags |= RF_ON; return 1; }
/*---------------------------------------------------------------------------*/ static int receiving_packet(void) { PUTSTRING("RF: Receiving\n"); /* * SFD high while transmitting and receiving. * TX_ACTIVE high only when transmitting * * FSMSTAT1 & (TX_ACTIVE | SFD) == SFD <=> receiving */ return (FSMSTAT1 & (FSMSTAT1_TX_ACTIVE | FSMSTAT1_SFD) == FSMSTAT1_SFD); }
/*---------------------------------------------------------------------------*/ static void set_rime_addr(void) { uint8_t *addr_long = NULL; uint16_t addr_short = 0; int8_t i; #ifdef SDCC __xdata unsigned char * macp = &X_IEEE_ADDR; #else volatile unsigned char * macp = &X_IEEE_ADDR; // IEEE地址 位于XDATA 780C #endif PUTSTRING("Rime is 0x"); PUTHEX(sizeof(rimeaddr_t)); PUTSTRING(" bytes long\r\n"); PUTSTRING("Reading MAC from Info Page\r\n"); // 从INFO中取MAC地址, for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) { rimeaddr_node_addr.u8[i] = *macp; macp++; } /* Now the address is stored MSB first */ #if STARTUP_VERBOSE // 显示MAC地址 PUTSTRING("Rime configured with address "); for(i = 0; i < RIMEADDR_SIZE - 1; i++) { PUTHEX(rimeaddr_node_addr.u8[i]); PUTCHAR(':'); } PUTHEX(rimeaddr_node_addr.u8[i]); PUTCHAR('\r');PUTCHAR('\n'); PUTSTRING("**************************************\r\n"); #endif cc2530_rf_set_addr(IEEE802154_PANID); // 设置PANID }
/*---------------------------------------------------------------------------*/ void serial_lprf_mac_rf_input(void) { uint8_t bufCnt, *bufPtr = packetbuf_dataptr(); #if (DEVICE_MODE == SERIAL_LPRF_MAC) uint8_t *addrPtr; #endif PUTSTRING("Data Received : "); PUTSTRING(bufPtr); PUTSTRING("\n"); leds_toggle(LEDS_RED); #if (DEVICE_MODE == SERIAL_LPRF_MAC) putchar(SERIAL_LPRF_MAC_PACKET_START_BYTE); putchar(packetbuf_datalen() + 1 + 8); putchar('R'); addrPtr = (uint8_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER); for(bufCnt = 0; bufCnt < 8; bufCnt++) putchar( * (addrPtr + bufCnt)); for(bufCnt = 0; bufCnt < packetbuf_datalen(); bufCnt++) putchar( * (bufPtr + bufCnt)); #endif }
/*---------------------------------------------------------------------------*/ static int prepare(const void *payload, unsigned short payload_len) { uint8_t i; PUTSTRING("RF: Prepare 0x"); PUTHEX(payload_len + CHECKSUM_LEN); PUTSTRING(" bytes\n"); /* * When we transmit in very quick bursts, make sure previous transmission * is not still in progress before re-writing to the TX FIFO */ while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE); if((rf_flags & RX_ACTIVE) == 0) { on(); } CC2530_CSP_ISFLUSHTX(); PUTSTRING("RF: data = "); /* Send the phy length byte first */ RFD = payload_len + CHECKSUM_LEN; /* Payload plus FCS */ for(i = 0; i < payload_len; i++) { RFD = ((unsigned char*) (payload))[i]; PUTHEX(((unsigned char*)(payload))[i]); } PUTSTRING("\n"); /* Leave space for the FCS */ RFD = 0; RFD = 0; return 0; }
/*---------------------------------------------------------------------------*/ int8_t cc2530_rf_channel_set(uint8_t channel) { PUTSTRING("RF: Set Chan\n"); if((channel < CC2530_RF_CHANNEL_MIN) || (channel > CC2530_RF_CHANNEL_MAX)) { return -1; } /* Changes to FREQCTRL take effect after the next recalibration */ off(); FREQCTRL = (CC2530_RF_CHANNEL_MIN + (channel - CC2530_RF_CHANNEL_MIN) * CC2530_RF_CHANNEL_SPACING); on(); return (int8_t) channel; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(sensor_process, ev, data) { static struct etimer et; PROCESS_BEGIN(); PUTSTRING("Sensor started\n"); leds_on(LEDS_GREEN); while(1) { PROCESS_YIELD(); } PROCESS_EXIT(); PROCESS_END(); }
/* Set our prefix when we receive one over SLIP */ void set_prefix_64(uip_ipaddr_t *prefix_64) { rpl_dag_t *dag; uip_ipaddr_t ipaddr; memcpy(&ipaddr, prefix_64, 16); prefix_set = 1; uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); /* Become root of a new DODAG with ID our global v6 address */ dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); if(dag != NULL) { rpl_set_prefix(dag, &ipaddr, 64); PUTSTRING("Created a new RPL dag with ID: "); PRINT6ADDR(&dag->dag_id); PUTCHAR('\n'); } }
PROCESS_THREAD(zigbee_comunication, ev, data) { static struct etimer et; unsigned char sum = 0; struct st_UartRcv *pdata = NULL; int i = 0; PROCESS_BEGIN(); GPIO_DeInit(GPIOB); GPIO_Init(GPIOC, GPIO_Pin_5, GPIO_Mode_Out_PP_High_Fast); //TXD GPIO_Init(GPIOC, GPIO_Pin_6, GPIO_Mode_In_PU_No_IT); //RXD //GPIO_Init(GPIOB,GPIO_Pin_6,GPIO_Mode_In_FL_IT); // ACK GPIO_Init(GPIOB,GPIO_Pin_5,GPIO_Mode_Out_PP_High_Fast); // RESET //GPIO_Init(GPIOB,GPIO_Pin_4,GPIO_Mode_In_FL_IT); // STATE GPIO_Init(GPIOB,GPIO_Pin_3,GPIO_Mode_Out_PP_High_Fast); // WAKEUP GPIO_Init(GPIOB,GPIO_Pin_2,GPIO_Mode_Out_PP_High_Fast); // SLEEP GPIO_Init(GPIOB,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Fast); // DEF GPIO_Init(GPIOD,GPIO_Pin_0,GPIO_Mode_Out_PP_Low_Fast); // DIR #if 0 GPIO_WriteBit(GPIOB, GPIO_Pin_1, RESET); GPIO_WriteBit(GPIOB, GPIO_Pin_5, RESET); etimer_set(&et, CLOCK_SECOND / 10); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); GPIO_WriteBit(GPIOB, GPIO_Pin_5, SET); etimer_set(&et, CLOCK_SECOND / 10); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); GPIO_WriteBit(GPIOB, GPIO_Pin_1, SET); #endif SYSCFG_REMAPPinConfig(REMAP_Pin_USART1TxRxPortC,ENABLE); CLK_PeripheralClockConfig(CLK_Peripheral_USART1, ENABLE); /* USART configured as follow: - BaudRate = 115200 baud - Word Length = 8 Bits - One Stop Bit - Odd parity - Receive and transmit enabled - USART Clock disabled */ USART_Init(USART1, (uint32_t)115200, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No, (USART_Mode_TypeDef)(USART_Mode_Tx | USART_Mode_Rx)); /* Enable the USART Receive interrupt: this interrupt is generated when the USART receive data register is not empty */ //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); /* Enable the USART Transmit complete interrupt: this interrupt is generated when the USART transmit Shift Register is empty */ //USART_ITConfig(USART1, USART_IT_TC, ENABLE); /* Enable USART */ //USART_Cmd(USART1, ENABLE); USART_Cmd(USART1, ENABLE); //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); #if 0 PUTSTRING("Now config ZM516X\r\n"); readLocalInfo: memcpy(usart_buf,read_local_cfg,sizeof(read_local_cfg)); usart_buf[4] = usart_buf[0] + usart_buf[1] + usart_buf[2] + usart_buf[3]; uart_send_byte(5,usart_buf); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_MSG); pdata = (struct st_UartRcv *)data; if((pdata->buf[0] == 0xAB) && (pdata->buf[1] == 0xBC) && (pdata->buf[2] == 0xCD) && (pdata->buf[3] == 0xD1)) { } else { goto readLocalInfo; } memcpy(&stDevInfo,&pdata->buf[4],65); usart_buf[0] = 0xab; usart_buf[1] = 0xbc; usart_buf[2] = 0xcd; usart_buf[3] = enModifyCfg; usart_buf[4] = stDevInfo.devLoacalNetAddr[0]; usart_buf[5] = stDevInfo.devLoacalNetAddr[1]; stDevInfo.devLoacalNetAddr[0] = 0x00; stDevInfo.devLoacalNetAddr[1] = 0x03; //memset(stDevInfo.devLoacalNetAddr,0,2); stDevInfo.devDestNetAddr[0] = 0x00; stDevInfo.devDestNetAddr[1] = 0x00; stDevInfo.devChannel = 0x19; stDevInfo.devPanid[0] = 0x10; stDevInfo.devPanid[1] = 0x01; memcpy(&usart_buf[6],&stDevInfo,65); for(i = 0;i < (6 + 65);i++) { sum += usart_buf[i]; } usart_buf[6 + 65] = sum; uart_send_byte(6 + 65 + 1,usart_buf); etimer_set(&et, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); GPIO_WriteBit(GPIOB,GPIO_Pin_5,RESET); etimer_set(&et, CLOCK_SECOND / CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); GPIO_WriteBit(GPIOB,GPIO_Pin_5,SET); #endif //uart_send_byte(5,"hello"); process_start(&hmc5983_work, NULL); while(1) { //etimer_set(&et, CLOCK_SECOND); //PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_MSG); //pdata = (struct st_UartRcv *)data; //if(memcmp(pdata->buf,"get",3) == 0) if(flg) { usart_buf[0] = 0xAA; usart_buf[1] = 0xBB; usart_buf[2] = 0xCC; *(int*)&usart_buf[3] = x; *(int*)&usart_buf[5] = y; *(int*)&usart_buf[7] = z; usart_buf[9] = 0; for(i = 0;i < 9;i ++) { usart_buf[9] += usart_buf[i]; } usart_buf[9] = 0xff - usart_buf[9]; GPIO_WriteBit(GPIOD, GPIO_Pin_0, SET); etimer_set(&et, CLOCK_SECOND / 20); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); uart_send_byte(10,usart_buf); etimer_set(&et, CLOCK_SECOND / 20); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); GPIO_WriteBit(GPIOD, GPIO_Pin_0, RESET); } //etimer_set(&et, CLOCK_SECOND / 10); //PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); //memcpy(usart_buf,"hello!\r\n",8); //uart_send_byte(8,usart_buf); } PROCESS_EXIT(); PROCESS_END(); }
/*---------------------------------------------------------------------------*/ int main(void) { /* Hardware initialization */ clock_init(); soc_init(); rtimer_init(); /* Init LEDs here */ leds_init(); leds_off(LEDS_ALL); fade(LEDS_GREEN); /* initialize process manager. */ process_init(); /* Init UART */ uart0_init(); #if DMA_ON dma_init(); #endif #if SLIP_ARCH_CONF_ENABLE slip_arch_init(0); #else uart0_set_input(serial_line_input_byte); serial_line_init(); #endif fade(LEDS_RED); PUTSTRING("##########################################\n"); putstring(CONTIKI_VERSION_STRING "\n"); putstring("TI SmartRF05 EB\n"); switch(CHIPID) { case 0xA5: putstring("cc2530"); break; case 0xB5: putstring("cc2531"); break; case 0x95: putstring("cc2533"); break; case 0x8D: putstring("cc2540"); break; } putstring("-F"); switch(CHIPINFO0 & 0x70) { case 0x40: putstring("256, "); break; case 0x30: putstring("128, "); break; case 0x20: putstring("64, "); break; case 0x10: putstring("32, "); break; } puthex(CHIPINFO1 + 1); putstring("KB SRAM\n"); PUTSTRING("\nSDCC Build:\n"); #if STARTUP_VERBOSE #ifdef HAVE_SDCC_BANKING PUTSTRING(" With Banking.\n"); #endif /* HAVE_SDCC_BANKING */ #ifdef SDCC_MODEL_LARGE PUTSTRING(" --model-large\n"); #endif /* SDCC_MODEL_LARGE */ #ifdef SDCC_MODEL_HUGE PUTSTRING(" --model-huge\n"); #endif /* SDCC_MODEL_HUGE */ #ifdef SDCC_STACK_AUTO PUTSTRING(" --stack-auto\n"); #endif /* SDCC_STACK_AUTO */ PUTCHAR('\n'); PUTSTRING(" Net: "); PUTSTRING(NETSTACK_NETWORK.name); PUTCHAR('\n'); PUTSTRING(" MAC: "); PUTSTRING(NETSTACK_MAC.name); PUTCHAR('\n'); PUTSTRING(" RDC: "); PUTSTRING(NETSTACK_RDC.name); PUTCHAR('\n'); PUTSTRING("##########################################\n"); #endif watchdog_init(); /* Initialise the H/W RNG engine. */ random_init(0); /* start services */ process_start(&etimer_process, NULL); ctimer_init(); /* initialize the netstack */ netstack_init(); set_rime_addr(); #if BUTTON_SENSOR_ON || ADC_SENSOR_ON process_start(&sensors_process, NULL); BUTTON_SENSOR_ACTIVATE(); ADC_SENSOR_ACTIVATE(); #endif #if UIP_CONF_IPV6 memcpy(&uip_lladdr.addr, &rimeaddr_node_addr, sizeof(uip_lladdr.addr)); queuebuf_init(); process_start(&tcpip_process, NULL); #endif /* UIP_CONF_IPV6 */ #if VIZTOOL_CONF_ON process_start(&viztool_process, NULL); #endif energest_init(); ENERGEST_ON(ENERGEST_TYPE_CPU); autostart_start(autostart_processes); watchdog_start(); fade(LEDS_YELLOW); while(1) { do { /* Reset watchdog and handle polls and events */ watchdog_periodic(); #if CLOCK_CONF_STACK_FRIENDLY if(sleep_flag) { if(etimer_pending() && (etimer_next_expiration_time() - clock_time() - 1) > MAX_TICKS) { etimer_request_poll(); } sleep_flag = 0; } #endif r = process_run(); } while(r > 0); len = NETSTACK_RADIO.pending_packet(); if(len) { packetbuf_clear(); len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); NETSTACK_RDC.input(); } } #if LPM_MODE #if (LPM_MODE==LPM_MODE_PM2) SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ while(!(SLEEP & HFRC_STB)); /* Wait for RCOSC to be stable */ CLKCON |= OSC; /* Switch to the RCOSC */ while(!(CLKCON & OSC)); /* Wait till it's happened */ SLEEP |= OSC_PD; /* Turn the other one off */ #endif /* LPM_MODE==LPM_MODE_PM2 */ /* * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM * Sleep Timer will wake us up in no more than 7.8ms (max idle interval) */ SLEEPCMD = (SLEEPCMD & 0xFC) | (LPM_MODE - 1); #if (LPM_MODE==LPM_MODE_PM2) /* * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or * no interrupt occurred and we can safely power down */ __asm nop nop nop __endasm; if(SLEEPCMD & SLEEP_MODE0) { #endif /* LPM_MODE==LPM_MODE_PM2 */ ENERGEST_OFF(ENERGEST_TYPE_CPU); ENERGEST_ON(ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); /* Go IDLE or Enter PM1 */ PCON |= PCON_IDLE; /* First instruction upon exiting PM1 must be a NOP */ __asm nop __endasm; /* Remember energest IRQ for next pass */ ENERGEST_IRQ_SAVE(irq_energest); ENERGEST_ON(ENERGEST_TYPE_CPU); ENERGEST_OFF(ENERGEST_TYPE_LPM); #if (LPM_MODE==LPM_MODE_PM2) SLEEPCMD &= ~SLEEP_OSC_PD; /* Make sure both HS OSCs are on */ while(!(SLEEPCMD & SLEEP_XOSC_STB)); /* Wait for XOSC to be stable */ CLKCONCMD &= ~CLKCONCMD_OSC; /* Switch to the XOSC */ /* * On occasion the XOSC is reported stable when in reality it's not. * We need to wait for a safeguard of 64us or more before selecting it */ clock_delay(10); while(CLKCONCMD & CLKCONCMD_OSC); /* Wait till it's happened */ } #endif /* LPM_MODE==LPM_MODE_PM2 */ #endif /* LPM_MODE */ } }
/*---------------------------------------------------------------------------*/ static int read(void *buf, unsigned short bufsize) { uint8_t i; uint8_t len; uint8_t crc_corr; int8_t rssi; PUTSTRING("RF: Read\n"); /* Check the length */ len = RFD; /* Check for validity */ if(len > CC2530_RF_MAX_PACKET_LEN) { /* Oops, we must be out of sync. */ PUTSTRING("RF: bad sync\n"); RIMESTATS_ADD(badsynch); CC2530_CSP_ISFLUSHRX(); return 0; } if(len <= CC2530_RF_MIN_PACKET_LEN) { PUTSTRING("RF: too short\n"); RIMESTATS_ADD(tooshort); CC2530_CSP_ISFLUSHRX(); return 0; } if(len - CHECKSUM_LEN > bufsize) { PUTSTRING("RF: too long\n"); RIMESTATS_ADD(toolong); CC2530_CSP_ISFLUSHRX(); return 0; } #if CC2530_RF_CONF_HEXDUMP /* If we reach here, chances are the FIFO is holding a valid frame */ uart0_writeb(magic[0]); uart0_writeb(magic[1]); uart0_writeb(magic[2]); uart0_writeb(magic[3]); uart0_writeb(len); #endif RF_RX_LED_ON(); PUTSTRING("RF: read (0x"); PUTHEX(len); PUTSTRING(" bytes) = "); len -= CHECKSUM_LEN; for(i = 0; i < len; ++i) { ((unsigned char*)(buf))[i] = RFD; #if CC2530_RF_CONF_HEXDUMP uart0_writeb(((unsigned char*)(buf))[i]); #endif PUTHEX(((unsigned char*)(buf))[i]); } PUTSTRING("\n"); /* Read the RSSI and CRC/Corr bytes */ rssi = ((int8_t) RFD) - 45; crc_corr = RFD; #if CC2530_RF_CONF_HEXDUMP uart0_writeb(rssi); uart0_writeb(crc_corr); #endif /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */ if(crc_corr & CRC_BIT_MASK) { packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK); RIMESTATS_ADD(llrx); } else { RIMESTATS_ADD(badcrc); CC2530_CSP_ISFLUSHRX(); RF_RX_LED_OFF(); return 0; } /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */ if((FSMSTAT1 & (FSMSTAT1_FIFO | FSMSTAT1_FIFOP)) == FSMSTAT1_FIFOP) { /* * If we reach here means that there might be more intact packets in the * FIFO despite the overflow. This can happen with bursts of small packets. * * Only flush if the FIFO is actually empty. If not, then next pass we will * pick up one more packet or flush due to an error. */ if(!RXFIFOCNT) { CC2530_CSP_ISFLUSHRX(); } } RF_RX_LED_OFF(); return (len); }
/*---------------------------------------------------------------------------*/ int main(void) { clock_init(); // 初始化 睡眠定时器 必要 soc_init(); // 还函数中启动了全局中断 可修改 rtimer_init(); // rtimer为定时器1 必要 /* Init LEDs here */ leds_init(); // 初始化LED 可修改 leds_off(LEDS_ALL); // 关闭所有LED 非必要 fade(LEDS_GREEN); // 绿色闪烁一下 非必要 /* initialize process manager. */ process_init(); // 任务初始化 必要 /* Init UART */ uart0_init(); // 初始化串口0,先用于调试,可修改 #if DMA_ON dma_init(); // 非必要 #endif #if SLIP_ARCH_CONF_ENABLE slip_arch_init(0); #else uart0_set_input(serial_line_input_byte); serial_line_init(); #endif fade(LEDS_RED); // 红色LED闪烁一下 非必要 // 打印若干提示信息 非必要 可修改 putstring("**************************************\r\n"); putstring(CONTIKI_VERSION_STRING "\r\n"); // 打印若干信息 putstring("Platform CC2530 NB\r\n"); switch(CHIPID) { case 0xA5: putstring("CC2530"); break; case 0xB5: putstring("CC2531"); break; case 0x95: putstring("CC2533"); break; case 0x8D: putstring("CC2540"); break; } putstring("-F"); switch(CHIPINFO0 & 0x70) { case 0x40: putstring("256,"); break; case 0x30: putstring("128,"); break; case 0x20: putstring("64,"); break; case 0x10: putstring("32,"); break; } puthex(CHIPINFO1 + 1); putstring("KB SRAM\r\n"); #if STARTUP_VERBOSE PUTSTRING("Net: "); // NETWORK名称 PUTSTRING(NETSTACK_NETWORK.name); PUTCHAR('\r');PUTCHAR('\n'); PUTSTRING("MAC: "); // MAC名称 PUTSTRING(NETSTACK_MAC.name); PUTCHAR('\r');PUTCHAR('\n'); PUTSTRING("RDC: "); // RDC名称 PUTSTRING(NETSTACK_RDC.name); PUTCHAR('\r');PUTCHAR('\n'); PUTSTRING("**************************************\r\n"); #endif watchdog_init(); // 初始化看门狗 /* Initialise the H/W RNG engine. */ random_init(0); // /* start services */ process_start(&etimer_process, NULL); // 启动etimer任务 ctimer_init(); // ctimer初始化 /* initialize the netstack */ netstack_init(); // NET协议栈初始化 set_rime_addr(); // 设置RIME地址,相当于设置IP地址 #if BUTTON_SENSOR_ON || ADC_SENSOR_ON process_start(&sensors_process, NULL); BUTTON_SENSOR_ACTIVATE(); ADC_SENSOR_ACTIVATE(); #endif #if UIP_CONF_IPV6 // 非常重要,启动TCPIP查询任务 memcpy(&uip_lladdr.addr, &rimeaddr_node_addr, sizeof(uip_lladdr.addr)); queuebuf_init(); process_start(&tcpip_process, NULL); #endif /* UIP_CONF_IPV6 */ #if VIZTOOL_CONF_ON process_start(&viztool_process, NULL); #endif energest_init(); // 能量估计初始化,但是该功能未被打开 ENERGEST_ON(ENERGEST_TYPE_CPU); // 该功能未被打开 autostart_start(autostart_processes); // 启动被定义为自动启动的任务 watchdog_start(); // 看门狗初始化 fade(LEDS_YELLOW); // 黄色LED闪烁,完成所有初始化工作 while(1) { do { /* Reset watchdog and handle polls and events */ watchdog_periodic(); // 喂狗操作 r = process_run(); } while(r > 0); #if SHORTCUTS_CONF_NETSTACK // 循环查询无线输入数据包长度 tcpip_process len = NETSTACK_RADIO.pending_packet(); if(len) { packetbuf_clear(); len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); NETSTACK_RDC.input(); } } #endif #if LPM_MODE // 该宏被定义为0,没有休眠功能,以下代码均无效 #if (LPM_MODE==LPM_MODE_PM2) SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ while(!(SLEEP & HFRC_STB)); /* Wait for RCOSC to be stable */ CLKCON |= OSC; /* Switch to the RCOSC */ while(!(CLKCON & OSC)); /* Wait till it's happened */ SLEEP |= OSC_PD; /* Turn the other one off */ #endif /* LPM_MODE==LPM_MODE_PM2 */ /* * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM * Sleep Timer will wake us up in no more than 7.8ms (max idle interval) */ SLEEPCMD = (SLEEPCMD & 0xFC) | (LPM_MODE - 1); #if (LPM_MODE==LPM_MODE_PM2) /* * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or * no interrupt occurred and we can safely power down */ __asm nop nop nop __endasm; if(SLEEPCMD & SLEEP_MODE0) { #endif /* LPM_MODE==LPM_MODE_PM2 */ ENERGEST_OFF(ENERGEST_TYPE_CPU); ENERGEST_ON(ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); /* Go IDLE or Enter PM1 */ PCON |= PCON_IDLE; /* First instruction upon exiting PM1 must be a NOP */ __asm nop __endasm; /* Remember energest IRQ for next pass */ ENERGEST_IRQ_SAVE(irq_energest); ENERGEST_ON(ENERGEST_TYPE_CPU); ENERGEST_OFF(ENERGEST_TYPE_LPM); #if (LPM_MODE==LPM_MODE_PM2) SLEEPCMD &= ~SLEEP_OSC_PD; /* Make sure both HS OSCs are on */ while(!(SLEEPCMD & SLEEP_XOSC_STB)); /* Wait for XOSC to be stable */ CLKCONCMD &= ~CLKCONCMD_OSC; /* Switch to the XOSC */ /* * On occasion the XOSC is reported stable when in reality it's not. * We need to wait for a safeguard of 64us or more before selecting it */ clock_delay(10); while(CLKCONCMD & CLKCONCMD_OSC); /* Wait till it's happened */ } #endif /* LPM_MODE==LPM_MODE_PM2 */ #endif /* LPM_MODE */ } }
/*---------------------------------------------------------------------------*/ static int transmit(unsigned short transmit_len) { uint8_t counter; int ret = RADIO_TX_ERR; rtimer_clock_t t0; transmit_len; /* hush the warning */ if(!(rf_flags & RX_ACTIVE)) { t0 = RTIMER_NOW(); on(); rf_flags |= WAS_OFF; while (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME)); } if(channel_clear() == CC2530_RF_CCA_BUSY) { RIMESTATS_ADD(contentiondrop); return RADIO_TX_COLLISION; } /* * prepare() double checked that TX_ACTIVE is low. If SFD is high we are * receiving. Abort transmission and bail out with RADIO_TX_COLLISION */ if(FSMSTAT1 & FSMSTAT1_SFD) { RIMESTATS_ADD(contentiondrop); return RADIO_TX_COLLISION; } /* Start the transmission */ RF_TX_LED_ON(); ENERGEST_OFF(ENERGEST_TYPE_LISTEN); ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); CC2530_CSP_ISTXON(); counter = 0; while(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE) && (counter++ < 3)) { clock_delay_usec(6); } if(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE)) { PUTSTRING("RF: TX never active.\n"); CC2530_CSP_ISFLUSHTX(); ret = RADIO_TX_ERR; } else { /* Wait for the transmission to finish */ while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE); ret = RADIO_TX_OK; } ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); ENERGEST_ON(ENERGEST_TYPE_LISTEN); if(rf_flags & WAS_OFF){ off(); } RIMESTATS_ADD(lltx); RF_TX_LED_OFF(); /* OK, sent. We are now ready to send more */ return ret; }
/*---------------------------------------------------------------------------*/ int main(void) { /* Hardware initialization */ bus_init();//ʱÖÓ³õʼ»¯ rtimer_init();//¼ÆʱÆ÷³õʼ»¯ /* model-specific h/w init. */ io_port_init(); /* Init LEDs here */ leds_init();//LED³õʼ»¯ /*LEDS_GREEN indicate LEDs Init finished*/ fade(LEDS_GREEN); /* initialize process manager. */ process_init();//½ø³Ì¹ÜÀí³õʼ»¯ /* Init UART0 * Based on the EJOY MCU CC2430 Circuit Design * */ uart0_init();//UART0´®¿Ú³õʼ»¯ #if DMA_ON dma_init();//DMA³õʼ»¯ #endif #if SLIP_ARCH_CONF_ENABLE /* On cc2430, the argument is not used */ slip_arch_init(0);//SLIP³õʼ»¯ #else uart1_set_input(serial_line_input_byte); serial_line_init(); #endif PUTSTRING("##########################################\n"); putstring(CONTIKI_VERSION_STRING "\n"); // putstring(SENSINODE_MODEL " (CC24"); puthex(((CHIPID >> 3) | 0x20)); putstring("-" FLASH_SIZE ")\n"); #if STARTUP_VERBOSE #ifdef HAVE_SDCC_BANKING PUTSTRING(" With Banking.\n"); #endif /* HAVE_SDCC_BANKING */ #ifdef SDCC_MODEL_LARGE PUTSTRING(" --model-large\n"); #endif /* SDCC_MODEL_LARGE */ #ifdef SDCC_MODEL_HUGE PUTSTRING(" --model-huge\n"); #endif /* SDCC_MODEL_HUGE */ #ifdef SDCC_STACK_AUTO PUTSTRING(" --stack-auto\n"); #endif /* SDCC_STACK_AUTO */ PUTCHAR('\n'); PUTSTRING(" Net: "); PUTSTRING(NETSTACK_NETWORK.name); PUTCHAR('\n'); PUTSTRING(" MAC: "); PUTSTRING(NETSTACK_MAC.name); PUTCHAR('\n'); PUTSTRING(" RDC: "); PUTSTRING(NETSTACK_RDC.name); PUTCHAR('\n'); PUTSTRING("##########################################\n"); #endif watchdog_init();//¿´ÃŹ·³õʼ»¯ /* Initialise the cc2430 RNG engine. */ random_init(0);//Ëæ»úÊýÉú³ÉÆ÷³õʼ»¯ /* start services */ process_start(&etimer_process, NULL);// ctimer_init();//ctimer³õʼ»¯ /* initialize the netstack */ netstack_init();//ÍøÂçµ×²ãÕ»³õʼ»¯ set_rime_addr();//rimeµØÖ·ÉèÖà //there is no sensor for us maintenance #if BUTTON_SENSOR_ON || ADC_SENSOR_ON process_start(&sensors_process, NULL); sensinode_sensors_activate(); #endif //IPV6,YES! #if UIP_CONF_IPV6 memcpy(&uip_lladdr.addr, &rimeaddr_node_addr, sizeof(uip_lladdr.addr)); queuebuf_init(); process_start(&tcpip_process, NULL); //DISCO #if DISCO_ENABLED process_start(&disco_process, NULL); #endif /* DISCO_ENABLED */ //VIZTOOL #if VIZTOOL_CONF_ON process_start(&viztool_process, NULL); #endif #if (!UIP_CONF_IPV6_RPL) { uip_ipaddr_t ipaddr; uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); } #endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6 */ /* * Acknowledge the UART1 RX interrupt * now that we're sure we are ready to process it * * We don't need it. by MW */ // model_uart_intr_en(); energest_init(); ENERGEST_ON(ENERGEST_TYPE_CPU); fade(LEDS_RED); #if BATMON_CONF_ON process_start(&batmon_process, NULL); #endif autostart_start(autostart_processes); watchdog_start(); while(1) { do { /* Reset watchdog and handle polls and events */ watchdog_periodic(); /**/ #if !CLOCK_CONF_ACCURATE if(sleep_flag) { if(etimer_pending() && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { /*core/sys/etimer.c*/ etimer_request_poll(); } sleep_flag = 0; } #endif r = process_run(); } while(r > 0); #if SHORTCUTS_CONF_NETSTACK len = NETSTACK_RADIO.pending_packet(); if(len) { packetbuf_clear(); len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); NETSTACK_RDC.input(); } } #endif #if LPM_MODE #if (LPM_MODE==LPM_MODE_PM2) SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ while(!(SLEEP & HFRC_STB)); /* Wait for RCOSC to be stable */ CLKCON |= OSC; /* Switch to the RCOSC */ while(!(CLKCON & OSC)); /* Wait till it's happened */ SLEEP |= OSC_PD; /* Turn the other one off */ #endif /* LPM_MODE==LPM_MODE_PM2 */ /* * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM * Sleep Timer will wake us up in no more than 7.8ms (max idle interval) */ SLEEP = (SLEEP & 0xFC) | (LPM_MODE - 1); #if (LPM_MODE==LPM_MODE_PM2) /* * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or * no interrupt occurred and we can safely power down */ __asm nop nop nop __endasm; if (SLEEP & SLEEP_MODE0) { #endif /* LPM_MODE==LPM_MODE_PM2 */ ENERGEST_OFF(ENERGEST_TYPE_CPU); ENERGEST_ON(ENERGEST_TYPE_LPM); /* We are only interested in IRQ energest while idle or in LPM */ ENERGEST_IRQ_RESTORE(irq_energest); /* Go IDLE or Enter PM1 */ PCON |= IDLE; /* First instruction upon exiting PM1 must be a NOP */ __asm nop __endasm; /* Remember energest IRQ for next pass */ ENERGEST_IRQ_SAVE(irq_energest); ENERGEST_ON(ENERGEST_TYPE_CPU); ENERGEST_OFF(ENERGEST_TYPE_LPM); #if (LPM_MODE==LPM_MODE_PM2) SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ while(!(SLEEP & XOSC_STB)); /* Wait for XOSC to be stable */ CLKCON &= ~OSC; /* Switch to the XOSC */ /* * On occasion the XOSC is reported stable when in reality it's not. * We need to wait for a safeguard of 64us or more before selecting it */ clock_delay(10); while(CLKCON & OSC); /* Wait till it's happened */ } #endif /* LPM_MODE==LPM_MODE_PM2 */ #endif /* LPM_MODE */ } }
/*---------------------------------------------------------------------------*/ static void set_rime_addr(void) { uint8_t *addr_long = NULL; uint16_t addr_short = 0; char i; #if SHORTCUTS_CONF_FLASH_READ __code unsigned char * macp; #else static uint8_t ft_buffer[8]; #endif PUTSTRING("Rime is 0x"); PUTHEX(sizeof(rimeaddr_t)); PUTSTRING(" bytes long\n"); if(node_id == 0) { PUTSTRING("Reading MAC from flash\n"); #if SHORTCUTS_CONF_FLASH_READ /* * The MAC is always stored in 0x1FFF8 of our flash. This maps to address * 0xFFF8 of our CODE segment, when BANK3 is selected. * Switch to BANK3, read 8 bytes starting at 0xFFF8 and restore last BANK * Since we are called from main(), this MUST be BANK1 or something is very * wrong. This code can be used even without banking */ /* Don't interrupt us to make sure no BANK switching happens while working */ DISABLE_INTERRUPTS(); /* Switch to BANK3, map CODE: 0x8000 – 0xFFFF to FLASH: 0x18000 – 0x1FFFF */ FMAP = 3; /* Set our pointer to the correct address and fetch 8 bytes of MAC */ macp = (__code unsigned char *) 0xFFF8; for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) { rimeaddr_node_addr.u8[i] = *macp; macp++; } /* Remap 0x8000 – 0xFFFF to BANK1 */ FMAP = 1; ENABLE_INTERRUPTS(); #else /* * Or use the more generic flash_read() routine which can read from any * address of our flash */ flash_read(ft_buffer, 0x1FFF8, 8); /* Flip the byte order and store MSB first */ for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) { rimeaddr_node_addr.u8[RIMEADDR_SIZE - 1 - i] = ft_buffer[i]; } #endif } else { PUTSTRING("Setting manual address from node_id\n"); rimeaddr_node_addr.u8[RIMEADDR_SIZE - 1] = node_id >> 8; rimeaddr_node_addr.u8[RIMEADDR_SIZE - 2] = node_id & 0xff; } /* Now the address is stored MSB first */ #if STARTUP_VERBOSE PUTSTRING("Rime configured with address "); for(i = 0; i < RIMEADDR_SIZE - 1; i++) { PUTHEX(rimeaddr_node_addr.u8[i]); PUTCHAR(':'); } PUTHEX(rimeaddr_node_addr.u8[i]); PUTCHAR('\n'); #endif /* Set the cc2430 RF addresses */ #if (RIMEADDR_SIZE==8) addr_short = (rimeaddr_node_addr.u8[6] * 256) + rimeaddr_node_addr.u8[7]; addr_long = (uint8_t *) &rimeaddr_node_addr; #else addr_short = (rimeaddr_node_addr.u8[0] * 256) + rimeaddr_node_addr.u8[1]; #endif cc2430_rf_set_addr(IEEE802154_PANID, addr_short, addr_long); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(serial_lprf_mac_process, ev, data) { PROCESS_BEGIN(); PUTSTRING("Serial LPRF MAC\n"); rimeaddr_set_node_addr(&rimeaddr_node_addr); #if (DEVICE_MODE == RF_TESTING_MASTER) PUTSTRING("RF Testing Master\n"); NETSTACK_RADIO.init(); NETSTACK_RDC.init(); NETSTACK_MAC.init(); etimer_set(&sendHelloEvent, CLOCK_SECOND * 6); while(1) { PROCESS_WAIT_EVENT(); if(ev == PROCESS_EVENT_TIMER) { PUTSTRING("Send Hello World "); PUTDEC(count++); PUTSTRING("\n"); packetbuf_clear(); packetbuf_copyfrom("Hello World", sizeof("Hello World")); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &rimeaddr_receiver); NETSTACK_RDC.send(NULL, NULL); leds_toggle(LEDS_GREEN); etimer_reset(&sendHelloEvent); } } #elif (DEVICE_MODE == RF_TESTING_SLAVE) PUTSTRING("RF Testing Slave\n"); NETSTACK_RADIO.init(); NETSTACK_RDC.init(); NETSTACK_MAC.init(); while(1) { len = NETSTACK_RADIO.pending_packet(); if(len) { packetbuf_clear(); len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); NETSTACK_RDC.input(); } } } #else // SERIAL_LPRF_MAC uart0_set_input(serial_lprf_mac_serial_input); NETSTACK_RADIO.init(); NETSTACK_RDC.init(); NETSTACK_MAC.init(); while(1) { if(state == SERIAL_REC_STATE_PACKET_COMPLETE) { switch(dataBuffer[0]) { case 'S': PUTSTRING("Send packet\n"); packetbuf_clear(); packetbuf_copyfrom(&dataBuffer[9], pktLength - 8 - 1); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t*)&dataBuffer[1]); NETSTACK_RDC.send(NULL, NULL); leds_toggle(LEDS_GREEN); break; default: PUTSTRING("Wrong command received\n"); } state = SERIAL_REC_STATE_WAIT_FOR_START; } len = NETSTACK_RADIO.pending_packet(); if(len) { packetbuf_clear(); len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); NETSTACK_RDC.input(); } } } #endif PROCESS_END(); }
uint convW2M(Wsysmsg *m, uchar *p, uint n) { int nn; nn = sizeW2M(m); if(n < nn || nn == 0 || n < 6) return 0; PUT(p, nn); p[4] = m->tag; p[5] = m->type; switch(m->type){ default: return 0; case Trdmouse: case Rbouncemouse: case Rmoveto: case Rcursor: case Trdkbd: case Rlabel: case Rinit: case Trdsnarf: case Rwrsnarf: case Ttop: case Rtop: case Rresize: break; case Rerror: PUTSTRING(p+6, m->error); break; case Rrdmouse: PUT(p+6, m->mouse.xy.x); PUT(p+10, m->mouse.xy.y); PUT(p+14, m->mouse.buttons); PUT(p+18, m->mouse.msec); p[19] = m->resized; break; case Tbouncemouse: PUT(p+6, m->mouse.xy.x); PUT(p+10, m->mouse.xy.y); PUT(p+14, m->mouse.buttons); break; case Tmoveto: PUT(p+6, m->mouse.xy.x); PUT(p+10, m->mouse.xy.y); break; case Tcursor: PUT(p+6, m->cursor.offset.x); PUT(p+10, m->cursor.offset.y); memmove(p+14, m->cursor.clr, sizeof m->cursor.clr); memmove(p+46, m->cursor.set, sizeof m->cursor.set); PUT(p+78, m->cursor2.offset.x); PUT(p+82, m->cursor2.offset.y); memmove(p+86, m->cursor2.clr, sizeof m->cursor2.clr); memmove(p+214, m->cursor2.set, sizeof m->cursor2.set); p[342] = m->arrowcursor; break; case Rrdkbd: PUT2(p+6, m->rune); break; case Tlabel: PUTSTRING(p+6, m->label); break; case Tinit: p += 6; p += PUTSTRING(p, m->winsize); p += PUTSTRING(p, m->label); break; case Rrdsnarf: case Twrsnarf: PUTSTRING(p+6, m->snarf); break; case Rrddraw: case Twrdraw: PUT(p+6, m->count); memmove(p+10, m->data, m->count); break; case Trddraw: case Rwrdraw: PUT(p+6, m->count); break; case Tresize: PUT(p+6, m->rect.min.x); PUT(p+10, m->rect.min.y); PUT(p+14, m->rect.max.x); PUT(p+18, m->rect.max.y); break; } return nn; }