Skip to content

Instantly share code, notes, and snippets.

@goebish
Last active October 11, 2018 16:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goebish/71fa5b6568e200438bf2090d50692480 to your computer and use it in GitHub Desktop.
Save goebish/71fa5b6568e200438bf2090d50692480 to your computer and use it in GitHub Desktop.
// dump rxid / address pairs out of the Bugs3 Mini stock TX
// https://i.imgur.com/i1ZzG9Z.jpg
#include <SPI.h>
#include "iface_nrf24l01.h"
// also require nRF24L01.ino, softSPI.ino and XN297_emu.ino
// from the nrf24-multipro project to be in the same folder
char buf [100];
volatile byte pos;
volatile boolean process_it;
// bug3smini stock tx xn297L spi
// use hardware spi
#define XN_CSN 10 // connect to D2 as well
#define XN_DAT 11
#define XN_CLK 13
// nrf24l01
//SPI Comm.pins with nRF24L01
// use software spi
#define MOSI_pin 3 // MOSI - D3
#define SCK_pin 4 // SCK - D4
#define CE_pin 5 // CE - D5
#define MISO_pin A0 // MISO - A0
#define CS_pin A1 // CS - A1
// SPI outputs
#define MOSI_on PORTD |= _BV(3) // PD3
#define MOSI_off PORTD &= ~_BV(3)// PD3
#define SCK_on PORTD |= _BV(4) // PD4
#define SCK_off PORTD &= ~_BV(4) // PD4
#define CE_on PORTD |= _BV(5) // PD5
#define CE_off PORTD &= ~_BV(5) // PD5
#define CS_on PORTC |= _BV(1) // PC1
#define CS_off PORTC &= ~_BV(1) // PC1
// SPI input
#define MISO_on (PINC & _BV(0)) // PC0
// MJX has disabled NRST pin in firmware in
// stock TX, so we use a n-mosfet connected to
// the battery pack to reset the mcu instead ...
// disconnect - (black) wire from battery pack
// gate -> D6
// drain -> transmitter - (black wire, not battery pack)
// source -> arduino gnd
// connect battery pack - to arduino gnd
// do not connect any other gnd between tx & arduino
#define TX_POWER_pin 6
// Function that printf and related will use to print
int serial_putchar(char c, FILE* f) {
if (c == '\n') serial_putchar('\r', f);
return Serial.write(c) == 1? 0 : 1;
}
FILE serial_stdout;
#define RX_PAYLOAD_SIZE 16
uint8_t packet[RX_PAYLOAD_SIZE];
u16 rxid = 0; //0x831d;
void setup (void)
{
Serial.begin (115200);
// Set up nrf24l01 IOs (soft spi)
pinMode(MOSI_pin, OUTPUT);
pinMode(SCK_pin, OUTPUT);
pinMode(CS_pin, OUTPUT);
pinMode(CE_pin, OUTPUT);
pinMode(MISO_pin, INPUT);
initRF();
memset(packet,0,sizeof(packet));
build_packet();
// Set up tx power on
pinMode(TX_POWER_pin ,OUTPUT);
reset_tx();
// Set up stdout
fdev_setup_stream(&serial_stdout, serial_putchar, NULL, _FDEV_SETUP_WRITE);
stdout = &serial_stdout;
// turn on hardware SPI in slave mode
SPCR |= bit (SPE);
// have to send on master in, *slave out*, pin12, unused
pinMode(MISO, OUTPUT);
// get ready for an interrupt
pos = 0; // buffer empty
process_it = false;
// now turn on interrupts
SPI.attachInterrupt();
// csn interrupt
attachInterrupt(digitalPinToInterrupt(2), process, RISING);
// csv header
Serial.println("rxid (hex),address,rxid (s16), address[3:4] (s16)");
}
// csn interrupt routine
void process()
{
process_it = true;
}
// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR; // grab byte from SPI Data Register
// add to buffer if room
if (pos < (sizeof (buf) - 1))
buf [pos++] = c;
}
// init nrf24l01
void initRF()
{
if(!NRF24L01_Reset()) {
Serial.println("NRF24 not detected!");
for(;;);
}
NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TX_EN);
NRF24L01_FlushTx();
NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, 0x07);
NRF24L01_SetBitrate(NRF24L01_BR_1M);
NRF24L01_SetPower(TX_POWER_20mW);
NRF24L01_Activate(0x73); // Activate feature register
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00); // Set feature bits on
NRF24L01_Activate(0x53);
NRF24L01_Activate(0x53);
XN297_SetTXAddr((const uint8_t*)"mjxRC", 5); // bind address
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x3b); // one of bind frequencies
}
// reset transmitter (via n-fet)
// permanently close the bind (lock) switch
// by soldering A & B together so the TX
// always starts in bind mode
void reset_tx()
{
digitalWrite(TX_POWER_pin, LOW);
delay(15);
digitalWrite(TX_POWER_pin, HIGH);
}
// bind packet from simulated bugs3 mini rx
void build_packet()
{
packet[1] = rxid >> 8;
packet[2] = rxid & 0xff;
packet[11]= 0xc0;
packet[0] = 0x6d + 0xc0;
packet[0]+= packet[1];
packet[0]+= packet[2];
}
// main loop - wait for flag set in csn interrupt routine
void loop (void)
{
static u32 next_packet = 0;
static u32 reset_timer = 0;
if (process_it) // csn went HIGH
{
// check if this is a TX_ADDR write command with 5 bytes of data
// drop it if it is bind address
if((u8)buf[0]==0x30 && pos==6 && memcmp(&buf[1], (const uint8_t*)"mjxRC", 5)) {
cli(); // stop messing with the buffer please, Serial is slow!
printf("%04x,", (uint16_t)rxid);
for(byte i=1; i<6; i++)
printf("%02x ", (uint8_t)buf[i]);
printf(",%d,", (int16_t)rxid);
printf("%d\n", (uint16_t)buf[4]<<8|buf[5]);
memset(buf,0,6);
sei();
if(rxid==0xffff) {
cli();
printf("\nDone!\n");
digitalWrite(TX_POWER_pin, LOW);
for(;;);
}
rxid++;
build_packet();
}
pos = 0;
process_it = false;
}
// reset transmiter
if(millis() >= reset_timer) {
reset_tx();
reset_timer += 300;
}
// transmit bind reply continuously
if(micros() >= next_packet) {
// Power on, TX mode, 2byte CRC
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
XN297_WritePayload(packet, RX_PAYLOAD_SIZE);
next_packet += 3000;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment