github.com/embeddedgo/x@v0.0.6-0.20191217015414-d79a36f562e7/radio/nrf24/registers.go (about)

     1  // Copyright 2019 Michal Derkacz. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package nrf24
     6  
     7  /*func fflags(fs fmt.State, format string, mask, b byte) {
     8  	m := byte(0x80)
     9  	k := 0
    10  	for i := 0; i < len(format); i++ {
    11  		c := format[i]
    12  		if c == '+' {
    13  			for mask&m == 0 {
    14  				m >>= 1
    15  			}
    16  			if b&m == 0 {
    17  				io.WriteString(fs, format[k:i])
    18  				fs.Write([]byte{'-'})
    19  			} else {
    20  				io.WriteString(fs, format[k:i+1])
    21  			}
    22  			m >>= 1
    23  			k = i + 1
    24  		}
    25  	}
    26  	if k < len(format) {
    27  		io.WriteString(fs, format[k:])
    28  	}
    29  }*/
    30  
    31  func (r *Radio) byteReg(addr byte) (byte, STATUS) {
    32  	var buf [1]byte
    33  	s := r.R_REGISTER(addr, buf[:])
    34  	return buf[0], s
    35  }
    36  
    37  type CONFIG byte
    38  
    39  const (
    40  	PRIM_RX     CONFIG = 1 << 0 // 1: Receiver (PRX) / 0: Transmitter (PPTX).
    41  	PWR_UP      CONFIG = 1 << 1 // Power: 1: up / 0: down.
    42  	CRCO        CONFIG = 1 << 2 // CRC encoding scheme: 0: one byte / 1: two bytes.
    43  	EN_CRC      CONFIG = 1 << 3 // Enable CRC. Forced 1 if one of bits in EN_AA is 1.
    44  	MASK_MAX_RT CONFIG = 1 << 4 // MAX_RT: 1: does not assert / 0: asserts IRQ.
    45  	MASK_TX_DS  CONFIG = 1 << 5 // TX_DS: 1: does not assert, 0: asserts IRQ.
    46  	MASK_RX_DR  CONFIG = 1 << 6 // RX_DR: 1: does not assert, 0: asserts IRQ.
    47  )
    48  
    49  /*func (c CONFIG) Format(fs fmt.State, _ rune) {
    50  	fflags(
    51  		fs, "MASK(RX_DR+ TX_DS+ MAX_RT+) EN_CRC+ CRCO+ PWR_UP+ PRIM_RX+",
    52  		0x7f, byte(c),
    53  	)
    54  }*/
    55  
    56  // CONFIG returns the value of the Configuration Register.
    57  func (r *Radio) CONFIG() (CONFIG, STATUS) {
    58  	b, s := r.byteReg(0)
    59  	return CONFIG(b), s
    60  }
    61  
    62  // Set_CONFIG sets the value of the Configuration Register.
    63  func (r *Radio) Set_CONFIG(c CONFIG) STATUS {
    64  	return r.W_REGISTER(0, byte(c))
    65  }
    66  
    67  // Pipes is a bitfield that represents the nRF24L01+ Rx data pipes.
    68  type Pipes byte
    69  
    70  const (
    71  	P0    Pipes = 1 << 0
    72  	P1    Pipes = 1 << 1
    73  	P2    Pipes = 1 << 2
    74  	P3    Pipes = 1 << 3
    75  	P4    Pipes = 1 << 4
    76  	P5    Pipes = 1 << 5
    77  	P_ALL       = P0 | P1 | P2 | P3 | P4 | P5
    78  )
    79  
    80  /*func (p Pipes) Format(fs fmt.State, _ rune) {
    81  	fflags(fs, "P5+ P4+ P3+ P2+ P1+ P0+", 0x3f, byte(p))
    82  }*/
    83  
    84  // EN_AA returns the value of the Enable ‘Auto Acknowledgment’ Function
    85  // register.
    86  func (r *Radio) EN_AA() (Pipes, STATUS) {
    87  	b, s := r.byteReg(1)
    88  	return Pipes(b), s
    89  }
    90  
    91  // Set_EN_AA sets the value of the Enable ‘Auto Acknowledgment’ Function
    92  // register.
    93  func (r *Radio) Set_EN_AA(p Pipes) STATUS {
    94  	return r.W_REGISTER(1, byte(p))
    95  }
    96  
    97  // EN_RXADDR returns the value of the Enabled RX Addresses register.
    98  func (r *Radio) EN_RXADDR() (Pipes, STATUS) {
    99  	b, s := r.byteReg(2)
   100  	return Pipes(b), s
   101  }
   102  
   103  // Set_EN_RXADDR sets the value of the Enabled RX Addresses) register.
   104  func (r *Radio) Set_EN_RXADDR(p Pipes) STATUS {
   105  	return r.W_REGISTER(2, byte(p))
   106  }
   107  
   108  // SETUP_AW returns the value of the Setup of Address Widths register increased
   109  // by two, that is it returns the address length in bytes.
   110  func (r *Radio) SETUP_AW() (int, STATUS) {
   111  	b, s := r.byteReg(3)
   112  	return int(b) + 2, s
   113  }
   114  
   115  // Set_SETUP_AW sets the value of the Setup of Address Widths register to
   116  // (aw-2), that is it sets the address length to aw bytes (allowed values:
   117  // 3, 4, 5).
   118  func (r *Radio) Set_SETUP_AW(alen int) STATUS {
   119  	if alen < 3 || alen > 5 {
   120  		panic("alen<3 || alen>5")
   121  	}
   122  	return r.W_REGISTER(3, byte(alen-2))
   123  }
   124  
   125  // SETUP_RETR returns the value of the Setup of Automatic Retransmission
   126  // register converted to number of retries and delay (µs) between retries.
   127  func (r *Radio) SETUP_RETR() (cnt, dlyus int, s STATUS) {
   128  	b, s := r.byteReg(4)
   129  	cnt = int(b & 0xf)
   130  	dlyus = (int(b>>4) + 1) * 250
   131  	return cnt, dlyus, s
   132  }
   133  
   134  // Set_SETUP_RETR sets the value of the Setup of Automatic Retransmission
   135  // register using cnt as number of retries and dlyus as delay between retries.
   136  func (r *Radio) Set_SETUP_RETR(cnt, dlyus int) STATUS {
   137  	if uint(cnt) > 15 {
   138  		panic("cnt<0 || cnt>15")
   139  	}
   140  	if dlyus < 250 || dlyus > 4000 {
   141  		panic("dlyus<250 || dlyus>4000")
   142  	}
   143  	return r.W_REGISTER(4, byte(((dlyus+125)/250-1)<<4|cnt))
   144  }
   145  
   146  // RF_CH returns the value of the RF Channel register.
   147  func (r *Radio) RF_CH() (int, STATUS) {
   148  	b, s := r.byteReg(5)
   149  	return int(b), s
   150  }
   151  
   152  // Set_RF_CH sets value of RF Channel register.
   153  func (r *Radio) Set_RF_CH(ch int) STATUS {
   154  	if uint(ch) > 127 {
   155  		panic("ch<0 || ch>127")
   156  	}
   157  	return r.W_REGISTER(5, byte(ch))
   158  }
   159  
   160  type RF_SETUP byte
   161  
   162  const (
   163  	LNA_HCURR  RF_SETUP = 1 << 0 // LNA gain 0: -1.5 dB, -0.8 mA (nRF24L01 specific).
   164  	RF_DR_HIGH RF_SETUP = 1 << 3 // High speed data rate 0: 1Mbps, 1: 2Mbps.
   165  	PLL_LOCK   RF_SETUP = 1 << 4 // Force PLL lock signal. Only used in test.
   166  	RF_DR_LOW  RF_SETUP = 1 << 5 // Set RF Data Rate to 250kbps.
   167  	CONT_WAVE  RF_SETUP = 1 << 7 // Enable continuous carrier transmit.
   168  )
   169  
   170  // RF_PWR returns RF output power in Tx mode [dBm].
   171  func (rf RF_SETUP) RF_PWR() int {
   172  	return 3*int(rf&6) - 18
   173  }
   174  
   175  func RF_PWR(dbm int) RF_SETUP {
   176  	switch {
   177  	case dbm < -18:
   178  		dbm = -18
   179  	case dbm > 0:
   180  		dbm = 0
   181  	}
   182  	return RF_SETUP((18+dbm)/3) & 6
   183  }
   184  
   185  /*func (rf RF_SETUP) Format(fs fmt.State, _ rune) {
   186  	fflags(
   187  		fs, "CONT_WAVE+ RF_DR_LOW+ PLL_LOCK+ RF_DR_HIGH+ LNA_HCURR+ RF_PWR:",
   188  		0xb9, byte(rf),
   189  	)
   190  	strconv.WriteInt(fs, rf.RF_PWR(), 10, 0, ' ')
   191  	io.WriteString(fs, " dBm")
   192  }*/
   193  
   194  // RF_SETUP returns the value of the RF Setup register.
   195  func (r *Radio) RF_SETUP() (RF_SETUP, STATUS) {
   196  	b, s := r.byteReg(6)
   197  	return RF_SETUP(b), s
   198  }
   199  
   200  // Set_RF_SETUP sets the value of the RF Setup register.
   201  func (r *Radio) Set_RF_SETUP(rf RF_SETUP) STATUS {
   202  	return r.W_REGISTER(6, byte(rf))
   203  }
   204  
   205  type STATUS byte
   206  
   207  const (
   208  	FULL_TX STATUS = 1 << 0 // Tx FIFO full flag.
   209  	MAX_RT  STATUS = 1 << 4 // Maximum number of Tx retransmits interrupt.
   210  	TX_DS   STATUS = 1 << 5 // Data Sent Tx FIFO interrupt.
   211  	RX_DR   STATUS = 1 << 6 // Data Ready Rx FIFO interrupt.
   212  )
   213  
   214  // RX_P_NO returns the data pipe number for the payload available for reading
   215  // from Rx FIFO or -1 if Tx FIFO is empty.
   216  func (s STATUS) RX_P_NO() int {
   217  	n := int(s) & 0x0e
   218  	if n == 0x0e {
   219  		return -1
   220  	}
   221  	return n >> 1
   222  }
   223  
   224  /*func (s STATUS) Format(fs fmt.State, _ rune) {
   225  	fflags(fs, "RX_DR+ TX_DS+ MAX_RT+ FULL_TX+ RX_P_NO:", 0x71, byte(s))
   226  	strconv.WriteInt(fs, s.RX_P_NO(), 10, 0, ' ')
   227  }*/
   228  
   229  // ClearIRQ allow to clear the interrupt bits of the Status register.
   230  func (r *Radio) ClearIRQ(s STATUS) STATUS {
   231  	mask := RX_DR | TX_DS | MAX_RT
   232  	return r.W_REGISTER(7, byte(s&mask))
   233  }
   234  
   235  // OBSERVE_TX returns the values of PLOS_CNT and ARC_CNT counters from the
   236  // Transmit observe register.
   237  func (r *Radio) OBSERVE_TX() (plos, arc int, s STATUS) {
   238  	b, s := r.byteReg(8)
   239  	arc = int(b & 0xf)
   240  	plos = int(b >> 4)
   241  	return plos, arc, s
   242  }
   243  
   244  // RPD returns the value of the Received Power Detector register: true if
   245  // RP > -64dBm, false otherwise. In case of nRF24L01 it returns the value of
   246  // the CD (Carrier Detect) register.
   247  func (r *Radio) RPD() (bool, STATUS) {
   248  	b, s := r.byteReg(9)
   249  	return b&1 != 0, s
   250  }
   251  
   252  func checkPayNum(pn int) {
   253  	if uint(pn) > 5 {
   254  		panic("pn<0 || pn>5")
   255  	}
   256  }
   257  
   258  func checkAddr(addr []byte) {
   259  	if len(addr) > 5 {
   260  		panic("len(addr)>5")
   261  	}
   262  }
   263  
   264  func checkPayNumAddr(pn int, addr []byte) {
   265  	checkPayNum(pn)
   266  	checkAddr(addr)
   267  	if pn > 1 && len(addr) > 1 {
   268  		panic("pn>1 && len(addr)>1")
   269  	}
   270  }
   271  
   272  // Read_RX_ADDR reads the receive address of the data pipe pn.
   273  func (r *Radio) Read_RX_ADDR(pn int, addr []byte) STATUS {
   274  	checkPayNumAddr(pn, addr)
   275  	return r.R_REGISTER(byte(0xa+pn), addr)
   276  }
   277  
   278  // Write_RX_ADDR sets the receive address of the data pipe pn.
   279  func (r *Radio) Write_RX_ADDR(pn int, addr ...byte) STATUS {
   280  	checkPayNumAddr(pn, addr)
   281  	return r.W_REGISTER(byte(0xa+pn), addr...)
   282  }
   283  
   284  // Read_TX_ADDR reads value of Transmit address register into addr.
   285  func (r *Radio) Read_TX_ADDR(addr []byte) STATUS {
   286  	checkAddr(addr)
   287  	return r.R_REGISTER(0x10, addr)
   288  }
   289  
   290  // Write_TX_ADDR sets value of Transmit address.
   291  func (r *Radio) Write_TX_ADDR(addr ...byte) STATUS {
   292  	checkAddr(addr)
   293  	return r.W_REGISTER(0x10, addr...)
   294  }
   295  
   296  // RX_PW returns the Rx payload width for pipe pn.
   297  func (r *Radio) RX_PW(pn int) (int, STATUS) {
   298  	checkPayNum(pn)
   299  	b, s := r.byteReg(byte(0x11 + pn))
   300  	return int(b) & 0x3f, s
   301  }
   302  
   303  // Set_RX_PW sets the Rx payload width for pipe pn.
   304  func (r *Radio) Set_RX_PW(pn, pw int) STATUS {
   305  	checkPayNum(pn)
   306  	if uint(pw) > 32 {
   307  		panic("pw<0 || pw>32")
   308  	}
   309  	return r.W_REGISTER(byte(0x11+pn), byte(pw))
   310  }
   311  
   312  type FIFO_STATUS byte
   313  
   314  const (
   315  	RX_EMPTY FIFO_STATUS = 1 << 0 // 1: Rx FIFO empty, 0: Data in Rx FIFO.
   316  	RX_FULL  FIFO_STATUS = 1 << 1 // 1: Rx FIFO full, 0: Available locations in Rx FIFO.
   317  	TX_EMPTY FIFO_STATUS = 1 << 4 // 1: Tx FIFO empty, 0: Data in Tx FIFO.
   318  	TX_FULL  FIFO_STATUS = 1 << 5 // 1: Tx FIFO full, 0: Available locations in Tx FIFO.
   319  	TX_REUSE FIFO_STATUS = 1 << 6 // Set by TX_REUSE, cleared by W_TX_PAYLOAD, FLUSH_TX.
   320  )
   321  
   322  /*func (f FIFO_STATUS) Format(fs fmt.State, _ rune) {
   323  	fflags(fs, "TX_REUSE+ TX_FULL+ TX_EMPTY+ RX_FULL+ RX_EMPTY+", 0x73, byte(f))
   324  }*/
   325  
   326  // FIFO_STATUS returns value of FIFO Status Register.
   327  func (r *Radio) FIFO_STATUS() (FIFO_STATUS, STATUS) {
   328  	b, s := r.byteReg(0x17)
   329  	return FIFO_STATUS(b), s
   330  }
   331  
   332  // DYNPD returns the value of Enable dynamic payload length register.
   333  func (r *Radio) DYNPD() (Pipes, STATUS) {
   334  	b, s := r.byteReg(0x1c)
   335  	return Pipes(b), s
   336  }
   337  
   338  // Set_DYNPD sets the value of Enable dynamic payload length register.
   339  func (r *Radio) Set_DYNPD(p Pipes) STATUS {
   340  	return r.W_REGISTER(0x1c, byte(p))
   341  }
   342  
   343  type FEATURE byte
   344  
   345  const (
   346  	EN_DYN_ACK FEATURE = 1 << 0 // 1: Enables the W_TX_PAYLOAD_NOACK command.
   347  	EN_ACK_PAY FEATURE = 1 << 1 // 1: Enables payload with ACK
   348  	EN_DPL     FEATURE = 1 << 2 // 1: Enables dynamic payload length
   349  )
   350  
   351  /*func (f FEATURE) Format(fs fmt.State, _ rune) {
   352  	fflags(fs, "EN_DPL+ EN_ACK_PAY+ EN_DYN_ACK+", 7, byte(f))
   353  }*/
   354  
   355  // FEATURE returns value of Feature Register.
   356  func (r *Radio) FEATURE() (FEATURE, STATUS) {
   357  	b, s := r.byteReg(0x1d)
   358  	return FEATURE(b), s
   359  }
   360  
   361  // Set_FEATURE sets value of FEATURE register.
   362  func (r *Radio) Set_FEATURE(f FEATURE) STATUS {
   363  	return r.W_REGISTER(0x1d, byte(f))
   364  }