AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Nrf24 Bitbang Spi

skill-wang200935-security-agent-skills-nrf24-bitbang-spi · by Wang200935

Bit-bang SPI driver for nRF24L01+ on ESP32 with verified writes, ShockBurst

No reviews yet
0 installs
10 views
0.0% view→install

Install

$ agentstack add skill-wang200935-security-agent-skills-nrf24-bitbang-spi

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-wang200935-security-agent-skills-nrf24-bitbang-spi)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
20d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Nrf24 Bitbang Spi? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

nRF24L01+ Bit-Bang SPI Driver with Verified Writes & Auto-Repair

🎯 Trigger Conditions

  • nRF24 modules on breadboard with Dupont wires showing SPI corruption (STATUS 0x00/0xFF, register reads corrupted)
  • Hardware SPI works on healthy connections but fails on high-resistance contacts
  • Need continuous ShockBurst (max-length packet flood) for WiFi/Bluetooth interference
  • Long-running firmware needs periodic health checks and self-repair

📋 Problem Context

Hardware SPI on ESP32 uses ~10-50ns edge rates. On breadboard with Dupont wires, contact resistance creates RC filters that round edges, causing bit errors. Bit-banging with configurable µs delays provides clean edges that pass through high-R connections.

Proven thresholds (Radio C = high-R branch):

  • HW SPI 50kHz: dead (MISO stuck 0x00)
  • Bit-bang 2kHz (500µs): alive, 0/20 errors
  • Bit-bang 20kHz (50µs): alive, 0/20 errors but marginal
  • Bit-bang 40kHz (25µs): occasional errors
  • Bit-bang 100kHz (10µs): frequent errors
  • Stable: 150µs delay (~6.6 kHz) for high-R; 10µs for healthy branches

🏗️ Architecture

Class Interface

class SoftNRF {
public:
  SoftNRF(uint8_t cePin, uint8_t csnPin, uint16_t delayUs);
  
  static void busInit();           // Call ONCE at boot: SCK/MOSI outputs LOW, MISO input
  void beginPins();                // CE output LOW, CSN output HIGH
  bool isPresent();                // STATUS sanity: not 0x00 / not 0xFF = alive
  void configureTx();              // Power-up, TX, no CRC/ACK, 2Mbps, PA max
  void setChannel(uint8_t ch);     // Fast path (no verification)
  void setChannelChecked(uint8_t); // Verified write (for init)
  void carrierOn();                // CONT_WAVE + PLL_LOCK, CE HIGH
  void carrierOff();               // CE LOW, clear carrier bits
  void powerDown();                // Full power down
  
  // constCarrier mode — CONT_WAVE + REUSE_TX_PL = continuous carrier+payload flood
  // This is the ONLY working TX method for interference. See rf-jammer-multi-protocol-jammer/references/nrf24-tx-mode-truth.md
  void startConstCarrier();       // RF_SETUP=0x9F, load payload, REUSE_TX_PL
  void stopConstCarrier();        // powerDown + clear CONT_WAVE + FLUSH_TX
  void sendReuseTXPL();           // CE LOW → clear MAX_RT → transfer(0xE3) → CE HIGH
  void reloadP();                 // FLUSH_TX → W_TX_PAYLOAD_NOACK → sendReuseTXPL
  
  // Legacy ShockBurst mode — DO NOT USE for interference (fires 1 packet then stops)
  void startShockBurst();          // [DEPRECATED] Single-packet TX, not continuous
  void repairShockBurstConfig();   // [DEPRECATED] Use reloadP() with constCarrier instead
  
  uint8_t readReg(uint8_t reg);    // Verification helper

private:
  uint8_t transfer(uint8_t out);
  void writeReg(uint8_t reg, uint8_t val);
  bool writeRegChecked(uint8_t reg, uint8_t val);  // Write + read-back verify (4 retries)
  
  uint8_t _ce, _csn;
  uint16_t _d;  // per-bit delay in microseconds
};

⚡ Critical Implementation Patterns

1. Bus Initialization (Single Call)

void SoftNRF::busInit() {
  pinMode(18, OUTPUT); digitalWrite(18, LOW);  // SCK
  pinMode(23, OUTPUT); digitalWrite(23, LOW);  // MOSI
  pinMode(19, INPUT);                          // MISO
}

2. Bit-Bang Transfer (Mode 0, MSB First)

uint8_t SoftNRF::transfer(uint8_t out) {
  uint8_t in = 0;
  for (int i = 0; i = 1.5ms
  // FLUSH_TX → W_TX_PAYLOAD_NOACK (0xB0) with 32 bytes 0xFF
  digitalWrite(_ce, HIGH);
  delay(1);
  // sendReuseTXPL(): CE LOW → STATUS clear → transfer(0xE3) → CE HIGH
}
// Expected RF_SETUP after start = 0x9F. FIFO shows TX_FULL=1, TX_EMPTY=0.
// If TX_EMPTY=1 → radio stopped. Call reloadP() to re-arm.

5. stopConstCarrier — Cannot Stop with CE LOW

Datasheet: CONTWAVE + REUSETX_PL together → CE LOW doesn't stop TX. Must powerDown:

void SoftNRF::stopConstCarrier() {
  powerDown();                         // PWR_UP=0 — only way to release
  writeRegChecked(RF_SETUP, 0x0F);     // clear CONT_WAVE + PLL_LOCK
  // FLUSH_TX
}

6. Periodic Health Check: reloadP()

void SoftNRF::reloadP() {
  // FLUSH_TX → W_TX_PAYLOAD_NOACK 32×0xFF → sendReuseTXPL()
}
// Runtime: every 5s, if RF_SETUP != 0x9F → call reloadP()

7. [DEPRECATED] startShockBurst — Single-Packet TX (DO NOT USE for interference)

void SoftNRF::startShockBurst() {
  writeRegChecked(EN_AA, 0x00);        // Auto-ack off
  writeRegChecked(SETUP_RETR, 0x00);   // No retries
  writeRegChecked(RF_SETUP, 0x0F);     // 2Mbps, PA max, LNA
  writeReg(STATUS, 0x70);              // Clear IRQ (not verifiable)
  writeRegChecked(CONFIG, 0x02);       // PWR_UP=1, PRIM_RX=0, CRC off
  delay(2);                            // Tpd2stby ≥ 1.5ms
  
  // TX address + payload width
  writeRegChecked(TX_ADDR, 0xE7);
  writeRegChecked(RX_ADDR_P0, 0xE7);
  writeRegChecked(RX_PW_P0, 32);
  
  // Fill TX FIFO with 32 bytes of 0xAA
  digitalWrite(_csn, LOW);
  delayMicroseconds(_d * 2);
  transfer(0xA0);  // W_TX_PAYLOAD
  for (int i = 0; i = 5000) {
  for (auto* r : {&RadioA, &RadioB, &RadioC}) {
    uint8_t rf = r->readReg(0x06);
    if (rf != 0x9F) {  // Expected: CONT_WAVE + PLL_LOCK + 2Mbps + PA max
      r->reloadP();   // FLUSH_TX → reload payload → re-arm REUSE_TX_PL
    }
  }
}

📡 TX Mode Comparison for 2.4GHz Interference

| Aspect | Pure CW (CONTWAVE only) | ShockBurst TX | constCarrier (CONTWAVE + REUSETXPL) | |--------|--------------------------|---------------|---------------------------------------------| | Signal | Single tone, no modulation | 32-byte packet, fire ONCE then stop | Continuous carrier modulated with payload data | | Duration | Continuous (until CE/PWR down) | Single packet (~10µs at 2Mbps) | Continuous (until powerDown) | | WiFi CCA Trigger | Energy detect only (often insufficient) | Brief, then gone | Energy detect + preamble correlation (persistent) | | BT/BLE Impact | Minimal — no preamble | Minimal — one packet | Effective — continuous modulated flood | | FIFO State | Empty (no payload) | Empty after 1 TX | TXFULL=1 (always has data via REUSETX_PL) | | How to Stop | CE LOW | CE LOW (auto-stops after packet) | powerDown() only (CE won't respond) |

Result: constCarrier is the ONLY working method. Verified empirically — see rf-jammer-multi-protocol-jammer/references/nrf24-tx-mode-truth.md for STATUS/FIFO observation data.

🔑 Key Register Map

| Register | Addr | ShockBurst Value | Purpose | |----------|------|------------------|---------| | CONFIG | 0x00 | 0x02 | PWRUP=1, PRIMRX=0, CRC off | | ENAA | 0x01 | 0x00 | Auto-ack disabled | | ENRXADDR | 0x02 | 0x01 | Pipe 0 only | | SETUPRETR | 0x04 | 0x00 | No retries | | RFCH | 0x05 | varies | Channel (0-125) | | RFSETUP | 0x06 | 0x0F | 2Mbps, PA max, LNA on | | STATUS | 0x07 | read-only | FIFO status, IRQ flags | | TXADDR | 0x10 | 0xE7... | TX address | | RXADDRP0 | 0x0A | 0xE7... | RX pipe 0 address | | RXPWP0 | 0x11 | 32 | Max payload | | DYNPD | 0x1C | 0x01 | Dynamic payload pipe 0 | | FEATURE | 0x1D | 0x01 | ENDYNACK |

📐 nRF24 Channel → Frequency Mapping

nRF24 channel N = 2400 + N MHz

| Protocol | Frequency | nRF24 Channel | |----------|-----------|---------------| | WiFi ch 1 | 2412 MHz | 12 | | WiFi ch 6 | 2437 MHz | 37 | | WiFi ch 11 | 2462 MHz | 62 | | BLE adv 37 | 2402 MHz | 2 | | BLE adv 38 | 2426 MHz | 26 | | BLE adv 39 | 2480 MHz | 80 | | BT Classic | 2402-2480 MHz | 2-80 |

🐛 Debugging Cheatsheet

| Symptom | Cause | Fix | |---------|-------|-----| | STATUS = 0x00 or 0xFF | SPI not communicating | Check wiring, power, CSN pin | | RFSETUP reads 0x62 not 0x0F | Write corruption during FIFO load | Use repair pass | | FEATURE reads 0x00 | ENDYN_ACK not set | Verify writeRegChecked in startShockBurst | | Works on boot, drifts later | No periodic health check | Add 5s verify + repair loop | | Radio C fails, A/B OK | High-R breadboard contact | Increase delayUs to 150µs |

🚀 Performance

  • Bit-bang rate: ~6.6 kHz (150µs delay) on high-R; ~100 kHz (10µs) on healthy
  • Channel hop: Single setChannel() = 1 register write = ~130µs PLL re-lock
  • ShockBurst throughput: Continuous 32-byte packets at 2Mbps
  • Memory: ~2KB flash, ~200 bytes RAM per radio instance

⚖️ Legal Notice

Taiwan Telecommunications Act Art 66/67: Manufacturing, possessing, or using 2.4GHz jammers is illegal (NCC confiscation + fines 100-700万; possession/use 3-30万). This driver is for authorized research in Faraday cage environments only.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.