SG RFID nRF51822 fork

Fork of nRF51822 by Nordic Semiconductor

Files at this revision

API Documentation at this revision

Comitter:
Rohit Grover
Date:
Tue Nov 04 10:42:27 2014 +0000
Parent:
68:936d81c963fe
Child:
70:d57285f18f65
Commit message:
Release 0.2.2
=============

Features
~~~~~~~~

- Add API Gap::getAddress() to fetch MAC address.
- Add inline assembly for some bootloader specific files to be compiled with arm-gcc.

Bugfixes
~~~~~~~~

none

Compatibility
~~~~~~~~~~~~~

Works with 0.2.0 of BLE_API.

Changed in this revision

nRF51Gap.cpp Show annotated file Show diff for this revision Revisions of this file
nRF51Gap.h Show annotated file Show diff for this revision Revisions of this file
nordic/bootloader_dfu/bootloader_util_arm.c Show annotated file Show diff for this revision Revisions of this file
nordic/nrf-sdk/app_common/app_timer.h Show annotated file Show diff for this revision Revisions of this file
--- a/nRF51Gap.cpp	Fri Sep 26 14:46:19 2014 +0100
+++ b/nRF51Gap.cpp	Tue Nov 04 10:42:27 2014 +0000
@@ -304,7 +304,7 @@
     @endcode
 */
 /**************************************************************************/
-ble_error_t nRF51Gap::setAddress(addr_type_t type, const uint8_t address[6])
+ble_error_t nRF51Gap::setAddress(addr_type_t type, const uint8_t address[ADDR_LEN])
 {
     if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) {
         return BLE_ERROR_PARAM_OUT_OF_RANGE;
@@ -312,13 +312,26 @@
 
     ble_gap_addr_t dev_addr;
     dev_addr.addr_type = type;
-    memcpy(dev_addr.addr, address, 6);
+    memcpy(dev_addr.addr, address, ADDR_LEN);
+
+    ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+    return BLE_ERROR_NONE;
+}
 
-    ASSERT_INT(ERROR_NONE,
-               sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr),
-               BLE_ERROR_PARAM_OUT_OF_RANGE);
+ble_error_t nRF51Gap::getAddress(addr_type_t *typeP, uint8_t addressP[ADDR_LEN])
+{
+    ble_gap_addr_t dev_addr;
+    if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) {
+        return BLE_ERROR_PARAM_OUT_OF_RANGE;
+    }
 
-
+    if (typeP != NULL) {
+        *typeP = static_cast<addr_type_t>(dev_addr.addr_type);
+    }
+    if (addressP != NULL) {
+        memcpy(addressP, dev_addr.addr, ADDR_LEN);
+    }
     return BLE_ERROR_NONE;
 }
 
--- a/nRF51Gap.h	Fri Sep 26 14:46:19 2014 +0100
+++ b/nRF51Gap.h	Tue Nov 04 10:42:27 2014 +0000
@@ -39,10 +39,9 @@
     }
 
     /* Functions that must be implemented from Gap */
-    virtual ble_error_t setAddress(addr_type_t   type,
-                                   const uint8_t address[6]);
-    virtual ble_error_t setAdvertisingData(const GapAdvertisingData &,
-                                           const GapAdvertisingData &);
+    virtual ble_error_t setAddress(addr_type_t  type,  const uint8_t address[ADDR_LEN]);
+    virtual ble_error_t getAddress(addr_type_t *typeP, uint8_t addressP[ADDR_LEN]);
+    virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
     virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
     virtual ble_error_t stopAdvertising(void);
     virtual ble_error_t disconnect(DisconnectionReason_t reason);
--- a/nordic/bootloader_dfu/bootloader_util_arm.c	Fri Sep 26 14:46:19 2014 +0100
+++ b/nordic/bootloader_dfu/bootloader_util_arm.c	Tue Nov 04 10:42:27 2014 +0000
@@ -17,16 +17,17 @@
 /**
  * @brief Function for aborting current handler mode and jump to to other application/bootloader.
  *
- * @details This functions will use the address provide (reset handler) to be executed after 
- *          handler mode is exited. It creates an initial stack to ensure correct reset behavior 
+ * @details This function will use the address provided (reset handler) to be executed after
+ *          handler mode is exited. It creates an initial stack to ensure correct reset behavior
  *          when the reset handler is executed.
  *
  * @param[in]  reset_handler  Address of the reset handler to be executed when handler mode exits.
  *
- * @note This function must never be called directly from 'C' but is intended only to be used from 
- *       \ref bootloader_util_reset. This function will never return but issue a reset into 
+ * @note This function must never be called directly from 'C' but is intended only to be used from
+ *       \ref bootloader_util_reset. This function will never return but issue a reset into
  *       provided address.
  */
+#ifdef TOOLCHAIN_ARM
 __asm void isr_abort(uint32_t reset_handler)
 {
 xPSR_RESET      EQU 0x21000000  ; Default value of xPSR after System Reset.
@@ -37,33 +38,59 @@
     MOV   R6, R0                ; Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR.
     LDR   R7,=xPSR_RESET        ; Move reset value of xPSR to R7. Will be popped as xPSR when exiting ISR.
     PUSH  {r4-r7}               ; Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR.
-    
+
     LDR   R4,=MASK_ZEROS        ; Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers).
     LDR   R5,=MASK_ZEROS        ; Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers).
     LDR   R6,=MASK_ZEROS        ; Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers).
     LDR   R7,=MASK_ZEROS        ; Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers).
     PUSH  {r4-r7}               ; Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine.
-    
+
     LDR   R0,=EXC_RETURN_CMD    ; Load the execution return command into register.
     BX    R0                    ; No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application.
     ALIGN
 }
+#elif defined(TOOLCHAIN_GCC)
+void isr_abort(uint32_t reset_handler)
+{
+    asm(
+        ".equ xPSR_RESET, 0x21000000    \n\t"  /* Default value of xPSR after System Reset.       */
+        ".equ EXC_RETURN_CMD, 0xFFFFFFF9\n\t"  /* EXC_RETURN for ARM Cortex. When loaded to PC the current interrupt
+                                                * service routine (handler mode) willl exit and the stack will be
+                                                * popped. Execution will continue in thread mode. */
 
+        "LDR   R4,=MASK_ONES \n\t" /* Fill with ones before jumping to reset handling. We be popped as R12 when exiting ISR (Cleaning up the registers). */
+        "LDR   R5,=MASK_ONES \n\t" /* Fill with ones before jumping to reset handling. We be popped as LR when exiting ISR. Ensures no return to application. */
+        "MOV   R6, R0        \n\t" /* Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR. */
+        "LDR   R7,=xPSR_RESET\n\t" /* Move reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. */
+        "PUSH  {r4-r7}       \n\t" /* Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR. */
+
+        "LDR   R4,=MASK_ZEROS\n\t" /* Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers). */
+        "LDR   R5,=MASK_ZEROS\n\t" /* Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers). */
+        "LDR   R6,=MASK_ZEROS\n\t" /* Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers). */
+        "LDR   R7,=MASK_ZEROS\n\t" /* Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers). */
+        "PUSH  {r4-r7}       \n\t" /* Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine. */
+
+        "LDR   R0,=EXC_RETURN_CMD\n\t" /* Load the execution return command into register. */
+        "BX    R0                \n\t" /* No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application. */
+        );
+}
+#endif /* TOOLCHAIN_ARM */
 
 /**
  * @brief Function for aborting current application/bootloader jump to to other app/bootloader.
  *
- * @details This functions will use the address provide to swap the stack pointer and then load 
- *          the address of the reset handler to be executed. It will check current system mode 
+ * @details This function will use the address provided to swap the stack pointer and then load
+ *          the address of the reset handler to be executed. It will check current system mode
  *          (thread/handler) and if in thread mode it will reset into other application.
- *          If in handler mode \ref isr_abort will be executed to ensure correct exit of handler 
+ *          If in handler mode \ref isr_abort will be executed to ensure correct exit of handler
  *          mode and jump into reset handler of other application.
  *
- * @param[in]  start_addr  Start address of other application. This address must point to the 
+ * @param[in]  start_addr  Start address of other application. This address must point to the
                initial stack pointer of the application.
  *
  * @note This function will never return but issue a reset into provided application.
  */
+#ifdef TOOLCHAIN_ARM
 __asm static void bootloader_util_reset(uint32_t start_addr)
 {
 MASK_ONES       EQU 0xFFFFFFFF  ; Ones, to be loaded into register as default value before reset.
@@ -72,9 +99,9 @@
     LDR   R1, [R0]              ; Get App initial MSP for bootloader.
     MSR   MSP, R1               ; Set the main stack pointer to the applications MSP.
     LDR   R0,[R0, #0x04]        ; Load Reset handler into register 0.
-    
+
     LDR   R2, =MASK_ZEROS       ; Load zeros to R2
-    MRS   R3, IPSR              ; Load IPSR to R3 to check for handler or thread mode 
+    MRS   R3, IPSR              ; Load IPSR to R3 to check for handler or thread mode
     CMP   R2, R3                ; Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader
     BNE   isr_abort             ; If not zero we need to exit current ISR and jump to reset handler of bootloader
 
@@ -83,7 +110,31 @@
     BX    R0                    ; Branch to reset handler of bootloader
     ALIGN
 }
+#elif defined(TOOLCHAIN_GCC)
+static void bootloader_util_reset(uint32_t start_addr)
+{
+    asm(
+        ".equ MASK_ONES,  0xFFFFFFFF\n\t" /* Ones, to be loaded into register as default value before reset.  */
+        ".equ MASK_ZEROS, 0x00000000\n\t" /* Zeros, to be loaded into register as default value before reset. */
 
+        "LDR   r1, [r0]       \n\t"       /* Get App initial MSP for bootloader.                              */
+        "MSR   MSP, r1        \n\t"       /* Set the main stack pointer to the applications MSP.              */
+        "LDR   r0,[r0, #0x04] \n\t"       /* Load Reset handler into register 0.                              */
+
+        "LDR   r2, =MASK_ZEROS\n\t"       /* Load zeros to R2                                                 */
+        "MRS   r3, IPSR       \n\t"       /* Load IPSR to R3 to check for handler or thread mode              */
+        "CMP   r2, r3         \n\t"       /* Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader */
+        "BNE   isr_abort      \n\t"       /* If not zero we need to exit current ISR and jump to reset handler of bootloader */
+
+        "LDR   r4, =MASK_ONES \n\t"       /* Load ones to R4 to be placed in Link Register.                   */
+        "MOV   LR, r4         \n\t"       /* Clear the link register and set to ones to ensure no return.     */
+        "BX    r0             \n\t"       /* Branch to reset handler of bootloader                            */
+        : /* output operands */
+        : /* input operands */
+        : "r0", "r1", "r2", "r3", "r4" /* clobber list */
+        );
+}
+#endif /* TOOLCHAIN_ARM */
 
 void bootloader_util_app_start(uint32_t start_addr)
 {
--- a/nordic/nrf-sdk/app_common/app_timer.h	Fri Sep 26 14:46:19 2014 +0100
+++ b/nordic/nrf-sdk/app_common/app_timer.h	Tue Nov 04 10:42:27 2014 +0000
@@ -19,7 +19,7 @@
  * @brief Application timer functionality.
  *
  * @details It enables the application to create multiple timer instances based on the RTC1
- *          peripheral. Checking for timeouts and invokation of user timeout handlers is performed
+ *          peripheral. Checking for timeouts and invocation of user timeout handlers is performed
  *          in the RTC1 interrupt handler. List handling is done using a software interrupt (SWI0).
  *          Both interrupt handlers are running in APP_LOW priority level.
  *
@@ -91,9 +91,9 @@
  *
  * @param[in]  MS          Milliseconds.
  * @param[in]  PRESCALER   Value of the RTC1 PRESCALER register (must be the same value that was
- *                         passed to APP_TIMER_INIT()). 
- * 
- * @note   When using this macro, it is the responsibility of the developer to ensure that the 
+ *                         passed to APP_TIMER_INIT()).
+ *
+ * @note   When using this macro, it is the responsibility of the developer to ensure that the
  *         values provided as input result in an output value that is supported by the
  *         @ref app_timer_start function. For example, when the ticks for 1 ms is needed, the
  *         maximum possible value of PRESCALER must be 6, when @ref APP_TIMER_CLOCK_FREQ is 32768.
@@ -130,11 +130,11 @@
  *          making sure that the buffer is correctly aligned. It will also connect the timer module
  *          to the scheduler (if specified).
  *
- * @note    This module assumes that the LFCLK is already running. If it isn't, the module will 
- *          be non-functional, since the RTC will not run. If you don't use a softdevice, you'll 
- *          have to start the LFCLK manually. See the rtc_example's \ref lfclk_config() function 
- *          for an example of how to do this. If you use a softdevice, the LFCLK is started on 
- *          softdevice init. 
+ * @note    This module assumes that the LFCLK is already running. If it isn't, the module will
+ *          be non-functional, since the RTC will not run. If you don't use a softdevice, you'll
+ *          have to start the LFCLK manually. See the rtc_example's \ref lfclk_config() function
+ *          for an example of how to do this. If you use a softdevice, the LFCLK is started on
+ *          softdevice init.
  *
  *
  * @param[in]  PRESCALER        Value of the RTC1 PRESCALER register. This will decide the
@@ -186,7 +186,7 @@
  * @retval     NRF_ERROR_INVALID_PARAM   Invalid parameter (buffer not aligned to a 4 byte
  *                                       boundary or NULL).
  */
-uint32_t app_timer_init(uint32_t                      prescaler, 
+uint32_t app_timer_init(uint32_t                      prescaler,
                         uint8_t                       max_timers,
                         uint8_t                       op_queues_size,
                         void *                        p_buffer,
@@ -287,7 +287,7 @@
 static __INLINE void app_timer_evt_get(void * p_event_data, uint16_t event_size)
 {
     app_timer_event_t * p_timer_event = (app_timer_event_t *)p_event_data;
-    
+
     APP_ERROR_CHECK_BOOL(event_size == sizeof(app_timer_event_t));
     p_timer_event->timeout_handler(p_timer_event->p_context);
 }
@@ -299,7 +299,7 @@
 
     timer_event.timeout_handler = timeout_handler;
     timer_event.p_context       = p_context;
-    
+
     return app_sched_event_put(&timer_event, sizeof(timer_event), app_timer_evt_get);
 }
 /**@endcond */