I am working on a C# port of the Adafruit_CircuitPython_RFM69 Python library which is an SPI radio module library that I'm using with a Raspberry Pi.
I have most of the python properties ported over and tested/working successfully, except for being able to get/set the frequency_mhz & frequency_deviation Python properties.
I'm unable to receive any radio packets with my C# port, but the Python version works flawlessly, and I suspect the two properties in question is the reason why.
Frequency:
// works? - not perfectly accurate
rfm.Frequency = 433;
Console.WriteLine("Frequency: {0}", rfm.Frequency); // after setting 'rfm.Frequency = 433' the get method reports '432'
private int GetFrequency()
{
// FRF register is computed from the frequency following the datasheet.
// See section 6.2 and FRF register description.
// Read bytes of FRF register and assemble into a 24-bit unsigned value.
byte msb = ReadByte(_REG_FRF_MSB);
byte mid = ReadByte(_REG_FRF_MID);
byte lsb = ReadByte(_REG_FRF_LSB);
int frf = ((msb << 16) | (mid << 8) | lsb) & 0xFFFFFF;
int frequency = (frf * _FSTEP) / 1000000;
return frequency;
}
private void SetFrequency(int freq)
{
if (freq < 290 || freq > 1020)
throw new ArgumentOutOfRangeException(nameof(freq), freq, "frequency must be between range(290, 1020)");
// Calculate FRF register 24-bit value using section 6.2 of the datasheet.
int frf = ((freq * 1000000) / _FSTEP) & 0xFFFFFF;
// Extract byte values and update registers.
byte msb = (byte)(frf >> 16);
byte mid = (byte)((frf >> 8) & 0xFF);
byte lsb = (byte)(frf & 0xFF);
WriteByte(_REG_FRF_MSB, msb);
WriteByte(_REG_FRF_MID, mid);
WriteByte(_REG_FRF_LSB, lsb);
}
FrequencyDeviation:
// works? - not perfectly accurate
rfm.FrequencyDeviation = 250000;
Console.WriteLine("FrequencyDeviation: {0}", rfm.FrequencyDeviation); // after setting 'rfm.FrequencyDeviation = 250000' the get method reports '249978'
private int GetFrequencyDeviation()
{
byte msb = ReadByte(_REG_FDEV_MSB);
byte lsb = ReadByte(_REG_FDEV_LSB);
return _FSTEP * ((msb << 8) | lsb);
}
private void SetFrequencyDeviation(int value)
{
if (value < 0 || value > _FSTEP * 16383) // fdev is a 14-bit unsigned value
throw new ArgumentOutOfRangeException(nameof(value), value, $"frequency deviation must be between range(0, {_FSTEP * 16383})");
// Round up to the next closest integer value with addition of 0.5.
int fdev = (int)((value / _FSTEP) + 0.5) & 0x3FFF;
WriteByte(_REG_FDEV_MSB, (byte)(fdev >> 8));
WriteByte(_REG_FDEV_LSB, (byte)(fdev & 0xFF));
}
Any help/pointers is greatly appreciated, thanks in advance!
I did some testing for getting/setting the two properties in Python and they both return the exact values that were set, I tried many different casts and rounding methods in my C# port to no avail.
I'm expecting to get the same input/output as Python, and I'm unsure why I'm not.
I can't figure out why I can't do the exact same bit operations in C# that are done in the Adafruit Python code. I know it must have something to do with the C# type differences but I'm unsure how to combine/cast the Python types to C# properly.
Here is the RFM69 datasheet just in case.