void at86rf231_rx_handler(void) { uint8_t lqi, fcs_rssi; // read packet length at86rf231_read_fifo(&at86rf231_rx_buffer[rx_buffer_next].length, 1); // read psdu, read packet with length as first byte and lqi as last byte. uint8_t *buf = buffer[rx_buffer_next]; at86rf231_read_fifo(buf, at86rf231_rx_buffer[rx_buffer_next].length); // read lqi which is appended after the psdu lqi = buf[at86rf231_rx_buffer[rx_buffer_next].length - 1]; // read fcs and rssi, from a register fcs_rssi = at86rf231_reg_read(AT86RF231_REG__PHY_RSSI); // build package at86rf231_rx_buffer[rx_buffer_next].lqi = lqi; // RSSI has no meaning here, it should be read during packet reception. at86rf231_rx_buffer[rx_buffer_next].rssi = fcs_rssi & 0x0F; // bit[4:0] // bit7, boolean, 1 FCS valid, 0 FCS not valid at86rf231_rx_buffer[rx_buffer_next].crc = (fcs_rssi >> 7) & 0x01; if (at86rf231_rx_buffer[rx_buffer_next].crc == 0) { DEBUG("Got packet with invalid crc.\n"); return; } ieee802154_frame_read(&buf[1], &at86rf231_rx_buffer[rx_buffer_next].frame, at86rf231_rx_buffer[rx_buffer_next].length); if (at86rf231_rx_buffer[rx_buffer_next].frame.fcf.frame_type != 2) { #if DEBUG_ENABLED ieee802154_frame_print_fcf_frame(&at86rf231_rx_buffer[rx_buffer_next].frame); #endif /* notify transceiver thread if any */ if (transceiver_pid) { msg_t m; m.type = (uint16_t) RCV_PKT_AT86RF231; m.content.value = rx_buffer_next; msg_send_int(&m, transceiver_pid); } } else { #if DEBUG_ENABLED DEBUG("GOT ACK for SEQ %u\n", at86rf231_rx_buffer[rx_buffer_next].frame.seq_nr); ieee802154_frame_print_fcf_frame(&at86rf231_rx_buffer[rx_buffer_next].frame); #endif } // shift to next buffer element if (++rx_buffer_next == AT86RF231_RX_BUF_SIZE) { rx_buffer_next = 0; } // Read IRQ to clear it at86rf231_reg_read(AT86RF231_REG__IRQ_STATUS); }
void at86rf231_switch_to_rx(void) { at86rf231_disable_interrupts(); // Send a FORCE TRX OFF command at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__FORCE_TRX_OFF); // Reset IRQ to TRX END only at86rf231_reg_write(AT86RF231_REG__IRQ_MASK, AT86RF231_IRQ_STATUS_MASK__TRX_END); // Read IRQ to clear it at86rf231_reg_read(AT86RF231_REG__IRQ_STATUS); // Enable IRQ interrupt at86rf231_enable_interrupts(); // Start RX at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__RX_ON); // wait until it is on RX_ON state uint8_t status; uint8_t max_wait = 100; // TODO : move elsewhere, this is in 10us do { status = at86rf231_get_status(); vtimer_usleep(10); if (!--max_wait) { printf("at86rf231 : ERROR : could not enter RX_ON mode"); break; } } while ((status & AT86RF231_TRX_STATUS_MASK__TRX_STATUS) != AT86RF231_TRX_STATUS__RX_ON); }
void at86rf231_rx_handler(void) { uint8_t lqi, fcs_rssi; /* read packet length */ at86rf231_read_fifo(&at86rf231_rx_buffer[rx_buffer_next].length, 1); /* read psdu, read packet with length as first byte and lqi as last byte. */ uint8_t *buf = buffer[rx_buffer_next]; at86rf231_read_fifo(buf, at86rf231_rx_buffer[rx_buffer_next].length); /* read lqi which is appended after the psdu */ lqi = buf[at86rf231_rx_buffer[rx_buffer_next].length - 1]; /* read fcs and rssi, from a register */ fcs_rssi = at86rf231_reg_read(AT86RF231_REG__PHY_RSSI); /* build package */ at86rf231_rx_buffer[rx_buffer_next].lqi = lqi; /* RSSI has no meaning here, it should be read during packet reception. */ at86rf231_rx_buffer[rx_buffer_next].rssi = fcs_rssi & 0x0F; // bit[4:0] /* bit7, boolean, 1 FCS valid, 0 FCS not valid */ at86rf231_rx_buffer[rx_buffer_next].crc = (fcs_rssi >> 7) & 0x01; if (at86rf231_rx_buffer[rx_buffer_next].crc == 0) { DEBUG("at86rf231: Got packet with invalid crc.\n"); return; } #ifdef DEBUG_ENABLED DEBUG("pkg: "); for (int i = 1; i < at86rf231_rx_buffer[rx_buffer_next].length; i++) { DEBUG("%x ", buf[i]); } DEBUG("\n"); #endif /* read buffer into ieee802154_frame */ ieee802154_frame_read(&buf[1], &at86rf231_rx_buffer[rx_buffer_next].frame, at86rf231_rx_buffer[rx_buffer_next].length); /* if packet is no ACK */ if (at86rf231_rx_buffer[rx_buffer_next].frame.fcf.frame_type != IEEE_802154_ACK_FRAME) { #ifdef DEBUG_ENABLED ieee802154_frame_print_fcf_frame(&at86rf231_rx_buffer[rx_buffer_next].frame); #endif if (at86rf231_raw_packet_cb != NULL) { at86rf231_raw_packet_cb(&at86rf231_netdev, (void*)buf, at86rf231_rx_buffer[rx_buffer_next].length, fcs_rssi, lqi, (fcs_rssi >> 7)); }
uint8_t at86rf231_set_channel(uint8_t channel) { uint8_t cca_state; radio_channel = channel; if (channel < RF86RF231_MIN_CHANNEL || channel > RF86RF231_MAX_CHANNEL) { radio_channel = RF86RF231_MAX_CHANNEL; } cca_state = at86rf231_reg_read(AT86RF231_REG__PHY_CC_CCA) & ~AT86RF231_PHY_CC_CCA_MASK__CHANNEL; at86rf231_reg_write(AT86RF231_REG__PHY_CC_CCA, cca_state | (radio_channel & AT86RF231_PHY_CC_CCA_MASK__CHANNEL)); return radio_channel; }
uint8_t at86rf231_get_status(void) { return at86rf231_reg_read(AT86RF231_REG__TRX_STATUS) & AT86RF231_TRX_STATUS_MASK__TRX_STATUS; }
void at86rf231_init(int tpid) { transceiver_pid = tpid; at86rf231_gpio_spi_interrupts_init(); at86rf231_reset(); // TODO : Enable addr decode, auto ack, auto crc // and configure security, power, channel, pan radio_pan = 0; radio_pan = 0x00FF & (uint16_t)at86rf231_reg_read(AT86RF231_REG__PAN_ID_0); radio_pan |= (uint16_t)at86rf231_reg_read(AT86RF231_REG__PAN_ID_1) << 8; radio_channel = at86rf231_reg_read(AT86RF231_REG__PHY_CC_CCA) & AT86RF231_PHY_CC_CCA_MASK__CHANNEL; radio_address = 0x00FF & (uint16_t)at86rf231_reg_read(AT86RF231_REG__SHORT_ADDR_0); radio_address |= at86rf231_reg_read(AT86RF231_REG__SHORT_ADDR_1) << 8; radio_address_long = 0x00000000000000FF & (uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_0); radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 8; radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 16; radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 24; radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 32; radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 40; radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 48; radio_address_long |= ((uint64_t)at86rf231_reg_read(AT86RF231_REG__IEEE_ADDR_1)) << 56; at86rf231_switch_to_rx(); }