summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile14
-rw-r--r--fiken_status_panel.ino330
-rw-r--r--fiken_status_panel.xml116
-rw-r--r--services.h154
4 files changed, 614 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..03e0b0f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+BOARD_TAG = leonardo
+#BOARD_TAG = blendmicro16
+#DEVICE_PORT = /dev/ttyACM0
+MONITOR_BAUDRATE = 115200
+MONITOR_PORT ?= /dev/ttyACM0
+
+ARDUINO_LIBS = BLE SPI
+
+ARDMK_DIR ?= /usr/share/arduino
+include $(ARDMK_DIR)/Arduino.mk
+
+#/usr/share/arduino/hardware/tools/avr/bin/avr-g++ -x c++ -include Arduino.h -MMD -c -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=105 -D__PROG_TYPES_COMPAT__ -I. -I/usr/share/arduino/hardware/arduino/cores/arduino -I/usr/share/arduino/hardware/arduino/variants/leonardo -I/usr/share/arduino/libraries/SPI -I/home/trygvis/sketchbook/libraries/BLE -Wall -ffunction-sections -fdata-sections -Os -DUSB_VID=0x2341 -DUSB_PID=0x8036 -fno-exceptions bitraf_door.ino -o build-leonardo/bitraf_door.o
+
+#/home/trygvis/opt/arduino-1.0.5/hardware/tools/avr/bin/avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega32u4 -DF_CPU=8000000L -MMD -DUSB_VID=0x03EB -DUSB_PID=0x2404 -DARDUINO=105 -I/home/trygvis/opt/arduino-1.0.5/hardware/arduino/cores/arduino -I/home/trygvis/sketchbook/hardware/blend/variants/BlendMicro-8MHz -I/home/trygvis/opt/arduino-1.0.5/libraries/SPI -I/home/trygvis/sketchbook/libraries/BLE /tmp/build8653612679895592527.tmp/bitraf_door.cpp -o /tmp/build8653612679895592527.tmp/bitraf_door.cpp.o
diff --git a/fiken_status_panel.ino b/fiken_status_panel.ino
new file mode 100644
index 0000000..6283201
--- /dev/null
+++ b/fiken_status_panel.ino
@@ -0,0 +1,330 @@
+#include <SPI.h>
+#include <lib_aci.h>
+#include <aci_setup.h>
+
+#include "services.h"
+
+static services_pipe_type_mapping_t services_pipe_type_mapping[NUMBER_OF_PIPES] = SERVICES_PIPE_TYPE_MAPPING_CONTENT;
+static hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] PROGMEM = SETUP_MESSAGES_CONTENT;
+
+static struct aci_state_t aci_state;
+static hal_aci_evt_t aci_data;
+static bool timing_change_done = false;
+
+void __ble_assert(const char *file, uint16_t line)
+{
+ Serial.print("ERROR ");
+ Serial.print(file);
+ Serial.print(": ");
+ Serial.print(line);
+ Serial.print("\n");
+ while(1);
+}
+
+void setup() {
+#if defined(BLEND_MICRO_8MHZ)
+ // As the F_CPU = 8000000UL, the USB core make the PLLCSR = 0x02
+ // But the external xtal is 16000000Hz, so correct it here.
+ PLLCSR |= 0x10; // Need 16 MHz xtal
+ while (!(PLLCSR & (1<<PLOCK))); // wait for lock pll
+#elif defined(BLEND_MICRO_16MHZ)
+ // The CPU clock in bootloader is 8MHz, change to 16MHz for sketches to run (i.e. overclock running at 3.3v).
+ CLKPR = 0x80;
+ CLKPR = 0;
+#endif
+
+ Serial.begin((unsigned int)115200);
+
+ //Wait until the serial port is available (useful only for the Leonardo)
+ //As the Leonardo board is not reseted every time you open the Serial Monitor
+ #if defined (__AVR_ATmega32U4__)
+ while(!Serial) {}
+ #elif defined(__PIC32MX__)
+ delay(1000);
+ #endif
+
+ Serial.println(F("setup()"));
+
+ // Point ACI data structures to the the setup data that the nRFgo studio generated for the nRF8001
+ if (NULL != services_pipe_type_mapping) {
+ aci_state.aci_setup_info.services_pipe_type_mapping = &services_pipe_type_mapping[0];
+ }
+ else {
+ aci_state.aci_setup_info.services_pipe_type_mapping = NULL;
+ }
+ aci_state.aci_setup_info.number_of_pipes = NUMBER_OF_PIPES;
+ aci_state.aci_setup_info.setup_msgs = (hal_aci_data_t*)setup_msgs;
+ aci_state.aci_setup_info.num_setup_msgs = NB_SETUP_MESSAGES;
+
+ /*
+ Tell the ACI library, the MCU to nRF8001 pin connections.
+ The Active pin is optional and can be marked UNUSED
+ */
+ aci_state.aci_pins.board_name = REDBEARLAB_SHIELD_V2;
+ aci_state.aci_pins.reqn_pin = 6;
+ aci_state.aci_pins.rdyn_pin = 7;
+ aci_state.aci_pins.mosi_pin = MOSI;
+ aci_state.aci_pins.miso_pin = MISO;
+ aci_state.aci_pins.sck_pin = SCK;
+
+ aci_state.aci_pins.spi_clock_divider = SPI_CLOCK_DIV8;//SPI_CLOCK_DIV8 = 2MHz SPI speed
+ //SPI_CLOCK_DIV16 = 1MHz SPI speed
+
+ aci_state.aci_pins.reset_pin = UNUSED; //4 for Nordic board, UNUSED for REDBEARLAB_SHIELD_V1_1
+ aci_state.aci_pins.active_pin = UNUSED;
+ aci_state.aci_pins.optional_chip_sel_pin = UNUSED;
+
+ aci_state.aci_pins.interface_is_interrupt = false; //Interrupts still not available in Chipkit
+ aci_state.aci_pins.interrupt_number = 4;
+
+ //We reset the nRF8001 here by toggling the RESET line connected to the nRF8001
+ //If the RESET line is not available we call the ACI Radio Reset to soft reset the nRF8001
+ //then we initialize the data structures required to setup the nRF8001
+ //The second parameter is for turning debug printing on for the ACI Commands and Events so they be printed on the Serial
+ lib_aci_init(&aci_state, false);
+ Serial.println(F("lib_aci_init done"));
+}
+
+static bool setup_required = false;
+
+static void aci_loop() {
+ // We enter the if statement only when there is a ACI event available to be processed
+ if (lib_aci_event_get(&aci_state, &aci_data)) {
+ aci_evt_t * aci_evt;
+ aci_evt = &aci_data.evt;
+
+ switch(aci_evt->evt_opcode) {
+ /**
+ As soon as you reset the nRF8001 you will get an ACI Device Started Event
+ */
+ case ACI_EVT_DEVICE_STARTED:
+ Serial.println(F("ACI_EVT_DEVICE_STARTED"));
+ aci_state.data_credit_total = aci_evt->params.device_started.credit_available;
+ switch(aci_evt->params.device_started.device_mode) {
+ case ACI_DEVICE_SETUP:
+ Serial.println(F("ACI_DEVICE_SETUP"));
+ setup_required = true;
+ break;
+
+ case ACI_DEVICE_STANDBY:
+ Serial.println(F("ACI_DEVICE_STANDBY"));
+ //Looking for an iPhone by sending radio advertisements
+ //When an iPhone connects to us we will get an ACI_EVT_CONNECTED event from the nRF8001
+ if (aci_evt->params.device_started.hw_error) {
+ delay(20); //Magic number used to make sure the HW error event is handled correctly.
+ }
+ else {
+ lib_aci_connect(180/* in seconds */, 0x0050 /* advertising interval 50ms*/);
+ Serial.println(F("Advertising started"));
+ }
+ break;
+ case ACI_DEVICE_INVALID:
+ case ACI_DEVICE_TEST:
+ case ACI_DEVICE_SLEEP:
+ // ignored
+ break;
+ }
+ break;
+
+ case ACI_EVT_CMD_RSP:
+// Serial.println(F("ACI_EVT_CMD_RSP"));
+// Serial.print(F("aci_evt->params.cmd_rsp.cmd_opcode="));
+// Serial.println(aci_evt->params.cmd_rsp.cmd_opcode, HEX);
+// Serial.print(F("aci_evt->params.cmd_rsp.cmd_status="));
+// Serial.println(aci_evt->params.cmd_rsp.cmd_status, HEX);
+
+ //If an ACI command response event comes with an error -> stop
+ if (aci_evt->params.cmd_rsp.cmd_status != ACI_STATUS_SUCCESS) {
+ //ACI ReadDynamicData and ACI WriteDynamicData will have status codes of
+ //TRANSACTION_CONTINUE and TRANSACTION_COMPLETE
+ //all other ACI commands will have status code of ACI_STATUS_SCUCCESS for a successful command//
+// Serial.print(F("ACI Command "));
+// Serial.println(aci_evt->params.cmd_rsp.cmd_opcode, HEX);
+// Serial.print(F("Evt Cmd respone: Status "));
+// Serial.println(aci_evt->params.cmd_rsp.cmd_status, HEX);
+ }
+ if (aci_evt->params.cmd_rsp.cmd_opcode == ACI_CMD_GET_DEVICE_VERSION) {
+ //Store the version and configuration information of the nRF8001 in the Hardware Revision String Characteristic
+// lib_aci_set_local_data(&aci_state, PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET,
+// (uint8_t *)&(aci_evt->params.cmd_rsp.params.get_device_version),
+// sizeof(aci_evt_cmd_rsp_params_get_device_version_t));
+ }
+ break;
+
+ case ACI_EVT_CONNECTED:
+ Serial.println(F("ACI_EVT_CONNECTED"));
+// uart_over_ble_init();
+ timing_change_done = false;
+ aci_state.data_credit_available = aci_state.data_credit_total;
+
+ // Get the device version of the nRF8001 and store it in the Hardware Revision String
+ lib_aci_device_version();
+ break;
+
+ case ACI_EVT_PIPE_STATUS:
+ Serial.println(F("ACI_EVT_PIPE_STATUS"));
+ /*
+ if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX) && (false == timing_change_done))
+ {
+ lib_aci_change_timing_GAP_PPCP(); // change the timing on the link as specified in the nRFgo studio -> nRF8001 conf. -> GAP.
+ // Used to increase or decrease bandwidth
+ timing_change_done = true;
+ }
+ */
+ break;
+
+ case ACI_EVT_TIMING:
+ Serial.println(F("ACI_EVT_TIMING"));
+// lib_aci_set_local_data(&aci_state,
+// PIPE_UART_OVER_BTLE_UART_LINK_TIMING_CURRENT_SET,
+// (uint8_t *)&(aci_evt->params.timing.conn_rf_interval), /* Byte aligned */
+// PIPE_UART_OVER_BTLE_UART_LINK_TIMING_CURRENT_SET_MAX_SIZE);
+ break;
+
+ case ACI_EVT_DISCONNECTED:
+ Serial.println(F("ACI_EVT_DISCONNECTED"));
+ lib_aci_connect(180/* in seconds */, 0x0100 /* advertising interval 100ms*/);
+ Serial.println(F("Advertising started"));
+ break;
+
+ case ACI_EVT_DATA_RECEIVED:
+ Serial.print(F("ACI_EVT_DATA_RECEIVED: pipe_number="));
+ Serial.println(aci_evt->params.data_received.rx_data.pipe_number, DEC);
+ if (aci_evt->params.data_received.rx_data.pipe_number == PIPE_FIKEN_STATUS_PANEL_GAUGE_RX_ACK) {
+ if (aci_evt->len != PIPE_FIKEN_STATUS_PANEL_GAUGE_RX_ACK_MAX_SIZE) {
+ break;
+ }
+ set_gauge_req(aci_evt->params.data_received.rx_data.aci_data);
+ lib_aci_send_ack(&aci_state, PIPE_FIKEN_STATUS_PANEL_GAUGE_RX_ACK);
+ }
+ /*
+ if (PIPE_UART_OVER_BTLE_UART_RX_RX == aci_evt->params.data_received.rx_data.pipe_number)
+ {
+ Serial.print(F(" Data(Hex) : "));
+ for(int i=0; i<aci_evt->len - 2; i++)
+ {
+ Serial.print((char)aci_evt->params.data_received.rx_data.aci_data[i]);
+ uart_buffer[i] = aci_evt->params.data_received.rx_data.aci_data[i];
+ Serial.print(F(" "));
+ }
+
+ uart_buffer_len = aci_evt->len - 2;
+ Serial.println(F(""));
+ if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX))
+ {
+ }
+ }
+ if (PIPE_UART_OVER_BTLE_UART_CONTROL_POINT_RX == aci_evt->params.data_received.rx_data.pipe_number)
+ {
+ uart_process_control_point_rx(&aci_evt->params.data_received.rx_data.aci_data[0], aci_evt->len - 2); //Subtract for Opcode and Pipe number
+ }
+ */
+ break;
+
+ case ACI_EVT_DATA_CREDIT:
+ Serial.println(F("ACI_EVT_DATA_CREDIT"));
+ aci_state.data_credit_available = aci_state.data_credit_available + aci_evt->params.data_credit.credit;
+ break;
+
+ case ACI_EVT_PIPE_ERROR:
+ Serial.println(F("ACI_EVT_PIPE_ERROR"));
+ //See the appendix in the nRF8001 Product Specication for details on the error codes
+ Serial.print(F("ACI Evt Pipe Error: Pipe #:"));
+ Serial.print(aci_evt->params.pipe_error.pipe_number, DEC);
+ Serial.print(F(" Pipe Error Code: 0x"));
+ Serial.println(aci_evt->params.pipe_error.error_code, HEX);
+
+ //Increment the credit available as the data packet was not sent.
+ //The pipe error also represents the Attribute protocol Error Response sent from the peer and that should not be counted
+ //for the credit.
+ if (ACI_STATUS_ERROR_PEER_ATT_ERROR != aci_evt->params.pipe_error.error_code)
+ {
+ aci_state.data_credit_available++;
+ }
+ break;
+
+ case ACI_EVT_HW_ERROR:
+ Serial.println(F("ACI_EVT_HW_ERROR"));
+ Serial.print(F("HW error: "));
+ Serial.println(aci_evt->params.hw_error.line_num, DEC);
+
+ for(uint8_t counter = 0; counter <= (aci_evt->len - 3); counter++)
+ {
+ Serial.write(aci_evt->params.hw_error.file_name[counter]); //uint8_t file_name[20];
+ }
+ Serial.println();
+ lib_aci_connect(180/* in seconds */, 0x0050 /* advertising interval 50ms*/);
+ Serial.println(F("Advertising started"));
+ break;
+
+ case ACI_EVT_INVALID:
+ Serial.println(F("ACI_EVT_INVALID"));
+ break;
+ case ACI_EVT_ECHO:
+ Serial.println(F("ACI_EVT_ECHO"));
+ break;
+ case ACI_EVT_BOND_STATUS:
+ Serial.println(F("ACI_EVT_BOND_STATUS"));
+ break;
+ case ACI_EVT_DATA_ACK:
+ Serial.println(F("ACI_EVT_DATA_ACK"));
+ break;
+ case ACI_EVT_DISPLAY_PASSKEY:
+ Serial.println(F("ACI_EVT_DISPLAY_PASSKEY"));
+ break;
+ case ACI_EVT_KEY_REQUEST:
+ Serial.println(F("ACI_EVT_KEY_REQUEST"));
+ break;
+ }
+ }
+ else {
+// Serial.println(F("No ACI Events available"));
+ // No event in the ACI Event queue and if there is no event in the ACI command queue the arduino can go to sleep
+ // Arduino can go to sleep now
+ // Wakeup from sleep from the RDYN line
+ }
+
+ /* setup_required is set to true when the device starts up and enters setup mode.
+ * It indicates that do_aci_setup() should be called. The flag should be cleared if
+ * do_aci_setup() returns ACI_STATUS_TRANSACTION_COMPLETE.
+ */
+ if (setup_required) {
+ int ret = do_aci_setup(&aci_state);
+// Serial.print(F("ret="));
+// Serial.println(ret, DEC);
+ if (SETUP_SUCCESS == ret) {
+ setup_required = false;
+ }
+ }
+}
+
+void set_gauge_req(uint8_t *data) {
+ Serial.print(F("set_gauge_req, channel="));
+ Serial.print(data[0], DEC);
+ Serial.print(F(", value="));
+ Serial.println(data[1], DEC);
+}
+
+static uint8_t value = 0;
+void loop() {
+ static unsigned long last = 0, now;
+
+ //Process any ACI commands or events
+ aci_loop();
+
+ if (Serial.available()) {
+ Serial.write(Serial.read());
+ }
+
+ if (!setup_required) {
+ now = millis();
+ if (now - last > 3000) {
+ value++;
+ lib_aci_set_local_data(&aci_state, PIPE_FIKEN_STATUS_PANEL_GAUGE_SET, &value, 1);
+ last = now;
+ Serial.print(F("value="));
+ Serial.println(value, DEC);
+ }
+ }
+}
+
diff --git a/fiken_status_panel.xml b/fiken_status_panel.xml
new file mode 100644
index 0000000..d86c69f
--- /dev/null
+++ b/fiken_status_panel.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE AttributeServer>
+<Profile Version="1.3">
+ <SetupId>1</SetupId>
+ <Device>nRF8001_Dx</Device>
+ <Service Type="local" PrimaryService="true">
+ <Name>Fiken Status Panel</Name>
+ <Uuid BaseUUID="32D00000035D59C570D3BC8E4A1FD83F" BaseUUIDName="trygvis.io">0001</Uuid>
+ <Characteristic>
+ <Name>Gauge</Name>
+ <Uuid BaseUUID="32D00000035D59C570D3BC8E4A1FD83F" BaseUUIDName="trygvis.io">0002</Uuid>
+ <DefaultValue>1234</DefaultValue>
+ <UsePresentationFormat>0</UsePresentationFormat>
+ <MaxDataLength>2</MaxDataLength>
+ <AttributeLenType>1</AttributeLenType>
+ <ForceOpen>false</ForceOpen>
+ <ForceEncryption>false</ForceEncryption>
+ <Properties>
+ <WriteWithoutResponse>false</WriteWithoutResponse>
+ <Write>true</Write>
+ <Notify>false</Notify>
+ <Indicate>false</Indicate>
+ <Broadcast>false</Broadcast>
+ </Properties>
+ <SetPipe>true</SetPipe>
+ <AckIsAuto>false</AckIsAuto>
+ <PresentationFormatDescriptor Value="0000" Exponent="0" Format="4" NameSpace="01" Unit="0000"/>
+ <PeriodForReadingThisCharacteristic>0</PeriodForReadingThisCharacteristic>
+ <PeriodForProperties/>
+ </Characteristic>
+ <Characteristic>
+ <Name>Led</Name>
+ <Uuid BaseUUID="32D00000035D59C570D3BC8E4A1FD83F" BaseUUIDName="trygvis.io">0003</Uuid>
+ <DefaultValue>0</DefaultValue>
+ <UsePresentationFormat>0</UsePresentationFormat>
+ <MaxDataLength>3</MaxDataLength>
+ <AttributeLenType>1</AttributeLenType>
+ <ForceOpen>false</ForceOpen>
+ <ForceEncryption>false</ForceEncryption>
+ <Properties>
+ <WriteWithoutResponse>false</WriteWithoutResponse>
+ <Write>true</Write>
+ <Notify>false</Notify>
+ <Indicate>false</Indicate>
+ <Broadcast>false</Broadcast>
+ </Properties>
+ <SetPipe>false</SetPipe>
+ <AckIsAuto>false</AckIsAuto>
+ <PresentationFormatDescriptor Value="0000" Exponent="0" Format="4" NameSpace="01" Unit="0000"/>
+ <PeriodForReadingThisCharacteristic>0</PeriodForReadingThisCharacteristic>
+ <PeriodForProperties/>
+ </Characteristic>
+ </Service>
+ <Gapsettings>
+ <Name>Fiken Display</Name>
+ <DeviceNameWriteLength>13</DeviceNameWriteLength>
+ <LocalPipeOnDeviceName>true</LocalPipeOnDeviceName>
+ <DeviceNameShortLength>0</DeviceNameShortLength>
+ <Apperance>0000</Apperance>
+ <SecurityLevel>0</SecurityLevel>
+ <AuthenticationReq>0</AuthenticationReq>
+ <IoCapabilities>0</IoCapabilities>
+ <BondTimeout>600</BondTimeout>
+ <SecurityRequestDelay>10</SecurityRequestDelay>
+ <MinimumKeySize>7</MinimumKeySize>
+ <MaximumKeySize>16</MaximumKeySize>
+ <AdvertisingDataBondedBitmap>0</AdvertisingDataBondedBitmap>
+ <AdvertisingDataGeneralBitmap>5a</AdvertisingDataGeneralBitmap>
+ <AdvertisingDataBrodcastBitmap>40</AdvertisingDataBrodcastBitmap>
+ <AdvertisingDataBondedScanResponseBitmap>0</AdvertisingDataBondedScanResponseBitmap>
+ <AdvertisingDataGeneralScanResponseBitmap>5a</AdvertisingDataGeneralScanResponseBitmap>
+ <AdvertisingDataBrodcastScanResponseBitmap>0</AdvertisingDataBrodcastScanResponseBitmap>
+ <AdvertisingDataBondedBitmapCustom>0</AdvertisingDataBondedBitmapCustom>
+ <AdvertisingDataGeneralBitmapCustom>0</AdvertisingDataGeneralBitmapCustom>
+ <AdvertisingDataBrodcastBitmapCustom>0</AdvertisingDataBrodcastBitmapCustom>
+ <AdvertisingDataBondedScanResponseBitmapCustom>0</AdvertisingDataBondedScanResponseBitmapCustom>
+ <AdvertisingDataGeneralScanResponseBitmapCustom>0</AdvertisingDataGeneralScanResponseBitmapCustom>
+ <AdvertisingDataBrodcastScanResponseBitmapCustom>0</AdvertisingDataBrodcastScanResponseBitmapCustom>
+ <TxPowerLevelOffset>0</TxPowerLevelOffset>
+ <MinimumConnectionInterval>65535</MinimumConnectionInterval>
+ <MaximumConnectionInterval>65535</MaximumConnectionInterval>
+ <SlaveLatency>0</SlaveLatency>
+ <TimeoutMultipler>65535</TimeoutMultipler>
+ <AddServiceUpdateCharacteristic>false</AddServiceUpdateCharacteristic>
+ <AddServiceUpdateCharacteristicPipe>false</AddServiceUpdateCharacteristicPipe>
+ <TimingChangeDelay>5</TimingChangeDelay>
+ <CustomAdTypes>
+ <AdType index="1">
+ <Type>19</Type>
+ <Value>0000</Value>
+ </AdType>
+ <AdType index="2">
+ <Type>18</Type>
+ <Value></Value>
+ </AdType>
+ </CustomAdTypes>
+ </Gapsettings>
+ <Hardwaresettings>
+ <Clocksource>0</Clocksource>
+ <ClockAccuracy>1</ClockAccuracy>
+ <InitialTxPower>3</InitialTxPower>
+ <HfClkSource>0</HfClkSource>
+ <DcDcConverter>0</DcDcConverter>
+ <ActiveSignalModeIndex>0</ActiveSignalModeIndex>
+ <ActiveSignalToTickDistance>0</ActiveSignalToTickDistance>
+ <DynamicWindowLimitingEnabled>false</DynamicWindowLimitingEnabled>
+ </Hardwaresettings>
+ <CurrentInput>
+ <BatteryCharge>220</BatteryCharge>
+ <Master32KhzClockAccuracy>10</Master32KhzClockAccuracy>
+ <ConnectionInterval>1000</ConnectionInterval>
+ <PercentOfTimeSleeping>70.12</PercentOfTimeSleeping>
+ <PercentOfTimeAdvertising>6.94</PercentOfTimeAdvertising>
+ <AdvertisingInterval>1280</AdvertisingInterval>
+ </CurrentInput>
+</Profile>
diff --git a/services.h b/services.h
new file mode 100644
index 0000000..fad505a
--- /dev/null
+++ b/services.h
@@ -0,0 +1,154 @@
+/**
+* This file is autogenerated by nRFgo Studio 1.17.1.3252
+*/
+
+#ifndef SETUP_MESSAGES_H__
+#define SETUP_MESSAGES_H__
+
+#include "hal_platform.h"
+#include "aci.h"
+
+
+#define SETUP_ID 1
+#define SETUP_FORMAT 3 /** nRF8001 D */
+#define ACI_DYNAMIC_DATA_SIZE 133
+
+/* Service: Gap - Characteristic: Device name - Pipe: SET */
+#define PIPE_GAP_DEVICE_NAME_SET 1
+#define PIPE_GAP_DEVICE_NAME_SET_MAX_SIZE 13
+
+/* Service: Fiken Status Panel - Characteristic: Gauge - Pipe: RX_ACK */
+#define PIPE_FIKEN_STATUS_PANEL_GAUGE_RX_ACK 2
+#define PIPE_FIKEN_STATUS_PANEL_GAUGE_RX_ACK_MAX_SIZE 2
+
+/* Service: Fiken Status Panel - Characteristic: Gauge - Pipe: SET */
+#define PIPE_FIKEN_STATUS_PANEL_GAUGE_SET 3
+#define PIPE_FIKEN_STATUS_PANEL_GAUGE_SET_MAX_SIZE 2
+
+/* Service: Fiken Status Panel - Characteristic: Led - Pipe: RX_ACK */
+#define PIPE_FIKEN_STATUS_PANEL_LED_RX_ACK 4
+#define PIPE_FIKEN_STATUS_PANEL_LED_RX_ACK_MAX_SIZE 3
+
+
+#define NUMBER_OF_PIPES 4
+
+#define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\
+ {ACI_STORE_LOCAL, ACI_SET}, \
+ {ACI_STORE_LOCAL, ACI_RX_ACK}, \
+ {ACI_STORE_LOCAL, ACI_SET}, \
+ {ACI_STORE_LOCAL, ACI_RX_ACK}, \
+}
+
+#define GAP_PPCP_MAX_CONN_INT 0xffff /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
+#define GAP_PPCP_MIN_CONN_INT 0xffff /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
+#define GAP_PPCP_SLAVE_LATENCY 0
+#define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */
+
+#define NB_SETUP_MESSAGES 18
+#define SETUP_MESSAGES_CONTENT {\
+ {0x00,\
+ {\
+ 0x07,0x06,0x00,0x00,0x03,0x02,0x42,0x07,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x10,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x00,0x06,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x03,0x90,0x01,0xff,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x00,\
+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x05,0x06,0x10,0x54,0x00,0x00,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\
+ 0x02,0x28,0x03,0x01,0x0e,0x03,0x00,0x00,0x2a,0x04,0x14,0x0d,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x20,0x1c,0x0d,0x00,0x03,0x2a,0x00,0x01,0x46,0x69,0x6b,0x65,0x6e,0x20,0x44,0x69,0x73,0x70,\
+ 0x6c,0x61,0x79,0x04,0x04,0x05,0x05,0x00,0x04,0x28,0x03,0x01,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x20,0x38,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,0x00,0x05,0x2a,0x01,0x01,0x00,0x00,\
+ 0x04,0x04,0x05,0x05,0x00,0x06,0x28,0x03,0x01,0x02,0x07,0x00,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x20,0x54,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,0x04,0x01,0xff,0xff,0xff,0xff,0x00,\
+ 0x00,0xff,0xff,0x04,0x04,0x02,0x02,0x00,0x08,0x28,0x00,0x01,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x20,0x70,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28,0x00,0x01,0x3f,0xd8,0x1f,0x4a,0x8e,\
+ 0xbc,0xd3,0x70,0xc5,0x59,0x5d,0x03,0x01,0x00,0xd0,0x32,0x04,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x20,0x8c,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x0e,0x0b,0x00,0x3f,0xd8,0x1f,0x4a,0x8e,\
+ 0xbc,0xd3,0x70,0xc5,0x59,0x5d,0x03,0x02,0x00,0xd0,0x32,0x46,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x20,0xa8,0x14,0x03,0x02,0x00,0x0b,0x00,0x02,0x02,0x12,0x34,0x04,0x04,0x13,0x13,0x00,0x0c,\
+ 0x28,0x03,0x01,0x0a,0x0d,0x00,0x3f,0xd8,0x1f,0x4a,0x8e,0xbc,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1a,0x06,0x20,0xc4,0xd3,0x70,0xc5,0x59,0x5d,0x03,0x03,0x00,0xd0,0x32,0x46,0x14,0x04,0x03,0x00,0x0d,\
+ 0x00,0x03,0x02,0x00,0x00,0x00,0x00,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x1f,0x06,0x40,0x00,0x2a,0x00,0x01,0x00,0x80,0x04,0x00,0x03,0x00,0x00,0x00,0x02,0x02,0x00,0x90,0x04,\
+ 0x00,0x0b,0x00,0x00,0x00,0x03,0x02,0x00,0x10,0x04,0x00,0x0d,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x05,0x06,0x40,0x1c,0x00,0x00,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x13,0x06,0x50,0x00,0x3f,0xd8,0x1f,0x4a,0x8e,0xbc,0xd3,0x70,0xc5,0x59,0x5d,0x03,0x00,0x00,0xd0,0x32,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x0c,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+ },\
+ },\
+ {0x00,\
+ {\
+ 0x06,0x06,0xf0,0x00,0x03,0xf7,0x6c,\
+ },\
+ },\
+}
+
+#endif
+