Attempting to create an open source, very simple (basically bluetooth notification light to start) smartwatch around the nRF51822.

Dependencies:   BLE_API mbed nRF51822

The main branch of code for the simpleWatch project

main.cpp

Committer:
rjpope42
Date:
2016-05-11
Revision:
0:3e9f9b3ed7c8

File content as of revision 0:3e9f9b3ed7c8:


#include "mbed.h"
#include "nrf51.h"
#include "nrf51_bitfields.h"
#include <string>

#include "BLE.h"
#include "DFUService.h"
#include "UARTService.h"

#define LED_GREEN   p21
#define LED_RED     p22
#define LED_BLUE    p23
#define BUTTON_PIN  p17
#define BATTERY_PIN p1

#define UART_TX     p9
#define UART_RX     p11
#define UART_CTS    p8
#define UART_RTS    p10

InterruptIn button(BUTTON_PIN);
AnalogIn    battery(BATTERY_PIN);



int read_none_count = 0;

BLEDevice  ble;
UARTService *uartServicePtr;

volatile bool bleIsConnected = false;
volatile uint8_t tick_event = 0;



void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
    bleIsConnected = true;
}

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams)
{
    ble.startAdvertising();
    bleIsConnected = false;
}

void detect(void)
{
    //LOG("Button pressed\n");  
    //blue = !blue;
}

void led_init(void)
{
      
//set LED pins to digital output
NRF_GPIO->PIN_CNF[LED_BLUE] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
                             | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
                             | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
                             | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
                             | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);

NRF_GPIO->PIN_CNF[LED_GREEN] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
                             | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
                             | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
                             | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
                             | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
                             
NRF_GPIO->PIN_CNF[LED_RED] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
                             | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
                             | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
                             | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
                             | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);                            
// NRF_GPIO - #define NRF_GPIO                        ((NRF_GPIO_Type           *) NRF_GPIO_BASE)
//   NRF_GPIO_Type - struct containing possible settings  (DIR, INPUT, PULL, DRIVE, SENSE, as well as PIN_CNF[] (configuration array for all 32 outputs)
//   NRF_GPIO_BASE - #define NRF_GPIO_BASE                   0x50000000UL  //base register address for GPIO settings
// -> just a way of accessing PIN_CNF[pin_we_want_to_mess_with], object oriented programming stuff
// GPIO_PIN_CNF_SENSE_Disabled   //the appropriate binary value to set sense as disabled
// <<                            //bit shift
// GPIO_PIN_CNF_SENSE_pos        //position that the value of GPIO_PIN_CNF_SENSE_Disabled should be placed at
// | //OR all of these values together to set the register
}
    

int main(void)
{
  
    led_init();
    
    //Turn all LEDs off
    NRF_GPIO->OUTSET = (1UL << LED_BLUE); //remember that writing zeros with outset and outclear has no effect
    NRF_GPIO->OUTSET = (1UL << LED_RED); 
    NRF_GPIO->OUTSET = (1UL << LED_GREEN); 
        
    wait(1);
    
    button.fall(detect);

    //Initialising the nRF51822
    ble.init();
    ble.gap().onDisconnection(disconnectionCallback);
    ble.gap().onConnection(connectionCallback);


    /* setup advertising */
    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                     (const uint8_t *)"PWMtest", sizeof("PWMtest"));
    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
    DFUService dfu(ble);                                 
    UARTService uartService(ble);
    uartServicePtr = &uartService;
    //uartService.retargetStdout();

    ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
    ble.gap().startAdvertising();
    char str[8];
    str[5]='\r';
    str[6]='\n';
    str[7]='\0';
    
    //int rgb_res = 8; //RGB resolution, TODO define this as a constant later
    int vals[3] = {0};
    bool pwmvals[3] = {0};
    
    
    while (true) {
        ble.waitForEvent();
        str[0]=uartService._getc();//set
        if (str[0]=='S')
        {
            
            str[1]=uartService._getc();//R
            str[2]=uartService._getc();//G
            str[3]=uartService._getc();//B
            str[4]=uartService._getc();
            
            vals[0] = str[1]-0x30;//convert from char to int
            vals[1] = str[2]-0x30;
            vals[2] = str[3]-0x30;
            uartService.writeString(str);
            
            str[0] = 0;
        }
        
        for(uint32_t j = 100000; j>0; j--)//display color for a couple seconds
        {
            for(int i = 8; i>0; i--)//
            {
                pwmvals[0] = (i - vals[0] == 0);//control brightness by turning LED on after x iterations
                pwmvals[1] = (i - vals[1] == 0);//could compare directly to str and save an array
                pwmvals[2] = (i - vals[2] == 0);
                NRF_GPIO->OUTCLR = (pwmvals[0] << LED_RED)|(pwmvals[1] << LED_GREEN)|(pwmvals[2] << LED_BLUE);
                
            }
            NRF_GPIO->OUTSET = (0x7UL << LED_GREEN);//turn all 3 off
        }
    }
}