X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=blobdiff_plain;f=tos%2Fchips%2Fcc2420_tkn154%2FCC2420TransmitP.nc;h=4e4c955437f39e60a400e08cc6fc93e850071164;hp=d746c854098e781a7849e1e647be7672e588ff94;hb=e9bfab607e051bae6afb47b44892ce37541d1b44;hpb=adf1de6c009d13b7b52e68535c63b28f59c97400 diff --git a/tos/chips/cc2420_tkn154/CC2420TransmitP.nc b/tos/chips/cc2420_tkn154/CC2420TransmitP.nc index d746c854..4e4c9554 100644 --- a/tos/chips/cc2420_tkn154/CC2420TransmitP.nc +++ b/tos/chips/cc2420_tkn154/CC2420TransmitP.nc @@ -34,6 +34,14 @@ * @author David Moss * @author Jung Il Choi Initial SACK implementation * @author Jan Hauer + * + * IMPORTANT: this module does not use the SPI Resource interface, + * instead the caller must take care of the resource arbitration + * (i.e. the caller must own the resource before calling commands + * like CC2420Tx.loadTXFIFO()) + * Note: on TelosB there seems to be a problem if BackoffAlarm + * is virtualized - i.e. BackoffAlarm should be a dedicated Alarm. + * * @version $Revision$ $Date$ */ @@ -45,21 +53,15 @@ module CC2420TransmitP { provides interface Init; provides interface AsyncStdControl; -/* interface CC2420Transmit;*/ provides interface CC2420Tx; -/* provides interface RadioBackoff;*/ -/* provides interface RadioTimeStamping as TimeStamp;*/ -/* provides interface ReceiveIndicator as EnergyIndicator;*/ -/* provides interface ReceiveIndicator as ByteIndicator;*/ - -/* uses interface Alarm as BackoffAlarm;*/ uses interface Alarm as BackoffAlarm; uses interface GpioCapture as CaptureSFD; uses interface GeneralIO as CCA; uses interface GeneralIO as CSN; uses interface GeneralIO as SFD; + uses interface GeneralIO as FIFO; + uses interface GeneralIO as FIFOP; -/* uses interface Resource as SpiResource;*/ uses interface ChipSpiResource; uses interface CC2420Fifo as TXFIFO; uses interface CC2420Ram as TXFIFO_RAM; @@ -71,7 +73,7 @@ module CC2420TransmitP { uses interface CC2420Strobe as SRXON; uses interface CC2420Strobe as SRFOFF; uses interface CC2420Strobe as SFLUSHRX; - uses interface CC2420Strobe as SACKPEND; // JH: ACKs must have pending flag set + uses interface CC2420Strobe as SACKPEND; uses interface CC2420Register as MDMCTRL1; uses interface CaptureTime; uses interface ReferenceTime; @@ -86,26 +88,22 @@ implementation { S_STOPPED, S_STARTED, S_LOAD, - S_SAMPLE_CCA, - S_BEGIN_TRANSMIT, + S_READY_TX, S_SFD, S_EFD, S_ACK_WAIT, - S_CANCEL, } cc2420_transmit_state_t; - // This specifies how many jiffies the stack should wait after a + // This specifies how many symbols the stack should wait after a // TXACTIVE to receive an SFD interrupt before assuming something is // wrong and aborting the send. There seems to be a condition // on the micaZ where the SFD interrupt is never handled. enum { - CC2420_ABORT_PERIOD = 320 + CC2420_ABORT_PERIOD = 320*3, }; -/* norace message_t *m_msg;*/ - norace ieee154_txframe_t *m_data; - norace uint8_t m_txFrameLen; - ieee154_reftime_t m_timestamp; + norace ieee154_txframe_t *m_frame; + ieee154_timestamp_t m_timestamp; cc2420_transmit_state_t m_state = S_STOPPED; @@ -119,27 +117,16 @@ implementation { /** Let the CC2420 driver keep a lock on the SPI while waiting for an ack */ norace bool abortSpiRelease; - /** Total CCA checks that showed no activity before the NoAck LPL send */ - norace int8_t totalCcaChecks; - /** The initial backoff period */ norace uint16_t myInitialBackoff; /** The congestion backoff period */ norace uint16_t myCongestionBackoff; + norace uint32_t alarmStartTime; /***************** Prototypes ****************/ - error_t load( ieee154_txframe_t *data ); - error_t resend( bool cca ); - void loadTXFIFO(); - void attemptSend(bool cca); - void congestionBackoff(); - error_t acquireSpiResource(); - error_t releaseSpiResource(); -/* void signalDone( error_t err );*/ void signalDone( bool ackFramePending, error_t err ); -/* void cancelTx();*/ /***************** Init Commands *****************/ command error_t Init.init() { @@ -166,81 +153,91 @@ implementation { m_state = S_STOPPED; call BackoffAlarm.stop(); call CaptureSFD.disable(); -/* call SpiResource.release(); // REMOVE*/ call CSN.set(); } return SUCCESS; } - /**************** Send Commands ****************/ + /**************** Load/Send Commands ****************/ -/* async command error_t Send.send( message_t* p_msg, bool useCca ) {*/ - async command error_t CC2420Tx.loadTXFIFO(ieee154_txframe_t *data) { - return load( data); - } - - async command void CC2420Tx.send(bool cca) + async command error_t CC2420Tx.loadTXFIFO(ieee154_txframe_t *data) { - attemptSend(cca); - } - - async command bool CC2420Tx.cca() - { - return call CCA.get(); - } - - async command error_t CC2420Tx.modify( uint8_t offset, uint8_t* buf, - uint8_t len ) { - call CSN.set(); - call CSN.clr(); - call TXFIFO_RAM.write( offset, buf, len ); - call CSN.set(); + atomic { + if ( m_state != S_STARTED ) + return FAIL; + m_state = S_LOAD; + m_frame = data; + m_frame->header->length = m_frame->headerLen + m_frame->payloadLen + 2; // 2 for CRC + call CSN.set(); + call CSN.clr(); + call SFLUSHTX.strobe(); // flush out anything that was in TXFIFO + call CSN.set(); + call CSN.clr(); + call TXFIFO.write( &(m_frame->header->length), 1 ); + } return SUCCESS; - } - - async command void CC2420Tx.lockChipSpi() + } + + async event void TXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len, error_t error) { - abortSpiRelease = TRUE; + atomic { + call CSN.set(); + if (tx_buf == &(m_frame->header->length)){ + call CSN.clr(); + call TXFIFO.write( m_frame->header->mhr, m_frame->headerLen ); + return; + } else if (tx_buf == m_frame->header->mhr) { + call CSN.clr(); + call TXFIFO.write( m_frame->payload, m_frame->payloadLen ); + return; + } + } + m_state = S_READY_TX; + signal CC2420Tx.loadTXFIFODone(m_frame, error); } - async command void CC2420Tx.unlockChipSpi() + + async command error_t CC2420Tx.send(bool cca) { - abortSpiRelease = FALSE; - } + cc2420_status_t status; + bool congestion = TRUE; - /***************** Indicator Commands ****************/ -/* command bool EnergyIndicator.isReceiving() {*/ -/* return !(call CCA.get());*/ -/* }*/ -/* */ -/* command bool ByteIndicator.isReceiving() {*/ -/* bool high;*/ -/* atomic high = sfdHigh;*/ -/* return high;*/ -/* }*/ - + atomic { + if (m_state != S_READY_TX) + return EOFF; + call CSN.set(); + call CSN.clr(); - /***************** RadioBackoff Commands ****************/ - /** - * Must be called within a requestInitialBackoff event - * @param backoffTime the amount of time in some unspecified units to backoff - */ -/* async command void RadioBackoff.setInitialBackoff(uint16_t backoffTime) {*/ -/* myInitialBackoff = backoffTime + 1;*/ -/* }*/ - - /** - * Must be called within a requestCongestionBackoff event - * @param backoffTime the amount of time in some unspecified units to backoff - */ -/* async command void RadioBackoff.setCongestionBackoff(uint16_t backoffTime) {*/ -/* myCongestionBackoff = backoffTime + 1;*/ -/* }*/ - -/* async command void RadioBackoff.setCca(bool useCca) {*/ -/* }*/ - - + // DEBUG + //P2OUT |= 0x40; // P2.6 high + status = cca ? call STXONCCA.strobe() : call STXON.strobe(); + //status = call STXON.strobe(); + //U0TXBUF = 0x04; // strobe STXON + //while (!(IFG1 & URXIFG0)); + //status = U0RXBUF; + //call CSN.set(); + + if ( !( status & CC2420_STATUS_TX_ACTIVE ) ) { + status = call SNOP.strobe(); + if ( status & CC2420_STATUS_TX_ACTIVE ) { + congestion = FALSE; + } + } + + call CSN.set(); + // DEBUG: on telosb SFD is connected to Pin P4.1 + //if (!congestion) {while (!(P4IN & 0x02)) ; P6OUT &= ~0x80;} + + if (congestion){ + return FAIL; // channel busy + } else { + m_state = S_SFD; + m_frame->metadata->timestamp = IEEE154_INVALID_TIMESTAMP; // pessimistic + call BackoffAlarm.start(CC2420_ABORT_PERIOD); + return SUCCESS; + } + } + } /** * The CaptureSFD event is actually an interrupt from the capture pin @@ -256,33 +253,19 @@ implementation { * would have picked up and executed had our microcontroller been fast enough. */ async event void CaptureSFD.captured( uint16_t time ) { - // "time" is from TimerB capture, which is sourced by SMCLK (1MHz) //P2OUT &= ~0x40; // debug: P2.6 low - uint32_t localTime; atomic { switch( m_state ) { case S_SFD: m_state = S_EFD; sfdHigh = TRUE; - call CaptureTime.convert(time, &m_timestamp, -8); // -8 for the preamble call CaptureSFD.captureFallingEdge(); -/* signal TimeStamp.transmittedSFD( time, m_msg );*/ - localTime = call ReferenceTime.toLocalTime(&m_timestamp); - signal CC2420Tx.transmittedSFD(localTime, m_data ); - //if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) { - //if ( (m_data->header)[0] & ( 1 << IEEE154_FCF_ACK_REQ ) ) { - // This is an ack packet, don't release the chip's SPI bus lock. - //} - releaseSpiResource(); + // timestamp denotes time of first bit (chip) of PPDU on the channel + // offset: -10 for 5 bytes (preamble+SFD) + if (call CaptureTime.convert(time, &m_timestamp, -10) == SUCCESS) + m_frame->metadata->timestamp = call ReferenceTime.toLocalTime(&m_timestamp); call BackoffAlarm.stop(); - m_data->metadata->timestamp = localTime; - - -/* if ( ( ( (call CC2420PacketBody.getHeader( m_msg ))->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7 ) == IEEE154_TYPE_DATA ) {*/ -/* (call CC2420PacketBody.getMetadata( m_msg ))->time = time;*/ -/* }*/ - if ( call SFD.get() ) { break; } @@ -291,11 +274,15 @@ implementation { case S_EFD: sfdHigh = FALSE; call CaptureSFD.captureRisingEdge(); - -/* if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {*/ - if ( (m_data->header->mhr)[0] & ( 1 << IEEE154_FCF_ACK_REQ ) ) { + signal CC2420Tx.transmissionStarted(m_frame); + if ( (m_frame->header->mhr)[0] & ( 1 << IEEE154_FCF_ACK_REQ ) ) { + // wait for the ACK m_state = S_ACK_WAIT; - call BackoffAlarm.start( 200 ); // we need to have *completely* received the ACK + alarmStartTime = call BackoffAlarm.getNow(); + // we need to have *completely* received the ACK, 32+22 symbols + // should theroretically be enough, but there can be delays in + // servicing the FIFOP interrupt, so we use 100 symbols here + call BackoffAlarm.start( 100 ); } else { signalDone(FALSE, SUCCESS); } @@ -306,11 +293,11 @@ implementation { /** Fall Through because the next interrupt was already received */ default: + // The CC2420 is in receive mode. if ( !m_receiving ) { sfdHigh = TRUE; call CaptureSFD.captureFallingEdge(); -/* signal TimeStamp.receivedSFD( time );*/ - call CaptureTime.convert(time, &m_timestamp, -8); + call CaptureTime.convert(time, &m_timestamp, -10); call CC2420Receive.sfd( &m_timestamp ); m_receiving = TRUE; m_prev_time = time; @@ -318,26 +305,44 @@ implementation { // wait for the next interrupt before moving on return; } + // if we move on, then the timestamp will be invalid! } sfdHigh = FALSE; call CaptureSFD.captureRisingEdge(); m_receiving = FALSE; -/* if ( time - m_prev_time < 10 ) {*/ -#ifdef PIERCEBOARD_ENABLED - if ( time - m_prev_time < 10*30 ) { -#else - if ( time - m_prev_time < 10 ) { -#endif + if (!call CaptureTime.isValidTimestamp(m_prev_time, time)) call CC2420Receive.sfd_dropped(); - } break; } } } + + async command bool CC2420Tx.cca() + { + return call CCA.get(); + } + + async command error_t CC2420Tx.modify( uint8_t offset, uint8_t* buf, uint8_t len ) + { + call CSN.set(); + call CSN.clr(); + call TXFIFO_RAM.write( offset, buf, len ); + call CSN.set(); + return SUCCESS; + } + + async command void CC2420Tx.lockChipSpi() + { + abortSpiRelease = TRUE; + } + + async command void CC2420Tx.unlockChipSpi() + { + abortSpiRelease = FALSE; + } - /***************** ChipSpiResource Events ****************/ async event void ChipSpiResource.releasing() { if(abortSpiRelease) { call ChipSpiResource.abortRelease(); @@ -351,392 +356,57 @@ implementation { * our send is complete. */ async event void CC2420Receive.receive( uint8_t type, message_t *ackFrame ){ -/* async event void CC2420Receive.receive( uint8_t type, message_t* ack_msg ) {*/ -/* cc2420_header_t* ack_header;*/ -/* cc2420_header_t* msg_header;*/ -/* cc2420_metadata_t* msg_metadata;*/ -/* uint8_t* ack_buf;*/ -/* uint8_t length;*/ - atomic { if ( type == IEEE154_TYPE_ACK ) { - - /* ack_header = call CC2420PacketBody.getHeader( ack_msg );*/ - /* msg_header = call CC2420PacketBody.getHeader( m_msg );*/ - - /* if ( m_state == S_ACK_WAIT && msg_header->dsn == ack_header->dsn ) {*/ if ( m_state == S_ACK_WAIT && - m_data->header->mhr[2] == ((ieee154_header_t*) ackFrame->header)->mhr[2] ) { // compare seqno + m_frame->header->mhr[2] == ((ieee154_header_t*) ackFrame->header)->mhr[2] ) { // compare seqno call BackoffAlarm.stop(); - - /* msg_metadata = call CC2420PacketBody.getMetadata( m_msg );*/ - /* ack_buf = (uint8_t *) ack_header;*/ - /* length = ack_header->length;*/ - /* */ - /* msg_metadata->ack = TRUE;*/ - /* msg_metadata->rssi = ack_buf[ length - 1 ];*/ - /* msg_metadata->lqi = ack_buf[ length ] & 0x7f;*/ signalDone(( ((ieee154_header_t*) ackFrame->header)->mhr[0] & 0x10) ? TRUE: FALSE, SUCCESS); } } } } - - /***************** SpiResource Events ****************/ - /* - event void SpiResource.granted() { - uint8_t cur_state; - - atomic { - cur_state = m_state; - } - - switch( cur_state ) { - case S_LOAD: - loadTXFIFO(); - break; - - case S_BEGIN_TRANSMIT: - attemptSend(); - break; - - case S_CANCEL: - cancelTx(); - break; - - default: - releaseSpiResource(); - break; - } - } - */ - - /***************** TXFIFO Events ****************/ - /** - * The TXFIFO is used to load packets into the transmit buffer on the - * chip - */ - async event void TXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len, - error_t error ) { - - call CSN.set(); - - if (tx_buf == &m_txFrameLen){ - // until here: 1.65 ms - call CSN.clr(); - call TXFIFO.write( m_data->header->mhr, m_data->headerLen ); - return; - } else if (tx_buf == m_data->header->mhr) { - // until here: 2.2 ms - call CSN.clr(); - call TXFIFO.write( m_data->payload, m_data->payloadLen ); - return; - } - // until here: 4.6 ms (no DMA on USART0) - // until here: 3.3 ms (with DMA on USART0) - // P2OUT &= ~0x40; // P2.1 low - -/* if ( m_state == S_CANCEL ) {*/ -/* atomic {*/ -/* call CSN.clr();*/ -/* call SFLUSHTX.strobe();*/ -/* call CSN.set();*/ -/* }*/ -/* releaseSpiResource();*/ -/* m_state = S_STARTED;*/ - -/* } else if ( !m_cca ) {*/ -/* } else {*/ - m_state = S_BEGIN_TRANSMIT; - releaseSpiResource(); - signal CC2420Tx.loadTXFIFODone(m_data, error); -/* attemptSend();*/ -/* }*/ - -/* } else {*/ -/* releaseSpiResource();*/ -/* atomic {*/ -/* if (m_state == S_LOAD_CANCEL) {*/ -/* m_state = S_CCA_CANCEL;*/ -/* } else {*/ -/* m_state = S_SAMPLE_CCA;*/ -/* }*/ -/* }*/ -/* signal CC2420Tx.loadTXFIFODone(m_data, error);*/ - -/* signal RadioBackoff.requestInitialBackoff(m_msg);*/ -/* call BackoffAlarm.start(myInitialBackoff);*/ -/* }*/ - } - - - async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len, - error_t error ) { - } - - /***************** Timer Events ****************/ - /** - * The backoff timer is mainly used to wait for a moment before trying - * to send a packet again. But we also use it to timeout the wait for - * an acknowledgement, and timeout the wait for an SFD interrupt when - * we should have gotten one. - */ async event void BackoffAlarm.fired() { atomic { switch( m_state ) { - - case S_SAMPLE_CCA : - // sample CCA and wait a little longer if free, just in case we - // sampled during the ack turn-around window - if ( call CCA.get() ) { - m_state = S_BEGIN_TRANSMIT; - call BackoffAlarm.start( CC2420_TIME_ACK_TURNAROUND ); - - } else { - congestionBackoff(); - } - break; - - case S_BEGIN_TRANSMIT: - case S_CANCEL: - // should never happen - call Leds.led0On(); -/* if ( acquireSpiResource() == SUCCESS ) {*/ -/* attemptSend();*/ -/* }*/ - break; - - case S_ACK_WAIT: -/* signalDone( SUCCESS );*/ - signalDone( FALSE, FAIL ); - break; - - case S_SFD: - // We didn't receive an SFD interrupt within CC2420_ABORT_PERIOD - // jiffies. Assume something is wrong. - atomic { - call CSN.set(); - call CSN.clr(); - call SFLUSHTX.strobe(); - call CSN.set(); - } - signalDone( FALSE, ERETRY ); - releaseSpiResource(); - //call CaptureSFD.captureRisingEdge(); - break; - - default: - break; - } - } - } - /***************** Functions ****************/ - /** - * Set up a message to be sent. First load it into the outbound tx buffer - * on the chip, then attempt to send it. - * @param *p_msg Pointer to the message that needs to be sent - * @param cca TRUE if this transmit should use clear channel assessment - */ - error_t load( ieee154_txframe_t *data) { - atomic { - if (m_state == S_CANCEL) { - return ECANCEL; - } - - if ( m_state != S_STARTED ) { - return FAIL; - } - - m_state = S_LOAD; -/* m_msg = p_msg;*/ - m_data = data; - totalCcaChecks = 0; - } - - if ( acquireSpiResource() == SUCCESS ) { - loadTXFIFO(); - } - - return SUCCESS; - } - - /** - * Resend a packet that already exists in the outbound tx buffer on the - * chip - * @param cca TRUE if this transmit should use clear channel assessment - */ -/* error_t resend( bool cca ) {*/ - -/* atomic {*/ -/* if (m_state == S_LOAD_CANCEL*/ -/* || m_state == S_CCA_CANCEL*/ -/* || m_state == S_TX_CANCEL) {*/ -/* return ECANCEL;*/ -/* }*/ -/* */ -/* if ( m_state != S_STARTED ) {*/ -/* return FAIL;*/ -/* }*/ -/* */ -/* m_cca = cca;*/ -/* m_state = cca ? S_SAMPLE_CCA : S_BEGIN_TRANSMIT;*/ -/* totalCcaChecks = 0;*/ -/* }*/ -/* */ -/* if(m_cca) {*/ -/* signal RadioBackoff.requestInitialBackoff(m_msg);*/ -/* call BackoffAlarm.start( myInitialBackoff );*/ -/* */ -/* } else if ( acquireSpiResource() == SUCCESS ) {*/ -/* attemptSend();*/ -/* }*/ -/* */ -/* return SUCCESS;*/ -/* }*/ - - /** - * Attempt to send the packet we have loaded into the tx buffer on - * the radio chip. The STXONCCA will send the packet immediately if - * the channel is clear. If we're not concerned about whether or not - * the channel is clear (i.e. m_cca == FALSE), then STXON will send the - * packet without checking for a clear channel. - * - * If the packet didn't get sent, then congestion == TRUE. In that case, - * we reset the backoff timer and try again in a moment. - * - * If the packet got sent, we should expect an SFD interrupt to take - * over, signifying the packet is getting sent. - */ - void attemptSend(bool cca) { - uint8_t status; - bool congestion = TRUE; - - atomic { - call CSN.set(); - call CSN.clr(); + case S_SFD: + case S_EFD: // fall through + // We didn't receive an SFD interrupt within CC2420_ABORT_PERIOD + // jiffies. Assume something is wrong. + atomic { + call CSN.set(); + call CSN.clr(); + call SFLUSHTX.strobe(); + call CSN.set(); + } + signalDone( FALSE, ERETRY ); + break; - // STXONCCA costs about ? symbols, i.e. attemptSend should be called - // ? symbols, before the actual CCA - //P2OUT |= 0x40; // P2.6 high - status = cca ? call STXONCCA.strobe() : call STXON.strobe(); - //status = call STXON.strobe(); - //U0TXBUF = 0x04; // strobe STXON - //while (!(IFG1 & URXIFG0)); - //status = U0RXBUF; - //call CSN.set(); + case S_ACK_WAIT: + /* signalDone( SUCCESS );*/ + signalDone( FALSE, ENOACK ); + break; - if ( !( status & CC2420_STATUS_TX_ACTIVE ) ) { - status = call SNOP.strobe(); - if ( status & CC2420_STATUS_TX_ACTIVE ) { - congestion = FALSE; - } - } - - call CSN.set(); - // debug: on telosb SFD is connected to Pin P4.1 - if (!congestion) {while (!(P4IN & 0x02)) ; P6OUT &= ~0x80;} - if (congestion){ - call ReferenceTime.getNow(&m_timestamp, 0); - m_state = S_BEGIN_TRANSMIT; // don't use a state S_SAMPLE_CCA - releaseSpiResource(); - signal CC2420Tx.sendDone(m_data, &m_timestamp, FALSE, EBUSY); // waiting for the next send() - } else { - m_state = S_SFD; // wait for an ACK - signal CC2420Tx.transmissionStarted(m_data); - call BackoffAlarm.start(CC2420_ABORT_PERIOD*3); + default: + break; } - return; // we still own the SPI, either we wait for an ACK or resend is going to be called soon } - -/* if ( congestion ) {*/ -/* totalCcaChecks = 0;*/ -/* releaseSpiResource();*/ -/* congestionBackoff();*/ -/* } else {*/ -/* call BackoffAlarm.start(CC2420_ABORT_PERIOD);*/ -/* }*/ } - - /** - * Congestion Backoff - */ - void congestionBackoff() { - atomic { -/* signal RadioBackoff.requestCongestionBackoff(m_msg);*/ - call BackoffAlarm.start(myCongestionBackoff); - } - } - - error_t acquireSpiResource() { - return SUCCESS; - /* - error_t error = call SpiResource.immediateRequest(); - if ( error != SUCCESS ) { - call SpiResource.request(); - } - return error; - */ - } - - error_t releaseSpiResource() { - //call SpiResource.release(); - return SUCCESS; - } - - - /** - * Setup the packet transmission power and load the tx fifo buffer on - * the chip with our outbound packet. - * - * Warning: the tx_power metadata might not be initialized and - * could be a value other than 0 on boot. Verification is needed here - * to make sure the value won't overstep its bounds in the TXCTRL register - * and is transmitting at max power by default. - * - * It should be possible to manually calculate the packet's CRC here and - * tack it onto the end of the header + payload when loading into the TXFIFO, - * so the continuous modulation low power listening strategy will continually - * deliver valid packets. This would increase receive reliability for - * mobile nodes and lossy connections. The crcByte() function should use - * the same CRC polynomial as the CC2420's AUTOCRC functionality. - */ - void loadTXFIFO() { -/* cc2420_header_t* header = call CC2420PacketBody.getHeader( m_msg );*/ -/* uint8_t tx_power = (call CC2420PacketBody.getMetadata( m_msg ))->tx_power;*/ - m_txFrameLen = m_data->headerLen + m_data->payloadLen + 2; -/* if ( !tx_power ) {*/ -/* tx_power = CC2420_DEF_RFPOWER;*/ -/* }*/ - call CSN.set(); - call CSN.clr(); - call SFLUSHTX.strobe(); // flush out anything that was in there - call CSN.set(); - call CSN.clr(); - -/* call TXFIFO.write( (uint8_t*)header, header->length - 1);*/ - call TXFIFO.write( &m_txFrameLen, 1 ); - - } - void signalDone( bool ackFramePending, error_t err ) { + ieee154_timestamp_t *txTime = &m_timestamp; atomic m_state = S_STARTED; - signal CC2420Tx.sendDone( m_data, &m_timestamp, ackFramePending, err ); + if (m_frame->metadata->timestamp == IEEE154_INVALID_TIMESTAMP) + txTime = NULL; + signal CC2420Tx.sendDone( m_frame, txTime, ackFramePending, err ); call ChipSpiResource.attemptRelease(); -/* signal Send.sendDone( m_msg, err );*/ } - - /***************** Tasks ****************/ - - /***************** Defaults ****************/ -/* default async event void TimeStamp.transmittedSFD( uint16_t time, message_t* p_msg ) {*/ -/* }*/ - -/* default async event void TimeStamp.receivedSFD( uint16_t time ) {*/ -/* }*/ + async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len, + error_t error ) { + } }