Skip to content

2. Arduino DUE Support

Jason edited this page Dec 18, 2017 · 3 revisions

Make BLE Shield compatible with DUE

Last Updated: 2014-12-11


Description


BLE Shield stands for Bluetooth Low Energy (BLE) Shield. It is designed to work with Arduino boards or compatibles. The on-board BLE chip is Nordic nRF8001. DUE is a ARM core development board provided by Arduino. More information about it, please refer to Arduino DUE introduction page. Therefore, BLE Shield can work with DUE together, but need some changes to the BLE library. It works well on Arduino IDE 1.5.2.

Objective


Make BLE library compatible with DUE so that BLE Shield and DUE can work together with BLE Controller app.

Requirements


hardware

  1. BLE Shield v2.0
  2. Arduino DUE
  3. Micro USB cable
  4. A Smart Devices supporting Bluetooth 4.0 Low Energy and running Bluetooth 4.0 Low Energy compatible Operation System, with BLE Controller App installed
  5. A Personal Computer with Arduino IDE 1.5.2 installed

software

  1. Arduino IDE version 1.5.2
  2. Nordic nRF8001 BLE Library for Arduino beta version 0.9.0
  3. RBL nRF8001 Library for Arduino ver.20140701
  4. iOS BLE Controller App or Android BLE Controller App

Getting Started


  1. Please follow our BLE Shield Getting Started Guide to set up BLE libraries.

  2. Navigate to Arduino library -> RBL_nRF8001 and open RBL_nRF8001.cpp. Add conditional compilation for SPI code. It locates at the beginning and the end of the function ble_begin() and ble_do_events().

     void ble_begin()
     {
     #if !defined(__SAM3X8E__)
     	spi_old = SPCR;
     	SPI.setBitOrder(LSBFIRST);
     	SPI.setClockDivider(SPI_CLOCK_DIV8);
     	SPI.setDataMode(SPI_MODE0);
     #endif
     	... /* other code */
     #if !defined(__SAM3X8E__)
     	SPCR = spi_old;
     	SPI.begin();
     #endif
     }
    
     ...
    
     void ble_do_events()
     {
     #if !defined(__SAM3X8E__)
     	spi_old = SPCR;
     	SPI.setBitOrder(LSBFIRST);
     	SPI.setClockDivider(SPI_CLOCK_DIV8);
     	SPI.setDataMode(SPI_MODE0);
     #endif
     	... /* other code */
     #if !defined(__SAM3X8E__)
     	SPCR = spi_old;
     #endif
     }
    
  3. Navigate to Arduino library -> RBL_nRF8001 and open RBL_nRF8001.h. Add conditional compilation for AVR head files.

     #if !defined(__SAM3X8E__)
     	#include <avr/sleep.h>
     	#include <avr/interrupt.h>
     #endif
    
  4. Navigate to Arduino library -> BLE and open hal_platform.h. Add board dependent defines for DUE.

     #if defined (__AVR__)
     	... /* definition for AVR */
     #elif defined(__PIC32MX__)
     	... /* definition for PIC */
     #elif defined(__SAM3X8E__)
     	/* definition for DUE */
     	#include "Arduino.h"
    
     	#define F(X) (X)
     	#undef PSTR
     	#define PSTR(x) (x)
     	#define PROGMEM
     
     	#define pgm_read_byte_near(x) (x)
     	#define memcpy_P memcpy
     
     	#define DUE_SPI_CSN  52
    
     #endif
    
  5. Navigate to Arduino library -> BLE and open aci_setup.cpp. Add board dependent defines for DUE in function aci_setup_fill(aci_state_t *aci_stat, uint8_t *num_cmd_offset).

     static bool aci_setup_fill(aci_state_t *aci_stat, uint8_t *num_cmd_offset)
     {
     	... /* other code */
     	//Board dependent defines
     #if defined (__AVR__)
     	... /* definition for AVR */
     #elif defined(__PIC32MX__)
     	... /* definition for PIC */
     #elif defined(__SAM3X8E__)
     	memcpy(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]), 
     		  (aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]+2));
     #endif
     	... /* other code */
     }
    
  6. Navigate to Arduino library -> BLE and open hal_aci_tl.cpp. Add conditional compilation for AVR head files.

     #if !defined(__SAM3X8E__)
     	#include <avr/sleep.h>
     #endif
    

Add SPI initialization code for DUE in function hal_aci_tl_init(aci_pins_t *a_pins, bool debug).

	void hal_aci_tl_init(aci_pins_t *a_pins, bool debug)
	{
		... /* other code */
	#if defined(__SAM3X8E__)
		SPI.begin(DUE_SPI_CSN);
		SPI.setBitOrder(DUE_SPI_CSN, LSBFIRST);
		SPI.setClockDivider(DUE_SPI_CSN, a_pins->spi_clock_divider); 
		SPI.setDataMode    (DUE_SPI_CSN, SPI_MODE0);
	#else
		SPI.begin();
		//Board dependent defines
		#if defined (__AVR__)
			//For Arduino use the LSB first
			SPI.setBitOrder(LSBFIRST);
		#elif defined(__PIC32MX__)
			//For ChipKit use MSBFIRST and REVERSE the bits on the SPI as LSBFIRST is not supported
			SPI.setBitOrder(MSBFIRST);
		#endif
		SPI.setClockDivider(a_pins->spi_clock_divider);
		SPI.setDataMode(SPI_MODE0);
	#endif
		... /* other code */
	}

Add board dependent defines for DUE in function uint8_t spi_readwrite(const uint8_t aci_byte).

	static uint8_t spi_readwrite(const uint8_t aci_byte)
	{
	#if defined (__AVR__)
		... /* definition for AVR */
	#elif defined(__PIC32MX__)
		... /* definition for PIC */
	#elif defined(__SAM3X8E__)
		return SPI.transfer(DUE_SPI_CSN, aci_byte, SPI_CONTINUE);
	#endif
	}
  1. Save all of the files that you have modified.

  2. Plug BLE Shield on the DUE and make sure that REQN is located at D9 and RDYN located at D8. Connect DUE to the host PC using the PROGRAMMING USB port via micro USB cable.

  3. Open Arduino IDE 1.5.2. Open the BLEControllerSketch, Arduino IDE Menu: File > Examples > RBL_nRF8001 > BLEControllerSketch Alt text

Edit line 17 to #include <RBL_services.h>

  1. Select Board and Serial Port
    Arduino IDE Menu: Tools > Board > Arduino Due (Programming Port)
    Arduino IDE Menu: Tools > Serial Port > (Your Serial Port)

  2. Upload the Sketch - click on the Right Arrow button at the IDE toolbar to begin upload (it will compile first).

  3. Run BLE Controller app. Touch the up-left menu icon to select corresponding application: BLE Controller.

  4. Click "Scan" - if everything is correct, the list will show your BLE devices, select BLE Shield to connect. On success, it will shows all pins of your Arduino DUE board. Change the pin mode and set the pin state to control.