.NET Micro Framework driver for the nRF8001

Introduction

A few months ago I started running again. Music helps me to stay motivated. Since most earphones keep falling out, especially when the sweat comes out, I googled for some sports earphones. After reading some good reviews I bought the Plantronics BackBeat Fit.

![Plantronics BackBeat Fit](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/7635.backbeat_2D00_fit_2D00_green.png)
Figure 1 - Plantronics BackBeat Fit.

And, wow, what a great pair of earphones. The sound is great, comfortable to wear and battery life is more than I excepted. The device connects via Bluetooth 3.0, simple and fluently.

This positive experience triggered my interest in Bluetooth and especially in Bluetooth Low Energy (4.x). So, as an engineer I googled the specifications and found them here. After downloading the zip and opening the pdf I got a little discouraged; 2772 pages!

How would I study BLE in a different way?

I remembered that I still had this FEZ Spider Starter Kit from GHI lying around. FEZ Spider Starter Kit was the first commercially available .NET Gadgeteer-compatible kit, based on the .NET Micro Framework. Since this board has no support for Bluetooth LE I searched for an affordable Bluetooth LE breakout board. I chose the board from Adafruit based on the Nordic nRF8001, which can be found here, based on SPI.

![Adafruit nRF8001 breakout](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/5657.1697_2D00_04.jpg)
Figure 2 - Adafruit nRF8001 breakout.

It’s affordable and well orderable in Dutch stores. Also Adafruit has a nice 'getting started' project with this breakout board. But unfortunately the project is based on the Arduino and I couldn’t find support for the .NET Micro Framework.

Gadgeteer interface

A good description of the Gadgeteer hardware interface can be found here. Figure 3 shows the numbering of the pins in the connector. Figure 4 shows funtion per pin for each socket type.

![Gadgeteer socket pins](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/8103.Socket_5F00_pins_5F00_large.jpg)
Figure 3 - Gadgeteer socket socket pins.
![Gadgeteer socket types](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/2555.Socket-Types.PNG)
Figure 4 - Gadgeteer socket types.

GHI FEZ Spider

Figure 5 shows the FEZ Spider and its available sockets.

![FEZ Spider sockets map](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/7585.fez_5F00_spider_5F00_socket_5F00_map.png)
Figure 5 - EZ Spider sockets map.

Hardware setup

The FEZ Spider starter kit contains an Extender module that can be used to connect the nRF8001 breakout board to the main board. I soldered a 10-pins header on it and connected jumperwires.

![Connection FEZ Spider side](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/2388.WP_5F00_20160311_5F00_008-_2800_2_2900_.jpg)
Figure 6 - Connection FEZ Spider side.
  • 3V3: -
  • 5V: Red
  • P3: Blue -> !GPIO ('!' denotes interrupt-capable)
  • P4: White -> GPIO
  • P5: Gray -> GPIO
  • P6: Orange -> CS
  • P7: Purple -> MOSI
  • P8: Green -> MISO
  • P9: Yellow -> SCK
  • GND: Black

I also soldered a 10-pins header on the Adafruit Bluetooth nRF8001 module and connected the jumperwires from the Extender module.

![Connection Adafruit Bluetooth nRF8001 side](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/6505.WP_5F00_20160311_5F00_011-_2800_2_2900_.jpg) ![Connection Adafruit Bluetooth nRF8001 side](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/5123.WP_5F00_20160311_5F00_006.jpg)
Figure 7 - Connection Adafruit Bluetooth nRF8001 side.
  • SCK: Yellow
  • MISO: Green
  • MOSI: Purple
  • REQ: White
  • RDY: Blue
  • ACT: Gray
  • RST: Orange
  • 3Vo: -
  • GND: Black
  • VIN: Red

Figure 8 shows the complete setup. Connect the Bluetooth module to the Extender module and the Extender module to the FEZ Spider at socket 6, both by a standard Gadgeteer cable. Socket 6 is configured as SPI. Also connect the USB Module to socket 1 to power the FEZ Spider (and Bluetooth module) and to be able to debug the software.

![image description](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/1321.WP_5F00_20160311_5F00_010.jpg)
Figure 8 - Complete setup.

Software setup

The Adafruit 'getting started' project can be found here. The project description contains several links to apps for both Android and iOS to be able to test the driver software. The driver software can be found on CodePlex here. The Visual Studio 2015 solution contains the following projects:

  • Nordic_nRF8001: Contains the library for handling the Application Control Interface (ACI) protocol. Here a the ACI messages defined.
  • Adafruit_BLE_UART: Contains the library for handling the setup and SPI communication with the nRF8001.
  • Adafruit_BLE_UART_FEZSpider_Test: Contains an example usage of the Adafruit_BLE_UART. This is the executable. Figure 9 shows the Gadgeteer layout. This view is shown when the file Program.gadgeteer is opened.

All projects are configured for NETMF 4.3. Only Adafruit_BLE_UART_FEZSpider_Test is depedend on the actual device, in this case the FEZ Spider.

![image description](/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-04-DZ-878/3377.Gadgeteer.PNG)
Figure 9 - Gadgeteer setup in Visual Studio.

Driver software

The code to configure the driver and do something with the data received can be found in Program.cs in the Adafruit_BLE_UART_FEZSpider_Test project.

var socket = breakout.Socket; // breakout is generated by the Gadgeteer plugin in Visual Studio
var config = new NordicRf8001Config()
{
   SpiModule = SPI.SPI_module.SPI2,
   ReqInputPin = socket.CpuPins[4],
   ActOutputPin = socket.CpuPins[5],
   RdyOutputPin = socket.CpuPins[3],
   RstInputPin = socket.CpuPins[6],
   McuSpiBitOrder = BitOrder.Msb
};

var chip = new NordicRf8001(config);
chip.WaitForSetupDone();
chip.OnDataReceived += data =>
{
   try
   {
      var s = new string(Encoding.UTF8.GetChars(data));
      chip.Write(data);
      Debug.Print(s);
   }
   catch (Exception)  { }
};

Particularities

  • SPI bitorder. The implementation of SPI in the .NET Micro Framework writes and reads the most significant bit (LSB) first. The nRF8001 expects the least significant bit first (LSB). In Aci.ReadWriteToSpiPort contains the following code to solve this.

    if (_mcuSpiBitOrder == BitOrder.Lsb)
    {
        _spiPort.WriteRead(writeBuffer, readBuffer);
    }
    else
    {
        Utils.ReverseBits(writeBuffer);
        _spiPort.WriteRead(writeBuffer, readBuffer);
        Utils.ReverseBits(readBuffer);
    }
    
  • Clock should be low when idle. The SPI configuration interface contains a parameter for specifying the state (i.e. high or low) of the master clock line when no byte is written or read. The nRF8001 needs this to be low. When the SPI is configured, the line is initially high. So just before reset, a zero-byte is written to set it low.

    _spiPort = new SPI(_spiConfiguration);
    _spiPort.Write(new byte[] {0x00});
    ...
    Reset();
    

Contact

Contact me at bob@codeconsult.nl if you have questions or remarks about this blog.

Anonymous