/****************************************************************************** * @fn mrfiLinkSend * * @brief Send data on the RX link. * * @param pBuf - buffer to be transmitted * * @param len - number of bytes to be transmitted * * @return Return code indicates success or failure of transmit: * MRFI_TX_RESULT_SUCCESS - transmit succeeded * MRFI_TX_RESULT_FAILED - transmit failed because CCA or ACK failed */ uint8 mrfiLinkSend(uint8 *pBuf, uint8 len, uint8 nRetrans) { uint8 v,i,status; v= halIntLock(); MRFI_SET_PAYLOAD_LEN(&pkt, len+2); memcpy(MRFI_P_DST_ADDR(&pkt), dest_addr, 4); memcpy(MRFI_P_SRC_ADDR(&pkt), src_addr, 4); MRFI_P_PAYLOAD(&pkt)[0]= seqSend; MRFI_P_PAYLOAD(&pkt)[1]= MRFI_LINK_DATA; memcpy(MRFI_P_PAYLOAD(&pkt)+2, pBuf, len); halIntUnlock(v); for (i=0;i<nRetrans;i++) { status= MRFI_Transmit(&pkt, MRFI_TX_TYPE_CCA); if (status==MRFI_TX_RESULT_SUCCESS) { if (waitForAck(20)) { seqSend++; break; } else { status= MRFI_TX_RESULT_FAILED; // wait random time if sending is not successful // (20-40 milliseconds) halMcuWaitUs( (20000/255*MRFI_RandomByte()) + 20000 ); } } } return status; }
/** * swTransmit * * Transmit SWAP packet * * 'packet' Pointer to the SWAP packet to be sent * * Return: * MRFI_TX_RESULT_SUCCESS - transmit succeeded * MRFI_TX_RESULT_FAILED - transmit failed because CCA failed */ static byte swTransmit(SWPACKET *swPacket) { mrfiPacket_t mPacket; int i; byte ret; mPacket.frame[0] = swPacket->value.length + SWAP_DATA_HEAD_LEN; mPacket.frame[1] = swPacket->destAddr; mPacket.frame[2] = swPacket->srcAddr; mPacket.frame[3] = (swPacket->hop << 4) & 0xF0; mPacket.frame[3] |= swPacket->security & 0x0F; mPacket.frame[4] = swPacket->nonce; mPacket.frame[5] = swPacket->function; mPacket.frame[6] = swPacket->regAddr; mPacket.frame[7] = swPacket->regId; for(i=0 ; i<swPacket->value.length ; i++) mPacket.frame[8+i] = swPacket->value.data[i]; i = SWAP_NB_TX_TRIES; while ((ret = MRFI_Transmit(&mPacket, SWAP_TX_METHOD)) == MRFI_TX_RESULT_FAILED && i > 0) { i--; DELAY_MS(SWAP_DY_TX_TRIES); } return ret; }
__interrupt void interrupt_button (void) { P1IFG &= ~0x04; uint8_t counter; mrfiPacket_t packet; packet.frame[0]=8+20; MRFI_WakeUp(); for (counter=50;counter>=1;counter--) { packet.frame[9]=counter; MRFI_Transmit(&packet, MRFI_TX_TYPE_FORCED); } }
/****************************************************************************** * @fn sendAck * * @brief Send an acknowledge packet (no payload) * * @param none * * @return none */ static void sendAck(void) { uint8 v; v= halIntLock(); MRFI_SET_PAYLOAD_LEN(&pkt, 2); memcpy(MRFI_P_DST_ADDR(&pkt), dest_addr, 4); memcpy(MRFI_P_SRC_ADDR(&pkt), src_addr, 4); MRFI_P_PAYLOAD(&pkt)[0]= seqRecv; MRFI_P_PAYLOAD(&pkt)[1]= MRFI_LINK_ACK; halIntUnlock(v); MRFI_Transmit(&pkt, MRFI_TX_TYPE_FORCED); }
/****************************************************************************** * @fn nwk_sendAckReply * * @brief Send an acknowledgement reply frame. * * input parameters * @param frame - pointer to frame with ack request. * @param port - port on whcih reply expected. * * output parameters * * @return void */ void nwk_sendAckReply(mrfiPacket_t *frame, uint8_t port) { mrfiPacket_t dFrame; uint8_t tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS); /* set the type of device sending the frame in the header */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, sMyTxType); /* set the listen type of device sending the frame in the header. */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); /* destination address from received frame */ memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); /* source address */ memcpy(MRFI_P_SRC_ADDR(&dFrame), sMyAddr, NET_ADDR_SIZE); /* port is the source the Tx port from the connection object */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); /* frame length... */ MRFI_SET_PAYLOAD_LEN(&dFrame,F_APP_PAYLOAD_OS); /* transaction ID taken from source frame */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, tid); /* hop count... */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS); /* set ACK field */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, F_ACK_RPLY_TYPE); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); /* This is not a forwarded frame */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, 0); /* Encryption state */ #if !defined(SMPL_SECURE) PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); #else PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); nwk_setSecureFrame(&dFrame, 0, 0); #endif MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); return; }
void nwk_SendEmptyPollRspFrame(mrfiPacket_t *frame) { mrfiPacket_t dFrame; uint8_t port = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + M_POLL_PORT_OS); /* set the type of device sending the frame in the header. we know it's an AP */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, F_TX_DEVICE_AP); /* set the listen type of device sending the frame in the header. we know it's * an AP is is probably always on...but use the static variable anyway. */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); /* destination address from received frame (polling device) */ memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); /* source address */ memcpy(MRFI_P_SRC_ADDR(&dFrame), MRFI_P_PAYLOAD( frame) + F_APP_PAYLOAD_OS + M_POLL_ADDR_OS, NET_ADDR_SIZE); /* port is the port requested */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); /* frame length... */ MRFI_SET_PAYLOAD_LEN(&dFrame, F_APP_PAYLOAD_OS); /* transaction ID... */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, sTRACTID); sTRACTID++; /* hop count... */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS_FROM_AP); /* Ack fields */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, 0); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); /* This is logically a forwarded frame */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, F_FRAME_FWD_TYPE); /* Encryption state */ # if !defined(SMPL_SECURE) PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); # else PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); nwk_setSecureFrame(&dFrame, 0, 0); # endif MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); return; }
__interrupt void Timer_A (void) { P2OUT |= 0x04; uint16_t i; /* stop timer */ TACTL=MC_0; TACCTL0=0; /* send probe packet */ for (i=0;i<1000;i++) { P1OUT |= 0x01; packet.frame[0]=8+20; MRFI_Transmit(&packet, MRFI_TX_TYPE_FORCED); P1OUT &= ~0x01; } /* return to Rx mode on channel 26 */ MRFI_RxIdle(); mrfiSpiWriteReg(CHANNR,0xBC); // channel 26 MRFI_RxOn(); P2OUT &= ~0x04; }
/****************************************************************************** * @fn nwk_sendFrame * * @brief Send a frame by copying it to the radio Tx FIFO. * * input parameters * @param pFrameInfo - pointer to frame to be sent * @param txOption - do CCA or force frame out. * * output parameters * * @return SMPL_SUCCESS * SMPL_TX_CCA_FAIL Tx failed because of CCA failure. * Tx FIFO flushed in this case. */ smplStatus_t nwk_sendFrame(frameInfo_t *pFrameInfo, uint8_t txOption) { smplStatus_t rc; /* set the type of device sending the frame in the header */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&pFrameInfo->mrfiPkt), F_TX_DEVICE, sMyTxType); if (MRFI_TX_RESULT_SUCCESS == MRFI_Transmit(&pFrameInfo->mrfiPkt, txOption)) { rc = SMPL_SUCCESS; } else { /* Tx failed -- probably CCA. free up frame buffer. We do not have NWK * level retries. Let application do it. */ rc = SMPL_TX_CCA_FAIL; } /* TX is done. free up the frame buffer */ pFrameInfo->fi_usage = FI_AVAILABLE; return rc; }
void MRFI_RxCompleteISR() { mrfiPacket_t PacketRecieved; mPacket Packet; char rssi ; uint8_t ID_Network_tmp, ID_Beacon_tmp ,src ,i ,data; uint32_t voisin_voisin; //the voisin of voisin MRFI_Receive(&PacketRecieved); RecievemPacket(&PacketRecieved ,&Packet); if(Packet.flag == FBEACON){ etat.Surveille_Cnt = ( etat.Surveille_Cnt + 1 )%65535; ID_Network_tmp = Packet.payload.beacon.ID_Network; ID_Beacon_tmp = Packet.payload.beacon.ID_Slot; src = Packet.src; voisin_voisin = Packet.payload.beacon.Voisin; rssi = PacketRecieved.rxMetrics[0]; if(rssi > -84){ //seuil avec pwr(0) ,distance 70cm etat.check[src-1] = (etat.check[src-1] + 1)%65535; //make sure if the voisin is there Add_router(&etat , src, voisin_voisin); //every time it recieve the beacon , update the route table } /* print_8b(ID_Network_tmp); print_8b(ID_Beacon_tmp); print(" "); print_8b(-rssi); print("\n\r"); */ if(rssi < -84 && etat.ID_Beacon == ID_Beacon_tmp && etat.ID_Beacon !=0 && etat.HOST == IS_NOT_CREATER){ //if the beacon source go far , choose another Stop_Timer(); }else{ if(etat.synchrone == 0 && etat.HOST == IS_NOT_CREATER){ Stop_Timer(); etat.ID_Network = ID_Network_tmp; etat.ID_Beacon = ID_Beacon_tmp; etat.synchrone = 1; if(etat.MAC > etat.ID_Beacon ){ etat.state = WAIT_BEACON ; //change the state timer_send_beacon(&etat); }else{ etat.state = WAIT_SYNCHRONE ; //change the state timer_synchrone(&etat); } } if(ID_Network_tmp < etat.ID_Network){ //if there is 2 network collision if(etat.HOST == IS_CREATER){ etat.HOST = IS_NOT_CREATER; P1OUT ^= 0x02; //jaune led } Stop_Timer(); etat.ID_Network = ID_Network_tmp; etat.ID_Beacon = ID_Beacon_tmp; etat.synchrone = 1; if(etat.MAC > etat.ID_Beacon ){ etat.state = WAIT_BEACON; //change the state timer_send_beacon(&etat); }else{ etat.state = WAIT_SYNCHRONE ; //change the state timer_synchrone(&etat); } } } }else if(Packet.flag == FDATA){ if(Packet.payload.data.Next_hop == etat.MAC){ //if next hop is him, relay and change the next hop if(Packet.dst == etat.MAC){ //if it is really for me etat.Dst = Packet.src; if(UART_MODE!=2){ //change mode to type if recieve a paquet UART_MODE = 2; print("\n\rRecieved message from: "); print_8b(etat.Dst); print("\n\r"); } for (i=0;i<Packet.length-11;i++) { data = Packet.payload.data.data[i]; EnQueue(&etat.FIFO_Recieve,data); } }else{ //if it just nedd relay P1OUT ^= 0x02; PacketRecieved.frame[10] = Find_next_hop(&etat , Packet.dst); MRFI_Transmit(&PacketRecieved, MRFI_TX_TYPE_CCA); //MRFI_Transmit(&PacketRecieved, MRFI_TX_TYPE_FORCED); } } if(Packet.dst == BROADCAST){ //if it is message broadcast for (i=0;i<Packet.length-11;i++) { data = Packet.payload.data.data[i]; EnQueue(&etat.FIFO_Recieve,data); } } }else if(Packet.flag == FRIP){ //recieve the packet of rip then update the router table Update_rip(&etat ,&Packet); } }
/*------------------------------------------------------------------------------ * Main *----------------------------------------------------------------------------*/ void main ( void ) { uint8_t tx_cmd; uint8_t tx_data; /* Initialize board devices */ BSP_Init(); MRFI_Init(); /* Setup I/O */ P1DIR |= (LED_RED+LED_GREEN); // Enable LEDs P1DIR &= ~PUSH_BUTTON; // Enable push button P1REN |= PUSH_BUTTON; // Enable pull-up/down resistor P1IE |= PUSH_BUTTON; // Enable interrupt P2DIR &= ~(TRIGGER_L2H+TRIGGER_H2L+MODE_SELECT); // Enable inputs P2IE |= (TRIGGER_L2H+TRIGGER_H2L); // Enable interrupts P2IES &= ~TRIGGER_L2H; // Set rising edge select P2IES |= TRIGGER_H2L; // Set falling edge select /* Setup Timer A */ BCSCTL3 |= LFXT1S_2; // Source VLO @ 12kHz TACCTL0 = CCIE; // Enable TimerA interrupt TACCR0 = 12000; // ~1Hz TACTL = MC_1+TASSEL_1; // Count up + ACLK /* Initialize device settings */ NODE1 |= LINK_MODE; /* Signal boot complete */ P1OUT |= (LED_RED+LED_GREEN); /* Enter main loop */ while(1) { __bis_SR_register(GIE+LPM3_bits); if (NODE1&MEASURE_VCC) { volatile long temp; P1OUT |= LED_GREEN; ADC10CTL1 = INCH_11; ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V; __delay_cycles(240); ADC10CTL0 |= ENC + ADC10SC; __bis_SR_register(CPUOFF+GIE); temp = ADC10MEM; tx_cmd = NODE_ALIVE; tx_data = (temp*25)/512; ADC10CTL0 &= ~ENC; ADC10CTL0 &= ~(REFON + ADC10ON); NODE1 &= ~MEASURE_VCC; NODE1 |= (WAKE_RADIO+BROADCAST); TACCTL0 |= CCIE; P1OUT &= ~LED_GREEN; } if (NODE1&LINK_MODE) { P1OUT ^= (LED_RED+LED_GREEN); tx_cmd = NEW_NODE; NODE1 |= (WAKE_RADIO+BROADCAST); } else { if (NODE1&STATE_CHANGED) { if (NODE1&ALARMED) { P1OUT |= LED_RED; tx_cmd = ALARMED_NODE; } else { P1OUT &= ~LED_RED; tx_cmd = RESET_NODE; } NODE1 |= (WAKE_RADIO+BROADCAST); } else { if (NODE1&ALARMED) { P1OUT ^= LED_RED; } else { P1OUT &= ~LED_RED; } } } if (NODE1&WAKE_RADIO) { MRFI_WakeUp(); MRFI_RxOn(); } if (NODE1&BROADCAST) { mrfiPacket_t tx_packet; tx_packet.frame[0] = 8+20; tx_packet.frame[SRC_ADDR] = my_addr; tx_packet.frame[DST_ADDR] = 0x00; tx_packet.frame[CMD] = tx_cmd; tx_packet.frame[DATA] = tx_data; MRFI_Transmit(&tx_packet, MRFI_TX_TYPE_FORCED); NODE1 &= ~BROADCAST; } if (!(NODE1&WAKE_RADIO)) { MRFI_Sleep(); } } }
//Main Execution of the program main() { int temp; int DegK; int light; int humidity; char c[4]; mrfiPacket_t packet; unsigned char msg[9]; BSP_Init(); MRFI_Init(); MRFI_WakeUp(); //Disable Watchdog Timer WDTCTL = WDTPW + WDTHOLD; //Red LED P1.1 P1DIR |= 0x01; P1OUT |= 0x00; //Analog Input Setup //P1.1 = A10 = Internal = Temperature Sensor //P2.2 = A2 = Pin 5 = Light Sensor //P2.3 = A3 = Pin 6 = Humidity Sensor P1DIR &= ~0x02; //P1.1 is Input P2DIR &= ~0x0C; //P2.2 & P2.3 are Inputs //Global Interrupt Enable __bis_SR_register(GIE); //Read Analog Sensors Forever! while(1) { //Read Light Sensor light = analogRead(2); light = (int) (light/1023.0*100.0); sleep(60000); //Read Humidity Sensor humidity = analogRead(3); humidity = (int) (((((humidity/1023.0)*2.5)-.45)*100.0)/1.5); //Derived from Datasheet Info sleep(60000); //ReadTemperature temp = analogRead(10); DegK = (int) (((temp - 673.0) * 423.0) / 1023.0) + 273.0; //Make all values into 3 digit strings. itoa(light, c, 999); if (light < 10) { msg[0] = '0'; msg[1] = '0'; msg[2] = c[0]; } else if (light < 100) { msg[0] = '0'; msg[1] = c[0]; msg[2] = c[1]; } else { msg[0] = c[0]; msg[1] = c[1]; msg[2] = c[2]; } itoa(humidity, c, 999); if (humidity < 10) { msg[3] = '0'; msg[4] = '0'; msg[5] = c[0]; } else if (humidity < 100) { msg[3] = '0'; msg[4] = c[0]; msg[5] = c[1]; } else { msg[3] = c[0]; msg[4] = c[1]; msg[5] = c[2]; } itoa(DegK, c, 999); if (DegK < 10) { msg[6] = '0'; msg[7] = '0'; msg[8] = c[0]; } else if (DegK < 100) { msg[6] = '0'; msg[7] = c[0]; msg[8] = c[1]; } else { msg[6] = c[0]; msg[7] = c[1]; msg[8] = c[2]; } //Copy message into the packet. strcpy( &packet.frame[9] , msg ); /** Enter source and destination addresses **/ //Source address here is useless, as this is a send-only application. memset( &packet.frame[1], 0x20, 4); memset( &packet.frame[5], 0x10, 4); // Enter length of packet. packet.frame[0] = 8 + strlen(msg); // 8-byte header, 20-byte payload. //Transmit MRFI_Transmit(&packet , MRFI_TX_TYPE_FORCED); //Toggle led. P1OUT ^= RED_SEND_LED; //sleep. sleep(60000); sleep(60000); sleep(60000); sleep(60000); sleep(60000); } }