def receive(self): self.set_rfm22_mode('ready') # is there any particular order these should be in? self.set_rx_fifo_almost_full_threshold(17) self.tx_ant.write(0) self.rx_ant.write(1) self.clear_interrupt() self.clear_fifo() self.set_rfm22_state('rx') self.enable_interrupt('valid_packet_received') print "RSSI Threshold: ", '{0:d}'.format(spi.read(0x27)) print "RSSI Indicator: ", '{0:d}'.format(spi.read(0x26)) print "receiving packet..." while self.module_power_state() == 'rx': result = self.irq.read() rssi = '{0:d}'.format(spi.read(0x26)) self.rssi_data.append([time.time(), rssi]) # print "RSSI Indicator: ", rssi # print "interrupt: ", int(result) if (int(result) == 0): rx_buffer = [] for i in range(17): rx_buffer.append(self.read_rx_fifo()) if (rx_buffer == self.packet): print "Packet Received" self.packet_count += 1
def enable_interrupt(self, signal): reg_1 = spi.read(0x05) reg_2 = spi.read(0x06) if signal == 'valid_packet_received': spi.write(0x05, reg_1 | 0x02) else: print "error in enable_interrupt"
def receive(self): self.set_rfm22_mode('ready') # is there any particular order these should be in? self.set_rx_fifo_almost_full_threshold(17) self.tx_ant.write(0) self.rx_ant.write(1) self.clear_interrupt() self.clear_fifo() self.set_rfm22_state('rx') self.enable_interrupt('valid_packet_received') print "RSSI Threshold: ", '{0:d}'.format(spi.read(0x27)) print "RSSI Indicator: ", '{0:d}'.format(spi.read(0x26)) print "receiving packet..." while self.module_power_state() == 'rx': result = self.irq.read() rssi = '{0:d}'.format(spi.read(0x26)) self.rssi_data.append([time.time(), rssi]) # print "RSSI Indicator: ", rssi # print "interrupt: ", int(result) if ( int(result) == 0 ): rx_buffer = [] for i in range(17): rx_buffer.append(self.read_rx_fifo()) if ( rx_buffer == self.packet ): print "Packet Received" self.packet_count += 1
def listen(self, freq, rssi_threshold=100, timeout=0.5, DEBUG=True): """ Listen before talk. This function implements listen-before-talk or carrier sense. RSSI is used to determine if the frequency of interest is busy. Timeout is used to interrupt the listening process, returning a value of `busy` to the parent (calling) function. Parameters ---------- freq : float Operating (center) frequency of interest. rssi_threshold : int, optional RSSI threshold for determining whether channel is clear. Default value is 100. This value is not a power value; for relationship between RSSI and power, see [RFM22]. timeout : float, optional Timeout value in seconds. DEBUG : bool, optional Flag to turn on debug message printing. Returns ------- out : str Frequency (channel) status, either `clear` or `busy`. References ---------- .. [RFM22] Figure 31, pg 64, RFM22 Data sheet. """ self.rfm22.set_op_mode('ready') self.rfm22.disable_interrupts() self.rfm22.clear_interrupts() self.rfm22.clear_rx_fifo() self.rfm22.set_frequency(freq) self._tx_rx_switch('rx') self.rfm22.set_op_mode('rx') time.sleep(0.01) # need a bit of time before we read rssi values rssi_level = float('{0:d}'.format(spi.read(0x26))) while (rssi_level >= 100): b = self.backoff.run() if (b == "continue"): rssi_level = float('{0:d}'.format(spi.read(0x26))) continue else: # (b == "break") self._tx_rx_switch('off') return 'busy' self._tx_rx_switch('off') return 'clear'
def check_rssi(self): self.tx_ant.write(0) self.rx_ant.write(1) self.clear_interrupt() self.clear_fifo() # self.set_rfm22_state('rx') self.enable_interrupt('valid_packet_received') print "RSSI Threshold: ", '{0:d}'.format(spi.read(0x27)) print "RSSI Indicator: ", '{0:d}'.format(spi.read(0x26))
def clear_interrupts(self): """ Clear interrupts. This function clears the interrupts by reading registers 0x03 Interrupt/Status 1 and 0x02 Interrupt Status 2. """ i = spi.read(0x03) i = spi.read(0x04)
def tx_data(self): spi.write(0x07, 0x01) s = "echo 0 > /sys/class/gpio/gpio" + str(self.rx_port) + "/value" result = subprocess.call(s, shell=True) s = "echo 1 > /sys/class/gpio/gpio" + str(self.tx_port) + "/value" result = subprocess.call(s, shell=True) time.sleep(0.05) spi.write(0x08, 0x03) spi.write(0x08, 0x00) spi.write(0x34, 64) # preamble = 64nibble spi.write(0x3E, 17) # packet length = 17bytes tx_buf =[0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x78] for i in tx_buf: spi.write(0x7F, i) # send payload to the FIFO spi.write(0x05, 0x04) # enable packet sent interrupt i = spi.read(0x03) # Read Interrupt status1 register i = spi.read(0x04) spi.write(0x07, 0x09) # Start TX s = "cat /sys/class/gpio/gpio" + str(int_port) + "/value" result = subprocess.check_output(s, shell=True) while ( int(result) == 1 ): print "int_port == 1" result = subprocess.check_output(s, shell=True) if ( int(result) == 0 ): print "int_port == 0" print "Register 0x03: ", '{0:08b}'.format(spi.read(0x03)) print "Register 0x04: ", '{0:08b}'.format(spi.read(0x04)) spi.write(0x07, 0x01) s = "echo 0 > /sys/class/gpio/gpio" + str(self.rx_port) + "/value" result = subprocess.call(s, shell=True) s = "echo 0 > /sys/class/gpio/gpio" + str(self.tx_port) + "/value" result = subprocess.call(s, shell=True)
def enable_interrupt(self, signal): """ Enable interrupt signals. This function enables interrupt signals in registers 0x05 Interrupt Enable 1 and 0x06 Interrupt Enable 2. TODO: There has to be a better way to enable multiple interrupts then calling this function over and over. Parameters ---------- signal : str Interrupt signal to be enabled. Available signals are: - """ r1 = spi.read(0x05) r2 = spi.read(0x06) if signal == 'crc_error': self._set_reg_interrupt_enable_1(r1 | 0x01) elif signal == 'valid_packet_received': self._set_reg_interrupt_enable_1(r1 | 0x02) elif signal == 'packet_sent': self._set_reg_interrupt_enable_1(r1 | 0x04) elif signal == 'external_interrupt': self._set_reg_interrupt_enable_1(r1 | 0x08) elif signal == 'rx_fifo_almost_full': self._set_reg_interrupt_enable_1(r1 | 0x10) elif signal == 'tx_fifo_almost_empty': self._set_reg_interrupt_enable_1(r1 | 0x20) elif signal == 'tx_fifo_almost_full': self._set_reg_interrupt_enable_1(r1 | 0x40) elif signal == 'fifo_underflow_overflow': self._set_reg_interrupt_enable_1(r1 | 0x80) elif signal == 'power_on_reset': self._set_reg_interrupt_enable_2(r2 | 0x01) elif signal == 'module_ready_xtal': self._set_reg_interrupt_enable_2(r2 | 0x02) elif signal == 'low_battery_detect': self._set_reg_interrupt_enable_2(r2 | 0x04) elif signal == 'wake_up_timer': self._set_reg_interrupt_enable_2(r2 | 0x08) elif signal == 'rssi': self._set_reg_interrupt_enable_2(r2 | 0x10) elif signal == 'invalid_preamble_detected': self._set_reg_interrupt_enable_2(r2 | 0x20) elif signal == 'valid_preamble_detected': self._set_reg_interrupt_enable_2(r2 | 0x40) elif signal == 'sync_word_detected': self._set_reg_interrupt_enable_2(r2 | 0x80) else: # TODO: add error/exception handling print "+++ Melon melon melon +++"
def run(self): self.setup_rf() ack = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] self.tx_data() print "transmitted packet" time.sleep(0.1) self.rx_mode() print "Register 0x02: ", '{0:08b}'.format(spi.read(0x02)) print "Register 0x03: ", '{0:08b}'.format(spi.read(0x03)) print "Register 0x04: ", '{0:08b}'.format(spi.read(0x04)) print "receiving packet..." while True: s = "cat /sys/class/gpio/gpio" + str(int_port) + "/value" result = subprocess.check_output(s, shell=True) print "Register 0x02: ", '{0:08b}'.format(spi.read(0x02)) print "Register 0x03: ", '{0:08b}'.format(spi.read(0x03)) print "Register 0x04: ", '{0:08b}'.format(spi.read(0x04)) print "interrupt: ", int(result) if ( int(result) == 0 ): rx_buffer = [] for i in range(17): rx_buffer.append(spi.read(0x7F)) if ( rx_buffer == ack ): print "ACK Received" print "Sending ACK" break spi.write(0x07, 0x01) self.rx_reset() reg = spi.read(0x02) if ( reg & 1 == 0 ): print "" print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" print "not in rx state !!!!" print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" print "" self.rx_reset() time.sleep(0.05)
def set_modulation(self, modulation): """ Set modulation. This function sets the modtyp[1:0] bits in registers 0x71 determining the modulation. Parameters ---------- modulation : str Modulation type, one of {'unmodulated' | 'ook' | 'fsk' | 'gfsk'}. Raises ------ ValueError If `modulation` is not one of {'unmodulated' | 'ook' | 'fsk' | 'gfsk'}. """ if modulation not in ['unmodulated', 'ook', 'fsk', 'gfsk']: print "modulation must be one of {'unmodulated' | 'ook' | 'fsk' | 'gfsk'}." raise ValueError else: if modulation == 'unmodulated': mod = 0x00 elif modulation == 'ook': mod = 0x01 elif modulation == 'fsk': mod = 0x02 else: # modulation == 'gfsk' mod = 0x03 val = spi.read(0x71) & 0xFC # clear last two bits self._set_reg_modulation_mode_1(val | mod) # set last two bits
def rx_reset(self): spi.write(0x07, 0x01) # Ready Mode # Read Int_Port Registers to reset i = spi.read(0x03) # IntStatReg1 i = spi.read(0x04) # IntStatReg2 # Set RX FIFO Almost Full level: 17 bytes spi.write(0x7E, 17) # Clear TX. RX FIFO Buffers spi.write(0x08, 0x03) spi.write(0x08, 0x00) spi.write(0x07, 0x05) spi.write(0x05, 0x02)
def get_rssi_raw(self): """ Get the raw RSSI reading. Returns ------- out : float RSSI value read directly from RFIC """ self.rfm22.set_op_mode('ready') self.rfm22.disable_interrupts() self.rfm22.clear_interrupts() self.rfm22.clear_rx_fifo() self._tx_rx_switch('rx') self.rfm22.set_op_mode('rx') time.sleep(0.01) # need a bit of time before we read rssi values return float('{0:d}'.format(spi.read(0x26)))
def rx_reset(self): spi.write(0x07, 0x01) # Ready Mode # Read Interrupt Registers to reset i = spi.read(0x03) # IntStatReg1 i = spi.read(0x04) # IntStatReg2 # Set RX FIFO Almost Full level: 17 bytes spi.write(0x7E, 17) # Clear TX. RX FIFO Buffers spi.write(0x08, 0x03) spi.write(0x08, 0x00) spi.write(0x07, 0x05) spi.write(0x05, 0x02)
def set_data_rate(self, rate): """ Set the data rate. This function sets the values in registers 0x6E and 0x6F, and bit txdtrtscale in register 0x70, determining the data rate. Parameters ---------- rate : float Data rate, in kbps, 1e3 <= rate <= 128e3 Raises ------ ValueError If not kbps, 1e3 <= rate <= 128e3 """ if rate < 1e3 or rate > 128e3: print "\nError: rate %f out of range" % (rate, ) print "1e3 <= rate <= 128e3" raise ValueError txdr1, txdr0, txdtrtscale = rf_utils.data_rate(rate) self._set_reg_tx_rate_1(txdr1) self._set_reg_tx_rate_0(txdr0) val = spi.read(0x70) self._set_reg_modulation_mode_1(val | 0x20)
def _receive(self, freq): time_out = Timer(2.0) ack = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] self.rfm22.set_frequency(freq) self.rfm22.disable_interrupts() self.rfm22.set_op_mode('ready') self.tx_ant.write(0) self.rx_ant.write(1) self.rfm22.clear_rx_fifo() self.rfm22.clear_interrupts() self.rfm22.set_rx_fifo_almost_full_threshold(17) self.rfm22.enable_interrupt('valid_packet_received') self.rfm22.set_op_mode('rx') print "waiting for ACK..." r = self.irq.read() time_out.start() while (int(r) == 1): if time_out.timer_event.isSet(): time_out.join() del(time_out) print "Time out exceeded" return else: r = self.irq.read() rx_buffer = [] for i in range(17): rx_buffer.append(spi.read(0x7F)) if (rx_buffer == ack): print "ACK Received"
def set_data_rate(self, rate): """ Set the data rate. This function sets the values in registers 0x6E and 0x6F, and bit txdtrtscale in register 0x70, determining the data rate. Parameters ---------- rate : float Data rate, in kbps, 1e3 <= rate <= 128e3 Raises ------ ValueError If not kbps, 1e3 <= rate <= 128e3 """ if rate < 1e3 or rate > 128e3: print "\nError: rate %f out of range" %(rate,) print "1e3 <= rate <= 128e3" raise ValueError txdr1, txdr0, txdtrtscale = rf_utils.data_rate(rate) self._set_reg_tx_rate_1(txdr1) self._set_reg_tx_rate_0(txdr0) val = spi.read(0x70) self._set_reg_modulation_mode_1(val | 0x20)
def _receive(self, freq): time_out = Timer(2.0) ack = [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ] self.rfm22.set_frequency(freq) self.rfm22.disable_interrupts() self.rfm22.set_op_mode('ready') self.tx_ant.write(0) self.rx_ant.write(1) self.rfm22.clear_rx_fifo() self.rfm22.clear_interrupts() self.rfm22.set_rx_fifo_almost_full_threshold(17) self.rfm22.enable_interrupt('valid_packet_received') self.rfm22.set_op_mode('rx') print "waiting for ACK..." r = self.irq.read() time_out.start() while (int(r) == 1): if time_out.timer_event.isSet(): time_out.join() del (time_out) print "Time out exceeded" return else: r = self.irq.read() rx_buffer = [] for i in range(17): rx_buffer.append(spi.read(0x7F)) if (rx_buffer == ack): print "ACK Received"
def module_power_state(self): status = spi.read(0x02) power_state = status & 0x03 if power_state == 0x00: return 'idle' elif power_state == 0x01: return 'rx' elif power_state == 0x02: return 'tx' else: print "error in module_power_state"
def run(self): tx_buf =[0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x78] self.setup_rf() self.rx_mode() print "Register 0x02: ", '{0:08b}'.format(spi.read(0x02)) print "Register 0x03: ", '{0:08b}'.format(spi.read(0x03)) print "Register 0x04: ", '{0:08b}'.format(spi.read(0x04)) print "receiving packet..." while True: s = "cat /sys/class/gpio/gpio" + str(interrupt) + "/value" result = subprocess.check_output(s, shell=True) print "Register 0x02: ", '{0:08b}'.format(spi.read(0x02)) print "Register 0x03: ", '{0:08b}'.format(spi.read(0x03)) print "Register 0x04: ", '{0:08b}'.format(spi.read(0x04)) print "interrupt: ", int(result) if ( int(result) == 0 ): rx_buffer = [] for i in range(17): rx_buffer.append(spi.read(0x7F)) if ( rx_buffer == tx_buf ): print "Packet Received" time.sleep(1) print "Sending ACK" self.tx_data() break spi.write(0x07, 0x01) self.rx_reset() reg = spi.read(0x02) if ( reg & 1 == 0 ): print "" print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" print "not in rx state !!!!" print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" print "" self.rx_reset() time.sleep(0.05)
def _listen(self, freq): self.rfm22.set_frequency(freq) self.rfm22.disable_interrupts() self.rfm22.set_op_mode('ready') self.tx_ant.write(0) self.rx_ant.write(1) self.rfm22.clear_rx_fifo() self.rfm22.clear_interrupts() self.rfm22.set_op_mode('rx') time.sleep(0.01) # need a bit of time before we read rssi values rssi_level = float('{0:d}'.format(spi.read(0x26))) while (rssi_level >= 100): b = self.back_off.run() if (b == "continue"): continue else: # (b == "break") keep_looping = False break
def read_rx_fifo(self): return spi.read(0x7F)
def clear_interrupt(self): i = spi.read(0x03) i = spi.read(0x04)
def receive(self, freq, rx_fifo_threshold=17, timeout=None, DEBUG=True): """ Receive data. This function receives data and does more stuff. TODO: Add more here. If `timeout` is none, then there is no time limit on how long to wait to receive a packet. Parameters ---------- freq : float Operating (center) frequency of interest. rx_fifo_threshold : int, optional Value for RX Almost Full threshold. When the incoming RX data reaches the Almost Full Threshold an interrupt will be generated to the microcontroller via the nIRQ pin. The microcontroller will then need to read the data from the RX FIFO. timeout : float, optional Timeout value in seconds. Default value is 120. DEBUG : bool, optional Flag to turn on debug message printing. Returns ------- rx_buffer : list Received data, from RX FIFO buffer. """ self.rfm22.set_op_mode('ready') self.rfm22.disable_interrupts() self.rfm22.clear_interrupts() self.rfm22.clear_rx_fifo() self.rfm22.set_frequency(freq) self.rfm22.set_rx_fifo_almost_full_threshold(rx_fifo_threshold) self._tx_rx_switch('rx') self.rfm22.enable_interrupt('valid_packet_received') self.rfm22.set_op_mode('rx') if timeout == None: if DEBUG: print "waiting for packet..." r = self.irq.read() while (int(r) == 1): # interrupt is driven low when packet arrives r = self.irq.read() rx_buffer = [] for i in range(rx_fifo_threshold): rx_buffer.append(spi.read(0x7F)) return rx_buffer else: timer=Timer(timeout) timer.start() if DEBUG: print "waiting for packet..." r = self.irq.read() while (int(r) == 1): # interrupt is driven low when packet arrives if timer.flag.isSet(): timer.join() del(timer) if DEBUG: print "Time out exceeded" return [] else: r = self.irq.read() # timer.join() # this doesn't seem necessary, and it takes # a long time to execute BigO(1 sec) # del(timer) rx_buffer = [] for i in range(rx_fifo_threshold): rx_buffer.append(spi.read(0x7F)) return rx_buffer
def receive(self, freq, rx_fifo_threshold=17, timeout=None, DEBUG=True): """ Receive data. This function receives data and does more stuff. TODO: Add more here. If `timeout` is none, then there is no time limit on how long to wait to receive a packet. Parameters ---------- freq : float Operating (center) frequency of interest. rx_fifo_threshold : int, optional Value for RX Almost Full threshold. When the incoming RX data reaches the Almost Full Threshold an interrupt will be generated to the microcontroller via the nIRQ pin. The microcontroller will then need to read the data from the RX FIFO. timeout : float, optional Timeout value in seconds. Default value is 120. DEBUG : bool, optional Flag to turn on debug message printing. Returns ------- rx_buffer : list Received data, from RX FIFO buffer. """ self.rfm22.set_op_mode('ready') self.rfm22.disable_interrupts() self.rfm22.clear_interrupts() self.rfm22.clear_rx_fifo() self.rfm22.set_frequency(freq) self.rfm22.set_rx_fifo_almost_full_threshold(rx_fifo_threshold) self._tx_rx_switch('rx') self.rfm22.enable_interrupt('valid_packet_received') self.rfm22.set_op_mode('rx') if timeout == None: if DEBUG: print "waiting for packet..." r = self.irq.read() while (int(r) == 1): # interrupt is driven low when packet arrives r = self.irq.read() rx_buffer = [] for i in range(rx_fifo_threshold): rx_buffer.append(spi.read(0x7F)) return rx_buffer else: timer = Timer(timeout) timer.start() if DEBUG: print "waiting for packet..." r = self.irq.read() while (int(r) == 1): # interrupt is driven low when packet arrives if timer.flag.isSet(): timer.join() del (timer) if DEBUG: print "Time out exceeded" return [] else: r = self.irq.read() # timer.join() # this doesn't seem necessary, and it takes # a long time to execute BigO(1 sec) # del(timer) rx_buffer = [] for i in range(rx_fifo_threshold): rx_buffer.append(spi.read(0x7F)) return rx_buffer