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); }
int cc2420_init(cc2420_t *dev) { uint16_t reg; uint8_t addr[8]; /* reset options and sequence number */ dev->netdev.seq = 0; dev->netdev.flags = 0; /* set default address, channel, PAN ID, and TX power */ luid_get(addr, sizeof(addr)); /* make sure we mark the address as non-multicast and not globally unique */ addr[0] &= ~(0x01); addr[0] |= 0x02; cc2420_set_addr_short(dev, &addr[6]); cc2420_set_addr_long(dev, addr); cc2420_set_pan(dev, CC2420_PANID_DEFAULT); cc2420_set_chan(dev, CC2420_CHAN_DEFAULT); cc2420_set_txpower(dev, CC2420_TXPOWER_DEFAULT); /* set default options */ cc2420_set_option(dev, CC2420_OPT_AUTOACK, true); cc2420_set_option(dev, CC2420_OPT_CSMA, true); cc2420_set_option(dev, CC2420_OPT_TELL_TX_START, true); cc2420_set_option(dev, CC2420_OPT_TELL_RX_END, true); #ifdef MODULE_NETSTATS_L2 cc2420_set_option(dev, CC2420_OPT_TELL_RX_END, true); #endif /* set default protocol*/ #ifdef MODULE_GNRC_SIXLOWPAN dev->netdev.proto = GNRC_NETTYPE_SIXLOWPAN; #elif MODULE_GNRC dev->netdev.proto = GNRC_NETTYPE_UNDEF; #endif /* change default RX bandpass filter to 1.3uA (as recommended) */ reg = cc2420_reg_read(dev, CC2420_REG_RXCTRL1); reg |= CC2420_RXCTRL1_RXBPF_LOCUR; cc2420_reg_write(dev, CC2420_REG_RXCTRL1, reg); /* set the FIFOP threshold to maximum. */ cc2420_reg_write(dev, CC2420_REG_IOCFG0, CC2420_PKT_MAXLEN); /* turn off "Security enable" (page 33). */ reg = cc2420_reg_read(dev, CC2420_REG_SECCTRL0); reg &= ~CC2420_SECCTRL0_RXFIFO_PROT; cc2420_reg_write(dev, CC2420_REG_SECCTRL0, reg); /* set preamble length to 3 leading zero byte */ /* and turn on hardware CRC generation */ reg = cc2420_reg_read(dev, CC2420_REG_MDMCTRL0); reg &= ~(CC2420_MDMCTRL0_PREAMBLE_M); reg |= CC2420_MDMCTRL0_PREAMBLE_3B; reg |= CC2420_MDMCTRL0_AUTOCRC; cc2420_reg_write(dev, CC2420_REG_MDMCTRL0, reg); /* go into RX state */ cc2420_set_state(dev, CC2420_GOTO_RX); return 0; }