def read(self): ''' checks if received a transmission and returns it as a bytes object. returns None if no transmission was received ''' with self.radio_lock: #self.maintenanceHook() # doesn't work properly reg = self.doOperation(duplex([FIFO_STATUS, NOP]))[0] self.rf_status = reg[0] self.last_received_pipe = (self.rf_status & (1 << 4) - 1) >> 1 reg = reg[1] if reg & RX_EMPTY: return None reg = self.doOperation(duplex([R_RX_PL_WID, NOP]))[0][1] _bytes = [R_RX_PAYLOAD] for x in range(0, reg): _bytes.append(0x00) ret = self.doOperation(duplex(_bytes)) if self.irq_derivereason(self.rf_status) & IRQ_RX: self.irq_clear(IRQ_RX) return ret.pop()[1:]
def radioState(self): with self.radio_lock, self.CE_pin: reg = self.doOperation(duplex([CONFIG, NOP])) reg = reg[0][1] if not reg & PWR_UP: return 'ENRF24_STATE_DEEPSLEEP' #At this point it's either Standby-I, II or PRX. if reg & PRIM_RX: if self.CE_pin.value: return 'ENRF24_STATE_PRX' #PRIM_RX=1 but CE=0 is a form of idle state. return 'ENRF24_STATE_IDLE' #Check if TX queue is empty, if so it's idle, if not it's PTX. reg = self.doOperation(duplex([FIFO_STATUS, NOP])) print(reg) reg = ord(reg[0][1]) if (reg & TX_EMPTY): return 'ENRF24_STATE_IDLE' return 'ENRF24_STATE_PTX'
def enableRX(self): ''' enables receiver mode ''' with self.radio_lock, self.CE_pin: self.CE_pin.value = 0 reg = self.doOperation(duplex([FIFO_STATUS, NOP]))[0][1] _bytes = [WRITE_REG | CONFIG] _bytes.append(CFGMASK_IRQ | self.CFGMASK_CRC(reg) | PWR_UP | PRIM_RX) self.doOperation(writing(_bytes)) if not (reg & PWR_UP): # wait 5ms if PWR_UP was off time.sleep(0.005) self.CE_pin.value = 1
def maintenanceHook(self): ''' from spirilis's Enrf24 ''' lastirq = self.irq_getreason() if lastirq & IRQ_TXFAILED: self.lastTXfailed = True self.doOperation(writing([FLUSH_TX])) self.irq_clear(IRQ_TXFAILED) if lastirq & IRQ_TX: self.lastTXfailed = False self.irq_clear(IRQ_TX) if lastirq & IRQ_RX: reg = self.doOperation(duplex([FIFO_STATUS, NOP]))[0][1] if (reg & RX_FULL) == 0: self.irq_clear(IRQ_RX) reg = self.doOperation(duplex([R_RX_PL_WID, NOP]))[0] self.rf_status = reg[0] i = reg[1] if i == 0 or i > 32 or ((self.rf_status & 0x0E) >> 1) == 0: self.doOperation(writing([FLUSH_RX])) self.irq_clear(IRQ_RX)
def write(self, data): ''' transmits data and returns true or false whether it failed or not. data needs to be a bytes object ''' if not len(data): return True with self.radio_lock: self.CE_pin.open() is_receiving = False self.is_transmitting = True self.CE_pin.value = 0 reg = self.doOperation(duplex([CONFIG, NOP]))[0][1] if not (reg & PWR_UP): _bytes = [WRITE_REG | CONFIG] _bytes.append(CFGMASK_IRQ | self.CFGMASK_CRC(reg) | PWR_UP) self.doOperation(writing(_bytes)) time.sleep(0.005) if reg & PRIM_RX: is_receiving = True _bytes = [WRITE_REG | CONFIG] _bytes.append(CFGMASK_IRQ | self.CFGMASK_CRC(reg) | PWR_UP) self.doOperation(writing(_bytes)) _bytes = [WR_TX_PLOAD] _bytes.extend(data) self.doOperation(writing(_bytes)) self.CE_pin.value = 1 time.sleep(0.00003) self.CE_pin.value = 0 if not self.readLoopFlag: self.epoll = select.epoll() self.IRQ_pin.open() self.epoll.register(self.IRQ_pin, select.EPOLLIN | select.EPOLLET) events = self.epoll.poll() for fileno, event in events: if fileno == self.IRQ_pin.fileno(): self.maintenanceHook() if not self.readLoopFlag: self.IRQ_pin.close() self.CE_pin.value = 1 self.is_transmitting = False if is_receiving: self.CE_pin.close() self.radio_lock.release() self.enableRX() self.radio_lock.acquire() else: self.CE_pin.close() return self.lastTXfailed
def irq_getreason(self): return self.doOperation(duplex([STATUS, NOP]))[0][1] & IRQ_MASK