adafruit / RadioHead

A github'ified version of http://www.airspayce.com/mikem/arduino/RadioHead/
Other
186 stars 115 forks source link

RFM69HCW running on SAMD51 (Arduino): Mode stuck in IDLE #67

Closed richbai90 closed 2 years ago

richbai90 commented 2 years ago

I'm trying to use your library to drive an RFM69HCW radio module via SPI. The problem is that the board never gets out of the waitSendPacket loop. By printing out the values of the RegIrqFlags1 and RegIrqFlags2 registers as well as printing some debug lines in the send method I've been able to track the issue down to this flow:

  1. Call Send
  2. Send successfully transmits the message over SPI
  3. An interrupt occurs: Mode: 2 (IDLE), flags1: 0x80 (ModeReady) flags 2: 0x60 (FifoLevel, FifoNotEmpty)
  4. Another interrupt occurs - Flags and mode are the same as the first
  5. Another interrupt occurs Mode: 2 (IDLE), flags1: 0x90 (PLLLock, ModeReady), flags2: 0x60 (FifoLevel, FifoNotEmpty)
  6. Stuck in waitSendPacket

It is strange that PLLLock should be set when the Mode according to the library is IDLE. Per the datasheet that's not actually possible. So the question becomes, why is the mode stuck in IDLE even when the Radio is reporting that this isn't the case. My code is adapted from the example code written for the feather32u4, which you can see below.

Some Other Details

I've tried to do as much of the leg work as possible so hopefully this is a relatively simple thing that I am missing. Thank you in advance.

// rf69 demo tx rx.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messageing client
// with the RH_RF69 class. RH_RF69 class does not provide for addressing or
// reliability, so you should only use RH_RF69  if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example rf69_server.
// Demonstrates the use of AES encryption, setting the frequency and modem 
// configuration

#include "Sketch.h" // includes <Arduino.H> as well as setup and loop declarations
#include <SPI.h>
#include <RH_RF69.h>

/************ Radio Setup ***************/

// Change to 434.0 or other frequency, must match RX's freq!
#define RF69_FREQ 915.0

#define RFM69_CS 53
#define RFM69_INT 7
#define RFM69_RST 5
#define LED 13

// forward declaration
void Blink(byte PIN, byte DELAY_MS, byte loops);

// Singleton instance of the radio driver
RH_RF69 rf69(RFM69_CS, RFM69_INT);

int16_t packetnum = 0;  // packet counter, we increment per xmission

void setup() 
{
  Serial.begin(9600);
  while (!Serial) { delay(1); } // wait until serial console is open, remove if not tethered to computer

  pinMode(LED, OUTPUT);     
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, LOW);

  Serial.println("Feather RFM69 TX Test!");
  Serial.println();

  // manual reset
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);

  if (!rf69.init()) {
    Serial.println("RFM69 radio init failed");
    while (1);
  }
  Serial.println("RFM69 radio init OK!");
  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
  // No encryption
  if (!rf69.setFrequency(RF69_FREQ)) {
    Serial.println("setFrequency failed");
  }

  // If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
  // ishighpowermodule flag set like this:
  rf69.setTxPower(20, true);  // range from 14-20 for power, 2nd arg must be true for 69HCW

  // The encryption key has to be the same as the one in the server
  uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  rf69.setEncryptionKey(key);

  pinMode(LED, OUTPUT);

  Serial.print("RFM69 radio @");  Serial.print((int)RF69_FREQ);  Serial.println(" MHz");
}

void loop() {
  delay(1000);  // Wait 1 second between transmits, could also 'sleep' here!

  char radiopacket[20] = "Hello World #";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Sending "); Serial.println(radiopacket);

  // Send a message!
  rf69.send((uint8_t *)radiopacket, strlen(radiopacket));
  rf69.waitPacketSent();

  // Now wait for a reply
  uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  if (rf69.waitAvailableTimeout(500))  { 
    // Should be a reply message for us now   
    if (rf69.recv(buf, &len)) {
      Serial.print("Got a reply: ");
      Serial.println((char*)buf);
      Blink(LED, 50, 3); //blink LED 3 times, 50ms between blinks
    } else {
      Serial.println("Receive failed");
    }
  } else {
    Serial.println("No reply, is another RFM69 listening?");
  }
}

void Blink(byte PIN, byte DELAY_MS, byte loops) {
  for (byte i=0; i<loops; i++)  {
    digitalWrite(PIN,HIGH);
    delay(DELAY_MS);
    digitalWrite(PIN,LOW);
    delay(DELAY_MS);
  }
}

sck output

ladyada commented 2 years ago

the feather examples are tested to work with the m4 feather as long as wiring follows the tutorial

richbai90 commented 2 years ago

Hello Ladyada, I really apprecaite you getting back so quickly. I'm not sure what I am missing then. I've triple checked my wiring, here's how I have it setup

MISO, MOSI, and SCK all go from the labeled pins on the radio to the center SPI pins on the Grand Central. NSS goes from the radio to digital pin 53, with a 100K PU resistor in parallel. The radio is fed from the 3v3 output on the Grand Central and a 10uF electrolytic capacitor is in parallel with ground to filter noise. I have tripple checked the polarity of the capacitor also, given that it's electrolytic. I'm using the GC as the TX device, you can see my code in the original issue was adapted from the raw TX Feather example, and the Feather 32u4 RFM69HCW board as the receiver running the raw RX Feather example.

ladyada commented 2 years ago

hiya, questions about how to use adafruit products are best posted in the adafruit forums at forums.adafruit.com thanks! :)

richbai90 commented 2 years ago

Understood, I'll take this matter up over there. Thank you!