/*---------------------------------------------------------------------------*/ void cc2420_set_pan_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr) { uint16_t f = 0; uint8_t tmp[2]; GET_LOCK(); /* * Writing RAM requires crystal oscillator to be stable. */ BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 10); tmp[0] = pan & 0xff; tmp[1] = pan >> 8; CC2420_WRITE_RAM(&tmp, CC2420RAM_PANID, 2); tmp[0] = addr & 0xff; tmp[1] = addr >> 8; CC2420_WRITE_RAM(&tmp, CC2420RAM_SHORTADDR, 2); if(ieee_addr != NULL) { uint8_t tmp_addr[8]; /* LSB first, MSB last for 802.15.4 addresses in CC2420 */ for (f = 0; f < 8; f++) { tmp_addr[7 - f] = ieee_addr[f]; } CC2420_WRITE_RAM(tmp_addr, CC2420RAM_IEEEADDR, 8); } RELEASE_LOCK(); }
/* Encrypt at most 16 bytes of data. */ static void cipher16(uint8_t *data, int len) { uint8_t status; len = MIN(len, MAX_DATALEN); CC2420_WRITE_RAM(data, CC2420RAM_SABUF, len); CC2420_STROBE(CC2420_SAES); /* Wait for the encryption to finish */ do { CC2420_GET_STATUS(status); } while(status & BV(CC2420_ENC_BUSY)); CC2420_READ_RAM(data, CC2420RAM_SABUF, len); }
/*---------------------------------------------------------------------------*/ 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. */ #ifndef CC2420_CONF_SYMBOL_LOOP_COUNT #error CC2420_CONF_SYMBOL_LOOP_COUNT needs to be set!!! #else #define LOOP_20_SYMBOLS CC2420_CONF_SYMBOL_LOOP_COUNT #endif #if WITH_SEND_CCA strobe(CC2420_SRXON); BUSYWAIT_UNTIL(status() & BV(CC2420_RSSI_VALID), RTIMER_SECOND / 10); strobe(CC2420_STXONCCA); #else /* WITH_SEND_CCA */ strobe(CC2420_STXON); #endif /* WITH_SEND_CCA */ for(i = LOOP_20_SYMBOLS; i > 0; i--) { if(CC2420_SFD_IS_1) { { rtimer_clock_t sfd_timestamp; sfd_timestamp = cc2420_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. */ CC2420_WRITE_RAM(&sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2); } } 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. */ 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(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10); #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_COLLISION; }