void cc2420_set_chan_pan_addr(unsigned channel, /* 11 - 26 */ unsigned pan, unsigned addr, const u8_t *ieee_addr) { /* * Subtract the base channel (11), multiply by 5, which is the * channel spacing. 357 is 2405-2048 and 0x4000 is LOCK_THR = 1. */ u8_t spiStatusByte; u16_t f = channel; int s; f = 5*(f - 11) + 357 + 0x4000; /* * Writing RAM requires crystal oscillator to be stable. */ do { spiStatusByte = cc2420_status(); } while (!(spiStatusByte & (BV(CC2420_XOSC16M_STABLE)))); pan_id = pan; cc2420_setreg(CC2420_FSCTRL, f); s = splhigh(); FASTSPI_WRITE_RAM_LE(&pan, CC2420RAM_PANID, 2, f); FASTSPI_WRITE_RAM_LE(&addr, CC2420RAM_SHORTADDR, 2, f); if (ieee_addr != NULL) FASTSPI_WRITE_RAM_LE(ieee_addr, CC2420RAM_IEEEADDR, 8, f); splx(s); }
/* * Request packet to be sent using CSMA-CA. Requires that RSSI is * valid. * * Return UIP_FW_DROPPED on failure. */ int cc2420_resend(void) { unsigned i; if (FIFOP_IS_1 && !FIFO_IS_1) { process_poll(&cc2420_process); PRINTF("rxfifo overflow!\n"); } /* 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 (CCA_IS_1) { cc2420_strobe(CC2420_STXONCCA); for (i = LOOP_20_SYMBOLS; i > 0; i--) if (SFD_IS_1) { if (cc2420_status() & BV(CC2420_TX_ACTIVE)) return UIP_FW_OK; /* Transmission has started. */ else break; /* We must be receiving. */ } } return UIP_FW_DROPPED; /* Transmission never started! */ }
static int _init(netdev2_t *netdev) { cc2420_t *dev = (cc2420_t *)netdev; uint16_t reg; /* initialize power and reset pins -> put the device into reset state */ gpio_init(dev->params.pin_reset, GPIO_OUT); gpio_set(dev->params.pin_reset); gpio_init(dev->params.pin_vrefen, GPIO_OUT); gpio_clear(dev->params.pin_vrefen); /* initialize the input lines */ gpio_init(dev->params.pin_cca, GPIO_IN); gpio_init(dev->params.pin_sfd, GPIO_IN); gpio_init(dev->params.pin_fifo, GPIO_IN); gpio_init_int(dev->params.pin_fifop, GPIO_IN, GPIO_RISING, _irq_handler, dev); /* initialize the chip select line and the SPI bus */ gpio_init(dev->params.pin_cs, GPIO_OUT); gpio_set(dev->params.pin_cs); /* power on and toggle reset */ gpio_set(dev->params.pin_vrefen); gpio_clear(dev->params.pin_reset); xtimer_usleep(CC2420_RESET_DELAY); gpio_set(dev->params.pin_reset); /* test the connection to the device by reading MANFIDL register */ reg = cc2420_reg_read(dev, CC2420_REG_MANFIDL); if (reg != CC2420_MANFIDL_VAL) { DEBUG("cc2420: init: unable to communicate with device\n"); return -1; } /* turn on the oscillator and wait for it to be stable */ cc2420_en_xosc(dev); if (!(cc2420_status(dev) & CC2420_STATUS_XOSC_STABLE)) { DEBUG("cc2420: init: oscillator did not stabilize\n"); return -1; } #ifdef MODULE_NETSTATS_L2 memset(&netdev->stats, 0, sizeof(netstats_t)); #endif return cc2420_init((cc2420_t *)dev); }
void cc2420_off(void) { u8_t spiStatusByte; if (receive_on == 0) return; receive_on = 0; /* Wait for transmission to end before turning radio off. */ do { spiStatusByte = cc2420_status(); } while (spiStatusByte & BV(CC2420_TX_ACTIVE)); cc2420_strobe(CC2420_SRFOFF); DISABLE_FIFOP_INT(); }
int cc2420_send(struct hdr_802_15 *hdr, u8_t hdr_len, const u8_t *payload, u8_t payload_len) { u8_t spiStatusByte; int s; /* struct hdr_802_15::len shall *not* be counted, thus the -1. * 2 == sizeof(footer). */ if (((hdr_len - 1) + payload_len + 2) > MAX_PACKET_LEN) return -1; /* This code uses the CC2420 CCA (Clear Channel Assessment) to * implement Carrier Sense Multiple Access with Collision Avoidance * (CSMA-CA) and requires the receiver to be enabled and ready. */ if (!receive_on) return -2; /* Wait for previous transmission to finish and RSSI. */ do { spiStatusByte = cc2420_status(); if (!(spiStatusByte & BV(CC2420_RSSI_VALID))) /* RSSI needed by CCA */ continue; } while (spiStatusByte & BV(CC2420_TX_ACTIVE)); hdr->dst_pan = pan_id; /* Not at fixed position! xxx/bg */ last_dst = hdr->dst; /* Not dst either. */ last_used_seq++; hdr->seq = last_used_seq; cc2420_ack_received = 0; /* Write packet to TX FIFO, appending FCS if AUTOCRC is enabled. */ cc2420_strobe(CC2420_SFLUSHTX); /* Cancel send that never started. */ s = splhigh(); FASTSPI_WRITE_FIFO(hdr, hdr_len); FASTSPI_WRITE_FIFO(payload, payload_len); splx(s); /* Send stuff from FIFO now! */ process_post_synch(&cc2420_retransmit_process, PROCESS_EVENT_MSG, NULL); return UIP_FW_OK; }
bool cc2420_cca(cc2420_t *dev) { while (!(cc2420_status(dev) & CC2420_STATUS_RSSI_VALID)) {} return gpio_read(dev->params.pin_cca); }