diff --git a/Anaren_uart_example/makefile.mk b/Anaren_uart_example/makefile.mk new file mode 100644 index 0000000..7a3617b --- /dev/null +++ b/Anaren_uart_example/makefile.mk @@ -0,0 +1,18 @@ +# +# Copyright 2015, Broadcom Corporation +# All Rights Reserved. +# +# This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; +# the contents of this file may not be disclosed to third parties, copied +# or duplicated in any form, in whole or in part, without the prior +# written permission of Broadcom Corporation. +# + +######################################################################## +# Application sources. +######################################################################## +APP_SRC = uart_example.c utils.c + +######################################################################## +################ DO NOT MODIFY FILE BELOW THIS LINE #################### +######################################################################## \ No newline at end of file diff --git a/Anaren_uart_example/uart_example.c b/Anaren_uart_example/uart_example.c new file mode 100644 index 0000000..31a0cd7 --- /dev/null +++ b/Anaren_uart_example/uart_example.c @@ -0,0 +1,374 @@ +/* + * Copyright 2015, Broadcom Corporation + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of Broadcom Corporation. + */ + +/** @file +* +* uart demo for the anaren a20737-MSDB1 board. +*/ + +#define CONFIG_IN_NVRAM 1 +#include "bleprofile.h" +#include "bleapp.h" +#include "gpiodriver.h" +#include "stdio.h" +#include "platform.h" +#include "bleappconfig.h" +#include "cfa.h" +#include "spar_utils.h" +#include "puart.h" +#include "devicelpm.h" +// To use PWM, we will need the auxiliary clock and the PWM drier. +#include "aclk.h" +#include "pwm.h" +#include "i2cm.h" +#include +#include +#include +#include +#include "utils.h" + +/****************************************************** + * Constants + ******************************************************/ +// The GPIO to which an LED is assumed to be connected. Note that +// the tag board does not have an LED connected to P26 by default. +const BYTE RED_LED = GPIO_PIN_P26; +const BYTE GREEN_LED = GPIO_PIN_P27; +const BYTE BLUE_LED = GPIO_PIN_P28; +const BYTE BUZZER = GPIO_PIN_P14; +BLE_PROFILE_CFG puart_control_cfg = {0}; + +// Please note that all UUIDs need to be reversed when publishing in the database +#define SERVICE_1_UUID 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#define SERVICE_1_CHARACTERISTIC_1_UUID 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#define SERVICE_1_CHARACTERISTIC_2_UUID 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#define SERVICE_1_CHARACTERISTIC_3_UUID 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define SERVICE_2_UUID 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#define SERVICE_2_CHARACTERISTIC_1_UUID 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define SERVICE_3_UUID 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#define SERVICE_4_UUID 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + + + + + + +/****************************************************** + * Types + ******************************************************/ + +/****************************************************** + * Function Prototypes + ******************************************************/ +static void app(void); +static void timer_cb(UINT32 value); +static void fine_timer_cb(UINT32 value); + +/****************************************************** + * Variables Definitions + ******************************************************/ +const char BLE_NAME[] = "BCM20737"; +const char DEV_VERSION[] = "0.01"; +const UINT8 gatt_database[] = +{ + //This service contains the device name + //A read/write characteristic + //The raw temp with ntf available + PRIMARY_SERVICE_UUID128(0x0010,SERVICE_1_UUID), + CHARACTERISTIC_UUID128(0x0011, 0x0012, SERVICE_1_CHARACTERISTIC_1_UUID, + LEGATTDB_CHAR_PROP_READ, + LEGATTDB_PERM_READABLE, 8), + 'B','C','M','2','0','7','3','7', + + CHARACTERISTIC_UUID128_WRITABLE(0x0013, 0x0014, SERVICE_1_CHARACTERISTIC_2_UUID, + LEGATTDB_CHAR_PROP_READ|LEGATTDB_CHAR_PROP_WRITE, + LEGATTDB_PERM_READABLE|LEGATTDB_PERM_WRITABLE|LEGATTDB_PERM_WRITE_REQ, 16), + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + + CHARACTERISTIC_UUID128_WRITABLE(0x0015, 0x0016, SERVICE_1_CHARACTERISTIC_3_UUID, + LEGATTDB_CHAR_PROP_READ|LEGATTDB_CHAR_PROP_WRITE|LEGATTDB_CHAR_PROP_NOTIFY, + LEGATTDB_PERM_READABLE|LEGATTDB_PERM_WRITABLE|LEGATTDB_PERM_WRITE_REQ, 16), + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + + CHAR_DESCRIPTOR_UUID16_WRITABLE(0x17, + UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION, + LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ, + 2), + 0x00,0x00, + + CHAR_DESCRIPTOR_UUID16(0x18, + UUID_DESCRIPTOR_CHARACTERISTIC_USER_DESCRIPTION, + LEGATTDB_PERM_READABLE, + 11), + 'T','e','m','p','e','r','a','t','u','r','e', + + //This service contains a characteristic to enable the buzzer + PRIMARY_SERVICE_UUID128(0x0020,SERVICE_2_UUID), + CHARACTERISTIC_UUID128_WRITABLE(0x0021, 0x0022, SERVICE_2_CHARACTERISTIC_1_UUID, + LEGATTDB_CHAR_PROP_READ | LEGATTDB_CHAR_PROP_WRITE, + LEGATTDB_PERM_READABLE|LEGATTDB_PERM_WRITABLE|LEGATTDB_PERM_WRITE_REQ, 1), + 0x00, + + CHAR_DESCRIPTOR_UUID16(0x23, + UUID_DESCRIPTOR_CHARACTERISTIC_USER_DESCRIPTION, + LEGATTDB_PERM_READABLE, + 6), + 'B','u','z','z','e','r', + + PRIMARY_SERVICE_UUID128(0x0030,SERVICE_3_UUID), + PRIMARY_SERVICE_UUID128(0x0040,SERVICE_4_UUID), + +}; + +BD_ADDR ble_device_addr = {0}; +uint8_t run = 1; +uint16_t raw_temp = 0; +char recvBuffer[20]; +BYTE numConnectedClients = 0; + +/****************************************************** + * Function Definitions + ******************************************************/ +static void serial_rxCb(void *unused) +{ + UINT8 character = 0; + static uint8_t i = 0; + + + while (puart_rxFifoNotEmpty() && puart_read(&character)) + { + puart_write(character); + recvBuffer[i++ % 20] = character; + } + recvBuffer[i] = '\0'; + + // clear the interrupt + P_UART_INT_CLEAR(P_UART_ISR_RX_AFF_MASK); + // enable UART interrupt in the Main Interrupt Controller and RX Almost Full in the UART Interrupt Controller + P_UART_INT_ENABLE |= P_UART_ISR_RX_AFF_MASK; + + if(memcmp(recvBuffer,"stop", 4) == 0) + run = 0, i = 0; + else if(memcmp(recvBuffer,"start", 4) == 0) + run = 1, i = 0; + + if(strlen(recvBuffer) > 3) + i = 0; +} + +static void ble_link_up(void) +{ + puart_print("BLE Link up\n"); + numConnectedClients++; +} + +static void ble_link_down(void) +{ + puart_print("BLE Link down\n"); + + //Mandatory to be able to reconnect once disconnected + bleprofile_Discoverable(HIGH_UNDIRECTED_DISCOVERABLE, ble_device_addr); + + numConnectedClients--; + if(!numConnectedClients)gpio_setPinOutput(PIN2PORT(RED_LED), PIN2PIN(RED_LED), 0); +} + +static INT32 ble_write_handler(LEGATTDB_ENTRY_HDR *p) +{ + UINT16 handle = legattdb_getHandle(p); + int len = legattdb_getAttrValueLen(p), i = 0; + UINT8 *buffer = legattdb_getAttrValue(p); + + puart_printf("Handle : 0x%02X\n", handle); + puart_print("Client wrote (HEX) : #"); + for(i = 0; i < len; i++) + { + puart_printf("0x%02X ",buffer[i]); + } + puart_print("#\n"); + + puart_print("Client wrote (ASCII) : #"); + for(i = 0; i < len; i++) + { + puart_write(buffer[i]); + } + puart_print("#\n"); + + switch(handle) + { + case 0x17: + if(len == 2) + { + if(buffer[0] & CCC_NOTIFICATION) + puart_print("NTF enabled\n"); + else + puart_print("NTF disabled\n"); + } + break; + case 0x22: + if(buffer[0]) + { + puart_print("Buzzer on\n"); + gpio_configurePin(PIN2PORT(BUZZER), PIN2PIN(BUZZER), PWM2_OUTPUT_ENABLE_P14 , 0); + pwm_start(PWM2, PMU_CLK, 0x2FF, 0x200); + } + else + { + puart_print("Buzzer off\n"); + gpio_configurePin(PIN2PORT(BUZZER), PIN2PIN(BUZZER), GPIO_OUTPUT_DISABLE | GPIO_PULL_DOWN, 0); + pwm_setReset(PWM2, 1); + } + break; + default: + break; + } + + return 0; +} + +// Application initialization +APPLICATION_INIT() +{ + puart_control_cfg.fine_timer_interval = 1000; + puart_control_cfg.default_adv = HIGH_UNDIRECTED_DISCOVERABLE; + puart_control_cfg.button_adv_toggle = 0; + puart_control_cfg.high_undirect_adv_interval = 32; + puart_control_cfg.low_undirect_adv_interval = 1024; + puart_control_cfg.high_undirect_adv_duration = 30; // seconds + puart_control_cfg.low_undirect_adv_duration = 300; // seconds + puart_control_cfg.high_direct_adv_interval = 0; // seconds + puart_control_cfg.low_direct_adv_interval = 0; // seconds + puart_control_cfg.high_direct_adv_duration = 0; // seconds + puart_control_cfg.low_direct_adv_duration = 0; // seconds + memcpy(puart_control_cfg.local_name, BLE_NAME, sizeof(BLE_NAME)); + puart_control_cfg.cod[0] = (UINT8) APPEARANCE_GENERIC_TAG ; + puart_control_cfg.cod[1] = APPEARANCE_GENERIC_TAG >> 8; + memcpy(puart_control_cfg.ver, DEV_VERSION, sizeof(DEV_VERSION)); + memset(puart_control_cfg.hdl, 0, HANDLE_NUM_MAX); + memset(puart_control_cfg.serv, 0, HANDLE_NUM_MAX); + memset(puart_control_cfg.cha, 0, HANDLE_NUM_MAX); + + puart_control_cfg.tx_power_level = 4; // max is +4 dBm... + memset(recvBuffer, 0, sizeof(recvBuffer)); + + + bleapp_set_cfg((UINT8 *)gatt_database, + sizeof(gatt_database), + (void *)&puart_control_cfg, + (void *)NULL, + (void *)NULL, + app); +} + +UINT32 uart_device_lpm_queriable(LowPowerModePollType type, UINT32 context) +{ + // Disable sleep. + return 0; +} + +void app(void) +{ + devlpm_init(); + + //UART INIT SECTION + puart_setBaudrate(0,0,115200); + puart_selectUartPads(((GPIO_PIN_UART_RX / 16) << 5) | (GPIO_PIN_UART_RX % 16), ((GPIO_PIN_UART_TX / 16) << 5) | (GPIO_PIN_UART_TX % 16), 0 ,0); + puart_init(); + puart_flowOff(); + devlpm_registerForLowPowerQueries(uart_device_lpm_queriable, 0); + P_UART_INT_CLEAR(P_UART_ISR_RX_AFF_MASK); + P_UART_WATER_MARK_RX_LEVEL(1); + P_UART_INT_ENABLE |= P_UART_ISR_RX_AFF_MASK; + puart_rxCb = serial_rxCb; + puart_enableInterrupt(); + + //BLE INIT SECTION + bleprofile_Init(bleprofile_p_cfg); + bleprofile_regTimerCb(fine_timer_cb, timer_cb); + bleprofile_StartTimer(); + + bleprofile_regAppEvtHandler(BLECM_APP_EVT_LINK_UP, ble_link_up); + bleprofile_regAppEvtHandler(BLECM_APP_EVT_LINK_DOWN, ble_link_down); + legattdb_regWriteHandleCb((LEGATTDB_WRITE_CB)ble_write_handler); + + bleprofile_Discoverable(HIGH_UNDIRECTED_DISCOVERABLE, ble_device_addr); + + gpio_configurePin(PIN2PORT(RED_LED), PIN2PIN(RED_LED), GPIO_OUTPUT_ENABLE ,0); + gpio_configurePin(PIN2PORT(GREEN_LED), PIN2PIN(GREEN_LED), GPIO_OUTPUT_ENABLE ,0); + gpio_configurePin(PIN2PORT(BLUE_LED), PIN2PIN(BLUE_LED), GPIO_OUTPUT_ENABLE ,0); + //Buzzer config + aclk_configure(512000, ACLK1, ACLK_FREQ_24_MHZ); + + puart_print("App init done\r\n"); +} + +void timer_cb(UINT32 value) +{ + static uint8_t state = 0; + + if(run) + state++; + + switch(state%2) + { + case 0: + gpio_setPinOutput(PIN2PORT(GREEN_LED), PIN2PIN(GREEN_LED), 1); + gpio_setPinOutput(PIN2PORT(BLUE_LED), PIN2PIN(BLUE_LED), 0); + break; + default: + gpio_setPinOutput(PIN2PORT(GREEN_LED), PIN2PIN(GREEN_LED), 0); + gpio_setPinOutput(PIN2PORT(BLUE_LED), PIN2PIN(BLUE_LED), 1); + + //I2C test + uint8_t reg = 0xFE; + uint8_t ManuID[2]; + + i2cm_init(); + i2cm_setSpeed(I2CM_SPEED_400KHZ); + if(i2cm_comboRead(ManuID, 2, ®, 1, 0x40 << 1) == I2CM_SUCCESS) + { + puart_print("I2C comboRead success\n"); + puart_printf("Manu ID : 0x%02X%02X\n", ManuID[0], ManuID[1]); + + reg = 0x01; + i2cm_comboRead(ManuID, 2, ®, 1, 0x40 << 1); + raw_temp = (ManuID[0] << 6) + (ManuID[1] >> 2); + puart_printf("Raw temp : 0x%02X%02X -> %u, %u\n", ManuID[0], ManuID[1], raw_temp, raw_temp / 32); + } + else + puart_print("I2C comboRead failure\n"); + + } + + if(numConnectedClients) + { + gpio_togglePin(PIN2PORT(RED_LED), PIN2PIN(RED_LED)); + } +} + +void fine_timer_cb(UINT32 value) +{ + BLEPROFILE_DB_PDU db_pdu; + + UINT8 buffer[15]; + sprintf((char*)buffer,"temp : %u", raw_temp); + + puart_printf("%s\nrecvBuffer : #%s#\n",buffer, recvBuffer); + + bleprofile_ReadHandle(0x0016, &db_pdu); + memcpy(db_pdu.pdu, buffer, sizeof(buffer)); + db_pdu.len = strlen(buffer); + + bleprofile_WriteHandle(0x0016, &db_pdu); + bleprofile_sendNotification(0x0016, (UINT8 *)db_pdu.pdu, db_pdu.len); +} diff --git a/Anaren_uart_example/utils.c b/Anaren_uart_example/utils.c new file mode 100644 index 0000000..4c0c7d8 --- /dev/null +++ b/Anaren_uart_example/utils.c @@ -0,0 +1,30 @@ +#include "utils.h" + +void delayMS(uint32_t ms) +{ + volatile uint32_t i; + for(i = 0; i < 1843*ms; i++); +} + +void delayS(uint32_t s) +{ + uint32_t i = 0; + for(i = 0; i < s*1000; i++) + delayMS(1); +} + +void puart_printf(const char *format, ...) +{ + char buffer[200]; + va_list argList; + + va_start(argList, format); + vsprintf(buffer, format, argList); + va_end(argList); + puart_print(buffer); +} + +void gpio_togglePin(BYTE port, BYTE pin) +{ + gpio_setPinOutput(port, pin, !gpio_getPinOutput(port, pin)); +} diff --git a/Anaren_uart_example/utils.h b/Anaren_uart_example/utils.h new file mode 100644 index 0000000..d6de02d --- /dev/null +++ b/Anaren_uart_example/utils.h @@ -0,0 +1,17 @@ +#ifndef UTILS_H +#define UTILS_H +#include +#include +#include +#include + +#define PIN2PORT(pin) (pin / 16) +#define PIN2PIN(pin) (pin % 16) + +void delayMS(uint32_t ms); +void delayS(uint32_t s); + +void puart_printf(const char *format, ...); +void gpio_togglePin(BYTE port, BYTE pin); + +#endif //UTILS_H