/*---------------------------------------------------------------------------*/ static int cc2520_transmit(unsigned short payload_len) { int i, txpower; GET_LOCK(); txpower = 0; if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Remember the current transmission power */ txpower = cc2520_get_txpower(); /* Set the specified transmission power */ set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1); } /* The TX FIFO can only hold one packet. Make sure to not overrun * FIFO by waiting for transmission to start here and synchronizing * with the CC2520_TX_ACTIVE check in cc2520_send. * * Note that we may have to wait up to 320 us (20 symbols) before * transmission starts. */ #ifndef CC2520_CONF_SYMBOL_LOOP_COUNT #error CC2520_CONF_SYMBOL_LOOP_COUNT needs to be set!!! #else #define LOOP_20_SYMBOLS CC2520_CONF_SYMBOL_LOOP_COUNT #endif #if WITH_SEND_CCA strobe(CC2520_INS_SRXON); BUSYWAIT_UNTIL(status() & BV(CC2520_RSSI_VALID) , RTIMER_SECOND / 10); strobe(CC2520_INS_STXONCCA); #else /* WITH_SEND_CCA */ strobe(CC2520_INS_STXON); #endif /* WITH_SEND_CCA */ for(i = LOOP_20_SYMBOLS; i > 0; i--) { if(CC2520_SFD_IS_1) { { rtimer_clock_t sfd_timestamp; sfd_timestamp = cc2520_sfd_start_time; if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP) { /* Write timestamp to last two bytes of packet in TXFIFO. */ CC2520_WRITE_RAM(&sfd_timestamp, CC2520RAM_TXFIFO + payload_len - 1, 2); } } if(!(status() & BV(CC2520_TX_ACTIVE))) { /* SFD went high but we are not transmitting. This means that we just started receiving a packet, so we drop the transmission. */ RELEASE_LOCK(); return RADIO_TX_COLLISION; } if(receive_on) { ENERGEST_OFF(ENERGEST_TYPE_LISTEN); } ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* We wait until transmission has ended so that we get an accurate measurement of the transmission time.*/ //BUSYWAIT_UNTIL(getreg(CC2520_EXCFLAG0) & TX_FRM_DONE , RTIMER_SECOND / 100); BUSYWAIT_UNTIL(!(status() & BV(CC2520_TX_ACTIVE)), RTIMER_SECOND / 10); #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2520_get_txpower()); #endif ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); if(receive_on) { ENERGEST_ON(ENERGEST_TYPE_LISTEN); } else { /* We need to explicitly turn off the radio, * since STXON[CCA] -> TX_ACTIVE -> RX_ACTIVE */ off(); } if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Restore the transmission power */ set_txpower(txpower & 0xff); } RELEASE_LOCK(); return RADIO_TX_OK; } } /* If we are using WITH_SEND_CCA, we get here if the packet wasn't transmitted because of other channel activity. */ RIMESTATS_ADD(contentiondrop); PRINTF("cc2520: do_send() transmission never started\n"); if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Restore the transmission power */ set_txpower(txpower & 0xff); } RELEASE_LOCK(); return RADIO_TX_COLLISION; }
/*---------------------------------------------------------------------------*/ static int cc2420_transmit(unsigned short payload_len) { int i, txpower; uint8_t total_len; #if CC2420_CONF_CHECKSUM uint16_t checksum; #endif /* CC2420_CONF_CHECKSUM */ GET_LOCK(); txpower = 0; if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Remember the current transmission power */ txpower = cc2420_get_txpower(); /* Set the specified transmission power */ set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1); } total_len = payload_len + AUX_LEN; /* The TX FIFO can only hold one packet. Make sure to not overrun * FIFO by waiting for transmission to start here and synchronizing * with the CC2420_TX_ACTIVE check in cc2420_send. * * Note that we may have to wait up to 320 us (20 symbols) before * transmission starts. */ #ifdef TMOTE_SKY #define LOOP_20_SYMBOLS 400 /* 326us (msp430 @ 2.4576MHz) */ #elif __AVR__ #define LOOP_20_SYMBOLS 500 /* XXX */ #endif #if WITH_SEND_CCA strobe(CC2420_SRXON); while(!(status() & BV(CC2420_RSSI_VALID))); strobe(CC2420_STXONCCA); #else /* WITH_SEND_CCA */ strobe(CC2420_STXON); #endif /* WITH_SEND_CCA */ for(i = LOOP_20_SYMBOLS; i > 0; i--) { if(SFD_IS_1) { if(!(status() & BV(CC2420_TX_ACTIVE))) { /* SFD went high but we are not transmitting. This means that we just started receiving a packet, so we drop the transmission. */ return RADIO_TX_ERR; } if(receive_on) { ENERGEST_OFF(ENERGEST_TYPE_LISTEN); } ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* We wait until transmission has ended so that we get an accurate measurement of the transmission time.*/ while(status() & BV(CC2420_TX_ACTIVE)); #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2420_get_txpower()); #endif ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); if(receive_on) { ENERGEST_ON(ENERGEST_TYPE_LISTEN); } else { /* We need to explicitly turn off the radio, * since STXON[CCA] -> TX_ACTIVE -> RX_ACTIVE */ off(); } if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Restore the transmission power */ set_txpower(txpower & 0xff); } RELEASE_LOCK(); return RADIO_TX_OK; } } /* If we are using WITH_SEND_CCA, we get here if the packet wasn't transmitted because of other channel activity. */ RIMESTATS_ADD(contentiondrop); PRINTF("cc2420: do_send() transmission never started\n"); if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { /* Restore the transmission power */ set_txpower(txpower & 0xff); } RELEASE_LOCK(); return RADIO_TX_ERR; /* Transmission never started! */ }
/*---------------------------------------------------------------------------*/ int cc2420_send(const void *payload, unsigned short payload_len) { int i; uint8_t total_len; struct timestamp timestamp; uint16_t checksum; GET_LOCK(); PRINTF("cc2420: sending %d bytes\n", payload_len); RIMESTATS_ADD(lltx); /* Wait for any previous transmission to finish. */ while(status() & BV(CC2420_TX_ACTIVE)); /* Write packet to TX FIFO. */ strobe(CC2420_SFLUSHTX); checksum = crc16_data(payload, payload_len, 0); total_len = payload_len + AUX_LEN; FASTSPI_WRITE_FIFO(&total_len, 1); FASTSPI_WRITE_FIFO(payload, payload_len); FASTSPI_WRITE_FIFO(&checksum, CHECKSUM_LEN); #if CC2420_CONF_TIMESTAMPS timestamp.authority_level = timesynch_authority_level(); timestamp.time = timesynch_time(); FASTSPI_WRITE_FIFO(×tamp, TIMESTAMP_LEN); #endif /* CC2420_CONF_TIMESTAMPS */ /* The TX FIFO can only hold one packet. Make sure to not overrun * FIFO by waiting for transmission to start here and synchronizing * with the CC2420_TX_ACTIVE check in cc2420_send. * * Note that we may have to wait up to 320 us (20 symbols) before * transmission starts. */ #ifdef TMOTE_SKY #define LOOP_20_SYMBOLS 100 /* 326us (msp430 @ 2.4576MHz) */ #elif __AVR__ #define LOOP_20_SYMBOLS 500 /* XXX */ #endif #if WITH_SEND_CCA strobe(CC2420_SRXON); while(!(status() & BV(CC2420_RSSI_VALID))); strobe(CC2420_STXONCCA); #else /* WITH_SEND_CCA */ strobe(CC2420_STXON); #endif /* WITH_SEND_CCA */ for(i = LOOP_20_SYMBOLS; i > 0; i--) { if(SFD_IS_1) { #if CC2420_CONF_TIMESTAMPS rtimer_clock_t txtime = timesynch_time(); #endif /* CC2420_CONF_TIMESTAMPS */ if(receive_on) { ENERGEST_OFF(ENERGEST_TYPE_LISTEN); } ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* We wait until transmission has ended so that we get an accurate measurement of the transmission time.*/ while(status() & BV(CC2420_TX_ACTIVE)); #if CC2420_CONF_TIMESTAMPS setup_time_for_transmission = txtime - timestamp.time; if(num_transmissions < 10000) { total_time_for_transmission += timesynch_time() - txtime; total_transmission_len += total_len; num_transmissions++; } #endif /* CC2420_CONF_TIMESTAMPS */ #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2420_get_txpower()); #endif ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); if(receive_on) { ENERGEST_ON(ENERGEST_TYPE_LISTEN); } RELEASE_LOCK(); return 0; } } /* If we are using WITH_SEND_CCA, we get here if the packet wasn't transmitted because of other channel activity. */ RIMESTATS_ADD(contentiondrop); PRINTF("cc2420: do_send() transmission never started\n"); RELEASE_LOCK(); return -3; /* Transmission never started! */ }
/*---------------------------------------------------------------------------*/ int nrf24l01_send(const void *payload, unsigned short payload_len) { uint8_t total_len,buffer[RF230_MAX_TX_FRAME_LENGTH],*pbuf; uint8_t tx_result = RADIO_TX_ERR; #if RF230_CONF_TIMESTAMPS struct timestamp timestamp; #endif /* RF230_CONF_TIMESTAMPS */ #if RF230_CONF_CHECKSUM uint16_t checksum; #endif /* RF230_CONF_CHECKSUM */ #if RADIOSTATS RF230_sendpackets++; #endif GET_LOCK(); RIMESTATS_ADD(lltx); #if RF230_CONF_CHECKSUM checksum = crc16_data(payload, payload_len, 0); #endif /* RF230_CONF_CHECKSUM */ total_len = payload_len + AUX_LEN; /*Check function parameters and current state.*/ if (total_len > RF230_MAX_TX_FRAME_LENGTH){ #if RADIOSTATS RF230_sendfail++; #endif return -1; } pbuf=&buffer[0]; memcpy(pbuf,payload,payload_len); pbuf+=payload_len; #if RF230_CONF_CHECKSUM memcpy(pbuf,&checksum,CHECKSUM_LEN); pbuf+=CHECKSUM_LEN; #endif /* RF230_CONF_CHECKSUM */ #if RF230_CONF_TIMESTAMPS timestamp.authority_level = timesynch_authority_level(); timestamp.time = timesynch_time(); memcpy(pbuf,×tamp,TIMESTAMP_LEN); pbuf+=TIMESTAMP_LEN; #endif /* RF230_CONF_TIMESTAMPS */ /* If radio is sleeping we have to turn it on first */ // /* if need radio calibrate, do it here */ // /* Wait for any previous transmission to finish. */ //nrf24l01_waitidle(); BUSYWAIT_UNTIL(nrf24l01_status(), RTIMER_SECOND / 100); /* set tx mode */ // /* set some features here like auto ack */ // /* get the current power and save, then adjust the power to send */ // if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { nrf24l01_set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1); } else { nrf24l01_set_txpower(TX_PWR_18DBM); //-18dbm } /* Now start transmitting... */ PRINTF("nrf24l01: sending %d bytes\n", payload_len); //send these data SPI_WRITE_BUF(WR_TX_PLOAD, buffer, total_len); if(1) { #if RF230_CONF_TIMESTAMPS rtimer_clock_t txtime = timesynch_time(); #endif /* RF230_CONF_TIMESTAMPS */ if(rf_radio_on) { ENERGEST_OFF(ENERGEST_TYPE_LISTEN); } ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* We wait until transmission has ended so that we get an accurate measurement of the transmission time.*/ //nrf24l01_waitidle(); //radio_set_trx_state(RX_AACK_ON);//Re-enable receive mode BUSYWAIT_UNTIL(isr_event_write.isr_type, RTIMER_SECOND / 100); if(ISR_TX_DS == isr_event_write.isr_type) { tx_result = RADIO_TX_OK; } /*else if(ISR_MAX_RT == state) { tx_result = RADIO_TX_NOACK; }*/ else { tx_result = RADIO_TX_NOACK; } #if RF230_CONF_TIMESTAMPS setup_time_for_transmission = txtime - timestamp.time; if(num_transmissions < 10000) { total_time_for_transmission += timesynch_time() - txtime; total_transmission_len += total_len; num_transmissions++; } #endif /* RF230_CONF_TIMESTAMPS */ #ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,rf230_get_txpower()); #endif ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); if(rf_radio_on) { ENERGEST_ON(ENERGEST_TYPE_LISTEN); } RELEASE_LOCK(); return tx_result; } }