Support for Arduino Due in CA Layer
authorvimala.v <vimala.v@samsung.com>
Tue, 31 Mar 2015 10:31:46 +0000 (16:01 +0530)
committerErich Keane <erich.keane@intel.com>
Thu, 2 Apr 2015 20:03:53 +0000 (20:03 +0000)
1) Sconscript is modifed for Due support.
2) A separate patch(arduino_due_ble.patch) is provided for BLE support.

Change-Id: Ide9894f64a307f1b6c17c19f1009150803458e16
Signed-off-by: vimala.v <vimala.v@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/590
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jonc@osg.samsung.com>
Reviewed-by: Erich Keane <erich.keane@intel.com>
resource/csdk/connectivity/build/How_To_Build.txt
resource/csdk/connectivity/build/arduino/Arduino_Setup_README.txt
resource/csdk/connectivity/build/arduino/SConscript
resource/csdk/connectivity/common/src/logger.c
resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch [new file with mode: 0644]
resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h
resource/csdk/connectivity/src/caprotocolmessage_singlethread.c

index ebe81e5..5b2c5b0 100644 (file)
@@ -87,7 +87,7 @@ Note :- Upon successful execution of above command(s) CA library and sample appl
 
 Arduino Build:
 
-Note :- Currently only megaADK build is supported.
+Note :- Currently Mega & Due build is supported.
 
 1) Set up Arduino first before building. Refer to "connectivity\build\arduino\Arduino_Setup_README.txt" file for help.
 
@@ -95,15 +95,19 @@ Note :- Currently only megaADK build is supported.
 
 3) Execute following command to start build :
 
-    $ scons TARGET_OS=arduino TARGET_TRANSPORT=<transport> TARGET_ARCH=avr BOARD=megaADK ARDUINO_HOME=<path_to_arduino_installation>
+For Arduino Mega
+    $ scons TARGET_OS=arduino TARGET_TRANSPORT=<transport> TARGET_ARCH=avr BOARD=mega ARDUINO_HOME=<path_to_arduino_installation>
+For Arduino Due
+    $ scons TARGET_OS=arduino TARGET_TRANSPORT=<transport> TARGET_ARCH=arm BOARD=arduino_due_x_dbg ARDUINO_HOME=<path_to_arduino_installation>
+    NOTE: BOARD=arduino_due_x_dbg|arduino_due_x. Default is arduino_due_x_dbg.
 
     Possible values for <transport> are:
     -> ETHERNET :
-    $ scons TARGET_OS=arduino TARGET_TRANSPORT=ETHERNET TARGET_ARCH=avr BOARD=megaADK ARDUINO_HOME=<path_to_arduino_installation>
+    $ scons TARGET_OS=arduino TARGET_TRANSPORT=ETHERNET TARGET_ARCH=avr BOARD=mega ARDUINO_HOME=<path_to_arduino_installation>
     -> WIFI :
-    $ scons TARGET_OS=arduino TARGET_TRANSPORT=WIFI TARGET_ARCH=avr BOARD=megaADK ARDUINO_HOME=<path_to_arduino_installation>
+    $ scons TARGET_OS=arduino TARGET_TRANSPORT=WIFI TARGET_ARCH=avr BOARD=mega ARDUINO_HOME=<path_to_arduino_installation>
     -> BLE :
-    $ scons TARGET_OS=arduino TARGET_TRANSPORT=BLE TARGET_ARCH=avr BOARD=megaADK ARDUINO_HOME=<path_to_arduino_installation>
+    $ scons TARGET_OS=arduino TARGET_TRANSPORT=BLE TARGET_ARCH=avr BOARD=mega ARDUINO_HOME=<path_to_arduino_installation>
 
     Note :- Only single transport can be built at a time for Arduino.
 
@@ -111,11 +115,11 @@ Note :- Currently only megaADK build is supported.
 
 5) After building sample, script will try to install on "/dev/ttyACM0" port in 'sudo' mode.
    To skip installation, set command line argument 'UPLOAD=false'.
-   "scons TARGET_OS=arduino TARGET_TRANSPORT=ETHERNET TARGET_ARCH=avr BOARD=megaADK ARDUINO_HOME=<path_to_arduino_installation> UPLOAD=false"
+   "scons TARGET_OS=arduino TARGET_TRANSPORT=ETHERNET TARGET_ARCH=avr BOARD=mega ARDUINO_HOME=<path_to_arduino_installation> UPLOAD=false"
 
 6) To set BLE Shield Name, include the option DEVICE_NAME during scons build.
 
-   -> $ scons TARGET_OS=arduino TARGET_TRANSPORT=ETHERNET TARGET_ARCH=avr BOARD=megaADK ARDUINO_HOME=<path_to_arduino_installation> DEVICE_NAME=OIC
+   -> $ scons TARGET_OS=arduino TARGET_TRANSPORT=ETHERNET TARGET_ARCH=avr BOARD=mega ARDUINO_HOME=<path_to_arduino_installation> DEVICE_NAME=OIC
 
    Specified Device name length MUST be less than 10 characters. RBL Library has this limitation.
    By Default DEVICE_NAME=OIC-DEVICE, if device name option is not specified
index 3f1cc0e..f3217e2 100644 (file)
@@ -24,11 +24,14 @@ STEPS to setup Arduino on linux machine for building CA code:
        (2) Extract zip file and apply RBL patch(connectivity/lib/arduino/RBL_nRF8001.patch) to "RBL_nRF8001" folder by following below steps,
                i)  Go to downloaded RBL_Library Folder ("nRF8001-master/Arduino/libraries/RBL_nRF8001")
                ii) Apply dos2unix for RBL_Library Folder and RBL Patch File (RBL_nRF8001.patch), if we have downloaded Library in Non UNIX Platform.
-               iii) Apply RBL Patch by using the below command
+               iii) Apply RBL Patch[connectivity\lib\arduino\RBL_nRF8001.patch] by using the below command
                        patch -p1 < RBL_Patch_File_Location(RBL_nRF8001.patch)
        (3) Copy the patched RBL_nRF8001 Library and place it in "arduino-<x.x.x>/libraries" folder
        (4) Download Nordic Arduino BLE library [Tag: "0.9.5.Beta" Version] from the link (https://github.com/NordicSemiconductor/ble-sdk-arduino).
                Extract the zip file and copy the "BLE" folder available under "libraries" folder and place it in "arduino-<x.x.x>/libraries" folder
+               i)  Apply dos2unix for the "BLE" folder.
+               ii) Go to the BLE folder and apply the patch[connectivity\lib\arduino\arduino_due_ble.patch] using the below command.
+                       patch -p1 < path/to/arduino_due_ble.patch
 
 5) ONE TIME ONLY - PATCH
        Complete patch has been provided at : "connectivity\lib\arduino\arduino_libraries.patch"
index 27a5921..d97d596 100644 (file)
@@ -114,12 +114,25 @@ def __import_lib(env, lib):
        lib_src.extend(__search_files(lib_path, '*.c'))
        lib_src.extend(__search_files(lib_path, '*.cpp'))
 
+       lib_obj = __src_to_obj(env, lib_src)
        build_dir = env.get('BUILD_DIR')
        if build_dir:
-               lib_a = env.StaticLibrary(build_dir + lib, __src_to_obj(env, lib_src))
+               lib_a = env.StaticLibrary(build_dir + lib, lib_obj)
        else:
-               lib_a = env.StaticLibrary(lib, __src_to_obj(env, lib_src))
-       env.PrependUnique(LIBS = [File(lib_a[0])])
+               lib_a = env.StaticLibrary(lib, lib_obj)
+
+       # If we link libSPI.a, the final binary is not getting launched
+       # on the board.  Which is not the case if we directly use SPI.o.
+
+       if env.get('TARGET_ARCH') == 'arm':
+               if lib == 'SPI':
+                       for obj in lib_obj:
+                               if obj.name.endswith('SPI.o'):
+                                       env.PrependUnique(LIBS = [File(obj)])
+               else:
+                       env.AppendUnique(LIBS = [File(lib_a[0])])
+       else:
+               env.PrependUnique(LIBS = [File(lib_a[0])])
 
 def __build_core(env):
        core_src = __search_files(core_folder, '*.S')
@@ -154,18 +167,25 @@ def __create_bin(env, source):
        else:
                hex = env.Command(name + '.hex', source, 'arm-none-eabi-objcopy -O binary $SOURCE $TARGET')
 
-#Currently supporting only megaADK build
+#Currently Mega and Due build is supported.
 def __upload(env, binary):
         if target_arch == 'avr':
                 protocol = __get_board_info(board, '.upload.protocol')
                 speed = __get_board_info(board, '.upload.speed')
                 port = '/dev/ttyACM0'
-                upload_cmd = 'sudo ' + arduino_home + '/hardware/tools/avr/bin/avrdude -C' + arduino_home +'/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -p' \
+                upload_cmd = arduino_home + '/hardware/tools/avr/bin/avrdude -C' + arduino_home +'/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -p' \
                 + mcu + ' -c' + protocol + ' -P' + port + ' -b' + speed + ' -D -Uflash:w:' + binary + ':i'
 
                 print "Upload command: %s" %upload_cmd
                 install_cmd = env.Command('install_cmd', None, upload_cmd)
                 env.Default('install_cmd')
+        else:
+               uu = __get_board_info(board, '.upload.native_usb')
+                port = 'ttyACM0'
+               upload_cmd = 'stty -F /dev/' + port + ' speed 1200 cs8 -cstopb -parenb \n' + arduino_home + '/hardware/tools/bossac -i -d --port=' + port + ' -U ' + uu + ' -e -w -v -b ' + binary + ' -R'
+                print "Upload command: %s" %upload_cmd
+                install_cmd = env.Command('install_cmd', None, upload_cmd)
+                env.Default('install_cmd')
 
 # Print the command line that to upload binary to the board
 def __upload_help(env):
@@ -356,11 +376,13 @@ else:
        else:
                cpu_flag = '-mcpu=' + mcu
 
-       comm_flag = [cpu_flag, '-DF_CPU=' + f_cpu, '-DARDUINO=' + version, '-DARDUINO_' + __get_board_info(board, '.build.board'), '-std=c99']
+       comm_flag = [cpu_flag, '-DF_CPU=' + f_cpu, '-DARDUINO=' + version, '-DARDUINO_' + __get_board_info(board, '.build.board')]
        if target_arch == 'arm':
-               comm_flag.extend(['-DARDUINO_ARCH_SAM'])
+               # As of 1.5.8 the arduino headers had asm bugs with ARM and
+               # require gnu99 to be used.
+               comm_flag.extend(['-std=gnu99', '-DARDUINO_ARCH_SAM'])
        else:
-               comm_flag.extend(['-DARDUINO_ARCH_AVR'])
+               comm_flag.extend(['-std=c99', '-DARDUINO_ARCH_AVR'])
 
        compiler_path = platform_info.get('compiler.path')
        compiler_path = compiler_path.replace('{runtime.ide.path}', arduino_home)
index 318c914..6e1098d 100644 (file)
@@ -326,7 +326,7 @@ void OICLog(LogLevel level, PROGMEM const char *tag, const int16_t lineNum,
         return;
     }
     char buffer[LINE_BUFFER_SIZE] = {0};
-    strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level])));
+    GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
     Serial.print(buffer);
     char c;
     Serial.print(F(": "));
@@ -360,7 +360,7 @@ void OICLogv(LogLevel level, PROGMEM const char *tag, const int16_t lineNum,
     char buffer[LINE_BUFFER_SIZE];
     va_list ap;
     va_start(ap, format);
-    strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level])));
+    GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
     Serial.print(buffer);
 
     char c;
@@ -373,7 +373,11 @@ void OICLogv(LogLevel level, PROGMEM const char *tag, const int16_t lineNum,
     Serial.print(lineNum);
     Serial.print(F(": "));
 
+#ifdef __AVR__
     vsnprintf_P(buffer, sizeof(buffer), format, ap);
+#else
+    vsnprintf(buffer, sizeof(buffer), format, ap);
+#endif
     for (char *p = &buffer[0]; *p; p++)
     {
         // emulate cooked mode for newlines
diff --git a/resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch b/resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch
new file mode 100644 (file)
index 0000000..2e0b165
--- /dev/null
@@ -0,0 +1,69 @@
+diff -rupN BLE_Old/aci_setup.cpp BLE_New/aci_setup.cpp
+--- BLE_Old/aci_setup.cpp      2015-02-26 08:59:03.289267311 +0530
++++ BLE_New/aci_setup.cpp      2015-02-26 08:59:02.985267313 +0530
+@@ -63,6 +63,9 @@ static bool aci_setup_fill(aci_state_t *
+               //Add 2 bytes to the length byte for status byte, length for the total number of bytes
+               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)); 
++      #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
+     //Put the Setup ACI message in the command queue
+diff -rupN BLE_Old/hal_aci_tl.cpp BLE_New/hal_aci_tl.cpp
+--- BLE_Old/hal_aci_tl.cpp     2015-02-26 08:59:03.521267309 +0530
++++ BLE_New/hal_aci_tl.cpp     2015-02-26 08:59:03.285267311 +0530
+@@ -346,6 +346,12 @@ void hal_aci_tl_init(aci_pins_t *a_pins,
+   The SPI library assumes that the hardware pins are used
+   */
++#if defined(__SAM3X8E__)
++      SPI.begin          (DUE_SPI_CSN);
++  SPI.setBitOrder    (DUE_SPI_CSN, LSBFIRST);
++  SPI.setClockDivider(DUE_SPI_CSN, a_pins->spi_clock_divider); /* This will run the SPI at 3MHz assuming a 84MHz clock to the mcu*/
++  SPI.setDataMode    (DUE_SPI_CSN, SPI_MODE0);
++#else
+   SPI.begin();
+   //Board dependent defines
+   #if defined (__AVR__)
+@@ -357,6 +363,7 @@ void hal_aci_tl_init(aci_pins_t *a_pins,
+   #endif
+   SPI.setClockDivider(a_pins->spi_clock_divider);
+   SPI.setDataMode(SPI_MODE0);
++#endif
+   /* Initialize the ACI Command queue. This must be called after the delay above. */
+   aci_queue_init(&aci_tx_q);
+@@ -429,6 +436,8 @@ static uint8_t spi_readwrite(const uint8
+     uint8_t tmp_bits;
+     tmp_bits = SPI.transfer(REVERSE_BITS(aci_byte));
+       return REVERSE_BITS(tmp_bits);
++#elif defined(__SAM3X8E__)
++      return SPI.transfer(DUE_SPI_CSN, aci_byte, SPI_CONTINUE);
+ #endif
+ }
+diff -rupN BLE_Old/hal_platform.h BLE_New/hal_platform.h
+--- BLE_Old/hal_platform.h     2015-02-26 08:59:03.293267311 +0530
++++ BLE_New/hal_platform.h     2015-02-26 08:59:02.989267313 +0530
+@@ -71,6 +71,19 @@
+       
+       //Redefine the function for reading from flash in ChipKit
+       #define memcpy_P        memcpy
++#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
+ #endif /* PLATFORM_H__ */
index deadd0b..76dcd9d 100644 (file)
@@ -108,7 +108,9 @@ extern "C"
 
 #ifdef WITH_ARDUINO
 #include "Time.h"
-#ifdef __AVR__
+#ifdef ARDUINO_ARCH_SAM
+#include <sys/types.h>  // time_t is defined in sys/types.h for ARM compiler
+#else
 typedef unsigned long time_t; //AVR compiler doesnt define time_t
 #endif
 typedef time_t coap_tick_t;
index d7b1ad1..4588eae 100644 (file)
 #include "logger.h"
 #include "oic_malloc.h"
 
+// ARM GCC compiler doesnt define srandom function.
+#if defined(ARDUINO) && !defined(ARDUINO_ARCH_SAM)
+#define HAVE_SRANDOM 1
+#endif
+
 #define TAG "CPM"
 
 #define CA_BUFSIZE 128
@@ -613,7 +618,11 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength)
             SEED = 0;
             return CA_STATUS_FAILED;
         }
+#if HAVE_SRANDOM
         srandom(SEED);
+#else
+        srand(SEED);
+#endif
     }
 
     // memory allocation