BLE test

Fork of X_NUCLEO_IDB0XA1 by ST

Revision:
130:770ce14d3d15
Child:
132:51056160fa4a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/BlueNRGDevice.cpp	Tue Oct 06 14:25:08 2015 +0200
@@ -0,0 +1,400 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* 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.
+*/
+
+/**
+  ******************************************************************************
+  * @file    BlueNRGDevice.cpp 
+  * @author  STMicroelectronics
+  * @brief   Implementation of BLEDeviceInstanceBase
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  */ 
+  
+/** @defgroup BlueNRGDevice
+ *  @brief BlueNRG BLE_API Device Adaptation
+ *  @{
+ */
+ 
+#include "mbed.h"
+#include "BlueNRGDevice.h"
+#include "BlueNRGGap.h"
+#include "BlueNRGGattServer.h"
+
+#include "btle.h"
+#include "Utils.h"
+#include "osal.h"
+
+#include "debug.h"
+#include "stm32_bluenrg_ble.h"
+
+extern "C" {
+    #include "hci.h"
+}
+
+#define HEADER_SIZE 5
+#define MAX_BUFFER_SIZE 255
+
+/**
+ * The singleton which represents the BlueNRG transport for the BLEDevice.
+ *
+ * See file 'x_nucleo_idb0xa1_targets.h' for details regarding the peripheral pins used!
+ */
+#include "x_nucleo_idb0xa1_targets.h"
+
+BlueNRGDevice bluenrgDeviceInstance(IDB0XA1_PIN_SPI_MOSI,
+                                    IDB0XA1_PIN_SPI_MISO,
+                                    IDB0XA1_PIN_SPI_SCK,
+                                    IDB0XA1_PIN_SPI_nCS,
+                                    IDB0XA1_PIN_SPI_RESET,
+                                    IDB0XA1_PIN_SPI_IRQ);
+
+/**
+* BLE-API requires an implementation of the following function in order to
+* obtain its transport handle.
+*/
+BLEInstanceBase *
+createBLEInstance(void)
+{
+    return (&bluenrgDeviceInstance);
+}
+
+/**************************************************************************/
+/**
+    @brief  Constructor
+     * @param mosi mbed pin to use for MOSI line of SPI interface
+     * @param miso mbed pin to use for MISO line of SPI interface
+     * @param sck mbed pin to use for SCK line of SPI interface
+     * @param cs mbed pin to use for not chip select line of SPI interface
+     * @param rst mbed pin to use for BlueNRG reset
+     * @param irq mbed pin for BlueNRG IRQ
+*/
+/**************************************************************************/
+BlueNRGDevice::BlueNRGDevice(PinName mosi,
+                             PinName miso,
+                             PinName sck,
+                             PinName cs,
+                             PinName rst,
+                             PinName irq) : spi_(mosi, miso, sck), nCS_(cs), rst_(rst), irq_(irq)
+{
+    isInitialized = false;
+	
+    // Setup the spi for 8 bit data, low clock polarity,
+    // 1-edge phase, with an 8MHz clock rate
+    spi_.format(8, 0);
+    spi_.frequency(8000000);
+	
+    // Deselect the BlueNRG chip by keeping its nCS signal high
+    nCS_ = 1;
+
+    wait_us(500);
+}
+
+/**************************************************************************/
+/**
+    @brief  Destructor
+*/
+/**************************************************************************/
+BlueNRGDevice::~BlueNRGDevice(void)
+{
+}
+
+
+/**
+    @brief  Initialises anything required to start using BLE
+    @param[in] void
+    @returns    ble_error_t
+*/
+ble_error_t BlueNRGDevice::init(void)
+{
+	// Set the interrupt handler for the device
+	irq_.mode(PullNone); // betzw: set irq mode
+	irq_.rise(&HCI_Isr);
+
+	/* ToDo: Clear memory contents, reset the SD, etc. */
+	btle_init(BlueNRGGap::getInstance().getIsSetAddress());
+	
+	isInitialized = true;
+    
+	return BLE_ERROR_NONE;
+}
+
+
+/**
+    @brief  Resets the BLE HW, removing any existing services and
+            characteristics
+    @param[in] void
+    @returns    ble_error_t
+*/
+ble_error_t BlueNRGDevice::reset(void)
+{
+    wait_us(500);
+
+    /* Reset BlueNRG SPI interface */
+	  rst_ = 0;
+  	wait_us(5);
+	  rst_ = 1;
+  	wait_us(5);
+
+    /* Wait for the radio to come back up */
+    wait_us(500);
+    
+    isInitialized = false;
+
+    return BLE_ERROR_NONE;
+}
+
+
+/*!
+  @brief  Wait for any BLE Event like BLE Connection, Read Request etc.    
+  @param[in] void
+  @returns    char *      
+*/
+void BlueNRGDevice::waitForEvent(void)
+{
+	bool must_return = false;
+
+	do {
+		BlueNRGGap::getInstance().Process();
+		
+		HCI_Process();
+		
+		if(must_return) return;
+
+		__WFE(); /* it is recommended that SEVONPEND in the
+			    System Control Register is NOT set */
+		must_return = true; /* after returning from WFE we must guarantee
+				       that conrol is given back to main loop before next WFE */
+	} while(true);
+
+}
+ 
+ 
+/*!
+    @brief  get GAP version
+    @param[in] void
+    @returns    char *
+*/
+const char *BlueNRGDevice::getVersion(void)
+{
+    char *version = new char[6];
+    memcpy((void *)version, "1.0.0", 5);
+    return version;
+}
+
+/**************************************************************************/
+/*!
+    @brief  get init state
+    @param[in] void
+    @returns    bool  
+*/
+/**************************************************************************/
+bool BlueNRGDevice::getIsInitialized(void)
+{
+    return isInitialized;
+}
+
+/**************************************************************************/
+/*!
+    @brief  get reference to GAP object
+    @param[in] void
+    @returns    Gap&      
+*/
+/**************************************************************************/
+Gap        &BlueNRGDevice::getGap()        
+{
+    return BlueNRGGap::getInstance();
+}
+
+const Gap  &BlueNRGDevice::getGap() const        
+{
+    return BlueNRGGap::getInstance();
+}
+
+/**************************************************************************/
+/*!
+    @brief  get reference to GATT server object
+    @param[in] void
+    @returns    GattServer&    
+*/
+/**************************************************************************/
+GattServer &BlueNRGDevice::getGattServer() 
+{
+    return BlueNRGGattServer::getInstance();
+}
+
+const GattServer &BlueNRGDevice::getGattServer() const
+{
+    return BlueNRGGattServer::getInstance();
+}
+ 
+/**************************************************************************/
+/*!
+    @brief  shut down the the BLE device
+    @param[out] error if any
+*/
+/**************************************************************************/
+ble_error_t  BlueNRGDevice::shutdown(void) {
+    return reset();
+}
+																							
+/**
+ * @brief  Reads from BlueNRG SPI buffer and store data into local buffer.
+ * @param  buffer   : Buffer where data from SPI are stored
+ * @param  buff_size: Buffer size
+ * @retval int32_t  : Number of read bytes
+ */
+int32_t BlueNRGDevice::spiRead(uint8_t *buffer, uint8_t buff_size)
+{
+  uint16_t byte_count;
+  uint8_t len = 0;
+  uint8_t char_ff = 0xff;
+  volatile uint8_t read_char;
+	
+	uint8_t i = 0;
+	volatile uint8_t tmpreg;
+
+  uint8_t header_master[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
+  uint8_t header_slave[HEADER_SIZE];
+
+  /* Select the chip */
+  nCS_ = 0;
+	
+  /* Read the header */  
+  for (i = 0; i < 5; i++)
+  { 
+		tmpreg = spi_.write(header_master[i]);
+		header_slave[i] = (uint8_t)(tmpreg);
+  } 
+	
+  if (header_slave[0] == 0x02) {
+    /* device is ready */
+    byte_count = (header_slave[4]<<8)|header_slave[3];
+  
+    if (byte_count > 0) {
+  
+      /* avoid to read more data that size of the buffer */
+      if (byte_count > buff_size){
+        byte_count = buff_size;
+      }
+  
+      for (len = 0; len < byte_count; len++){
+        read_char = spi_.write(char_ff);
+				buffer[len] = read_char;
+      }
+    }    
+  }
+  /* Release CS line to deselect the chip */
+  nCS_ = 1;
+	
+  // Add a small delay to give time to the BlueNRG to set the IRQ pin low
+  // to avoid a useless SPI read at the end of the transaction
+  for(volatile int i = 0; i < 2; i++)__NOP();
+  
+#ifdef PRINT_CSV_FORMAT
+  if (len > 0) {
+    print_csv_time();
+    for (int i=0; i<len; i++) {
+      PRINT_CSV(" %02x", buffer[i]);
+    }
+    PRINT_CSV("\n");
+  }
+#endif
+  
+  return len;   
+}
+
+/**
+ * @brief  Writes data from local buffer to SPI.
+ * @param  data1    : First data buffer to be written
+ * @param  data2    : Second data buffer to be written
+ * @param  Nb_bytes1: Size of first data buffer to be written
+ * @param  Nb_bytes2: Size of second data buffer to be written
+ * @retval Number of read bytes
+ */
+int32_t BlueNRGDevice::spiWrite(uint8_t* data1,
+				uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2)
+{  
+	int32_t result = 0;
+	uint32_t i;
+	volatile uint8_t tmpreg;
+    
+  unsigned char header_master[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
+  unsigned char header_slave[HEADER_SIZE]  = {0xaa, 0x00, 0x00, 0x00, 0x00};
+
+  disable_irq();
+
+  /* CS reset */
+  nCS_ = 0;
+
+  /* Exchange header */  
+  for (i = 0; i < 5; i++)
+  { 
+		tmpreg = spi_.write(header_master[i]);
+		header_slave[i] = tmpreg;
+  } 
+	
+  if (header_slave[0] == 0x02) {
+    /* SPI is ready */
+    if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) {
+  
+      /*  Buffer is big enough */
+			for (i = 0; i < Nb_bytes1; i++) {
+				spi_.write(*(data1 + i));
+      }
+      for (i = 0; i < Nb_bytes2; i++) {
+				spi_.write(*(data2 + i));
+      }			
+    } else {
+      /* Buffer is too small */
+      result = -2;
+    }
+  } else {
+    /* SPI is not ready */
+    result = -1;
+  }
+    
+  /* Release CS line */
+  //HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
+  nCS_ = 1;
+			
+  enable_irq();
+    
+  return result;
+}
+
+bool BlueNRGDevice::dataPresent()
+{
+    return (irq_ == 1);
+}
+
+void BlueNRGDevice::disable_irq()
+{
+    irq_.disable_irq();
+}
+
+void BlueNRGDevice::enable_irq()
+{
+    irq_.enable_irq();
+}