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 }