After debugging Windows 10 IoT Core, .NetMF and Wilderness Labs Meadow nRF24L01P libraries I figured yet another port, this time to a GHI Electronics Tiny CLR V2 powered device shouldn’t be “rocket science”.
This test rig uses SC20100S Dev and MikroE nRF C Click boards.

//---------------------------------------------------------------------------------
// Copyright (c) May 2020, devMobile Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//---------------------------------------------------------------------------------
namespace devMobile.IoT.nRf24L01.ModuleSPI
{
using System;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Threading;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.Spi;
using GHIElectronics.TinyCLR.Pins;
class Program
{
const byte SETUP_AW = 0x03;
const byte RF_CH = 0x05;
const byte RX_ADDR_P0 = 0x0A;
const byte R_REGISTER = 0b00000000;
const byte W_REGISTER = 0b00100000;
const string P0_Address = "ZYXWV";
static SpiDevice nrf24L01Device;
static void Main()
{
try
{
GpioController gpioController = GpioController.GetDefault();
var settings = new SpiConnectionSettings()
{
ChipSelectType = SpiChipSelectType.Gpio,
//ChipSelectLine = FEZ.GpioPin.D10,
ChipSelectLine = gpioController.OpenPin(SC20100.GpioPin.PD3),
Mode = SpiMode.Mode0,
//Mode = SpiMode.Mode1,
//Mode = SpiMode.Mode2,
//Mode = SpiMode.Mode3,
ClockFrequency = 500000,
//ChipSelectActiveState = true
ChipSelectActiveState = false,
//ChipSelectHoldTime = new TimeSpan(0, 0, 0, 0, 500),
//ChipSelectSetupTime = new TimeSpan(0, 0, 0, 0, 500),
};
var spiController = SpiController.FromName(SC20100.SpiBus.Spi3);
Debug.WriteLine("nrf24L01Device Device...");
nrf24L01Device = spiController.GetDevice(settings);
if (nrf24L01Device == null)
{
Debug.WriteLine("nrf24L01Device == null");
}
Thread.Sleep(100);
Debug.WriteLine("ConfigureSpiPort Done...");
Debug.WriteLine("");
Thread.Sleep(500);
}
catch (Exception ex)
{
Debug.WriteLine("Configure SpiPort " + ex.Message);
}
try
{
// Read the Address width
Debug.WriteLine("Read address width");
byte[] txBuffer1 = new byte[] { SETUP_AW | R_REGISTER, 0x0 };
byte[] rxBuffer1 = new byte[txBuffer1.Length];
Debug.WriteLine(" nrf24L01Device.TransferFullDuplex...SETUP_AW");
Debug.WriteLine(" txBuffer:" + BitConverter.ToString(txBuffer1));
nrf24L01Device.TransferFullDuplex(txBuffer1, rxBuffer1);
Debug.WriteLine(" rxBuffer:" + BitConverter.ToString(rxBuffer1));
// Extract then adjust the address width
byte addressWidthValue = rxBuffer1[1];
addressWidthValue &= 0b00000011;
addressWidthValue += 2;
Debug.WriteLine($"Address width 0x{SETUP_AW:x2} - Value 0X{rxBuffer1[1]:x2} Value adjusted {addressWidthValue}");
Debug.WriteLine("");
// Write Pipe0 Receive address
Debug.WriteLine($"Write Pipe0 Receive Address {P0_Address}");
byte[] txBuffer2 = new byte[addressWidthValue + 1];
txBuffer2[0] = RX_ADDR_P0 | W_REGISTER;
Array.Copy(Encoding.UTF8.GetBytes(P0_Address), 0, txBuffer2, 1, addressWidthValue);
Debug.WriteLine(" nrf24L01Device.Write...RX_ADDR_P0");
Debug.WriteLine(" txBuffer:" + BitConverter.ToString(txBuffer2));
nrf24L01Device.Write(txBuffer2);
Debug.WriteLine("");
// Read Pipe0 Receive address
Debug.WriteLine("Read Pipe0 Receive address");
byte[] txBuffer3 = new byte[addressWidthValue + 1];
txBuffer3[0] = RX_ADDR_P0 | R_REGISTER;
byte[] rxBuffer3 = new byte[txBuffer3.Length];
Debug.WriteLine(" nrf24L01Device.TransferFullDuplex...RX_ADDR_P0");
Debug.WriteLine(" txBuffer:" + BitConverter.ToString(txBuffer3));
nrf24L01Device.TransferFullDuplex(txBuffer3, rxBuffer3);
Debug.WriteLine(" rxBuffer:" + BitConverter.ToString(rxBuffer3));
Debug.WriteLine($"Address 0x{RX_ADDR_P0:x2} Address {UTF8Encoding.UTF8.GetString(rxBuffer3, 1, addressWidthValue)}");
Debug.WriteLine("");
// Read the RF Channel
Debug.WriteLine("RF Channel read 1");
byte[] txBuffer4 = new byte[] { RF_CH | R_REGISTER, 0x0 };
byte[] rxBuffer4 = new byte[txBuffer4.Length];
Debug.WriteLine(" nrf24L01Device.TransferFullDuplex...RF_CH");
Debug.WriteLine(" txBuffer:" + BitConverter.ToString(txBuffer4));
nrf24L01Device.TransferFullDuplex(txBuffer4, rxBuffer4);
Debug.WriteLine(" rxBuffer:" + BitConverter.ToString(rxBuffer4));
ushort rfChannel1 = rxBuffer4[1];
rfChannel1 += 2400;
Debug.WriteLine($"RF Channel 1 0x{RF_CH:x2} - Value 0X{rxBuffer4[1]:x2} - Value adjusted {rfChannel1}");
Debug.WriteLine("");
// Write the RF Channel
Debug.WriteLine("RF Channel write");
byte[] txBuffer5 = new byte[] { RF_CH | W_REGISTER, rxBuffer4[1]+=1};
Debug.WriteLine(" nrf24L01Device.Write...RF_CH");
Debug.WriteLine(" txBuffer:" + BitConverter.ToString(txBuffer5));
nrf24L01Device.Write(txBuffer5);
Debug.WriteLine("");
// Read the RF Channel
Debug.WriteLine("RF Channel read 2");
byte[] txBuffer6 = new byte[] { RF_CH | R_REGISTER, 0x0 };
byte[] rxBuffer6 = new byte[txBuffer6.Length];
Debug.WriteLine(" nrf24L01Device.TransferFullDuplex...RF_CH");
Debug.WriteLine(" txBuffer:" + BitConverter.ToString(txBuffer6));
nrf24L01Device.TransferFullDuplex(txBuffer6, rxBuffer6);
Debug.WriteLine(" rxBuffer:" + BitConverter.ToString(rxBuffer6));
ushort rfChannel2 = rxBuffer6[1];
rfChannel2 += 2400;
Debug.WriteLine($"RF Channel 2 0x{RF_CH:x2} - Value 0X{rxBuffer6[1]:x2} - Value adjusted {rfChannel2}");
Debug.WriteLine("");
}
catch (Exception ex)
{
Debug.WriteLine("Configure Port0 " + ex.Message);
}
}
}
}
After lots of tinkering with SPI configuration options I can read and write my nRF24L01 device receive port address
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
nrf24L01Device Device...
ConfigureSpiPort Done...
Read address width
nrf24L01Device.TransferFullDuplex...SETUP_AW
txBuffer:03-00
rxBuffer:0E-03
Address width 0x03 - Value 0X03 Value adjusted 5
Write Pipe0 Receive Address ZYXWV
nrf24L01Device.Write...RX_ADDR_P0
txBuffer:2A-5A-59-58-57-56
Read Pipe0 Receive address
nrf24L01Device.TransferFullDuplex...RX_ADDR_P0
txBuffer:0A-00-00-00-00-00
rxBuffer:0E-5A-59-58-57-56
Address 0x0a Address ZYXWV
RF Channel read 1
nrf24L01Device.TransferFullDuplex...RF_CH
txBuffer:05-00
rxBuffer:0E-15
RF Channel 1 0x05 - Value 0X15 - Value adjusted 2421
RF Channel write
nrf24L01Device.Write...RF_CH
txBuffer:25-16
RF Channel read 2
nrf24L01Device.TransferFullDuplex...RF_CH
txBuffer:05-00
rxBuffer:0E-16
RF Channel 2 0x05 - Value 0X16 - Value adjusted 2422
Pingback: TinyCLR OS V2 nRF24L01 library Part2 | devMobile's blog
Pingback: nanoFramework nRF24L01 library Part2 | devMobile's blog