WICED_Anaren_BCM20737_Samples/Anaren_uart_example/uart_example.c

407 lines
12 KiB
C

/*
* 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 <inttypes.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#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;
const BYTE IOEXPAND_INT = GPIO_PIN_2;
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);
static UINT8* showActivity(UINT8 *buffer);
static void ioexpand_int_handler(void *data, UINT8 pin);
/******************************************************
* 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, 18),
0,0,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;
uint8_t temp = 0.0;
UINT8 activityBuffer[4] = {'.',' ',' ',0};
char recvBuffer[20];
BYTE numConnectedClients = 0;
/******************************************************
* Function Definitions
******************************************************/
static void serial_rxCb(void *unused)
{
UINT8 character = 0;
uint8_t i = 0;
while (puart_rxFifoNotEmpty() && puart_read(&character))
{
puart_write(character);
recvBuffer[i++ % 20] = character;
bleapputils_delayUs(500); //Needed to let some time to the uart to receive the data
}
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;
else if(memcmp(recvBuffer,"start", 4) == 0)
run = 1;
}
static void ioexpand_int_handler(void *data, UINT8 pin)
{
puart_print("IO int\n");
}
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;
}
// Makes the litle dot move at the end of the temperature string.
UINT8* showActivity(UINT8 *buffer)
{
if(buffer[0] == '.')
{
buffer[0] = ' ';
buffer[1] = '.';
buffer[2] = ' ';
}
else if(buffer[1] == '.')
{
buffer[0] = ' ';
buffer[1] = ' ';
buffer[2] = '.';
}
else
{
buffer[0] = '.';
buffer[1] = ' ';
buffer[2] = ' ';
}
return buffer;
}
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, GPIO_PIN_OUTPUT_LOW);
gpio_configurePin(PIN2PORT(GREEN_LED), PIN2PIN(GREEN_LED), GPIO_OUTPUT_ENABLE, GPIO_PIN_OUTPUT_LOW);
gpio_configurePin(PIN2PORT(BLUE_LED), PIN2PIN(BLUE_LED), GPIO_OUTPUT_ENABLE, GPIO_PIN_OUTPUT_LOW);
gpio_configurePin(PIN2PORT(IOEXPAND_INT), PIN2PIN(IOEXPAND_INT), GPIO_INPUT_ENABLE | GPIO_PULL_UP | GPIO_EN_INT_FALLING_EDGE, GPIO_PIN_INPUT_HIGH);
gpio_registerForInterrupt(NULL, ioexpand_int_handler, NULL);
//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];
uint16_t raw_temp = 0;
if(i2cm_comboRead(ManuID, 2, &reg, 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, &reg, 1, 0x40 << 1);
raw_temp = (ManuID[0] << 6) + (ManuID[1] >> 2);
temp = raw_temp / 32;
puart_printf("Raw temp : 0x%02X%02X -> %u, %u\n", ManuID[0], ManuID[1], raw_temp, temp);
}
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[18];
sprintf((char*)buffer,"temp : %u C%s", temp, showActivity(activityBuffer));
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);
}