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

Committer:
rjpope42
Date:
Wed May 11 18:29:00 2016 +0000
Revision:
0:3e9f9b3ed7c8
Committing a PWM attempt as version 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rjpope42 0:3e9f9b3ed7c8 1
rjpope42 0:3e9f9b3ed7c8 2 #include "mbed.h"
rjpope42 0:3e9f9b3ed7c8 3 #include "nrf51.h"
rjpope42 0:3e9f9b3ed7c8 4 #include "nrf51_bitfields.h"
rjpope42 0:3e9f9b3ed7c8 5 #include <string>
rjpope42 0:3e9f9b3ed7c8 6
rjpope42 0:3e9f9b3ed7c8 7 #include "BLE.h"
rjpope42 0:3e9f9b3ed7c8 8 #include "DFUService.h"
rjpope42 0:3e9f9b3ed7c8 9 #include "UARTService.h"
rjpope42 0:3e9f9b3ed7c8 10
rjpope42 0:3e9f9b3ed7c8 11 #define LED_GREEN p21
rjpope42 0:3e9f9b3ed7c8 12 #define LED_RED p22
rjpope42 0:3e9f9b3ed7c8 13 #define LED_BLUE p23
rjpope42 0:3e9f9b3ed7c8 14 #define BUTTON_PIN p17
rjpope42 0:3e9f9b3ed7c8 15 #define BATTERY_PIN p1
rjpope42 0:3e9f9b3ed7c8 16
rjpope42 0:3e9f9b3ed7c8 17 #define UART_TX p9
rjpope42 0:3e9f9b3ed7c8 18 #define UART_RX p11
rjpope42 0:3e9f9b3ed7c8 19 #define UART_CTS p8
rjpope42 0:3e9f9b3ed7c8 20 #define UART_RTS p10
rjpope42 0:3e9f9b3ed7c8 21
rjpope42 0:3e9f9b3ed7c8 22 InterruptIn button(BUTTON_PIN);
rjpope42 0:3e9f9b3ed7c8 23 AnalogIn battery(BATTERY_PIN);
rjpope42 0:3e9f9b3ed7c8 24
rjpope42 0:3e9f9b3ed7c8 25
rjpope42 0:3e9f9b3ed7c8 26
rjpope42 0:3e9f9b3ed7c8 27 int read_none_count = 0;
rjpope42 0:3e9f9b3ed7c8 28
rjpope42 0:3e9f9b3ed7c8 29 BLEDevice ble;
rjpope42 0:3e9f9b3ed7c8 30 UARTService *uartServicePtr;
rjpope42 0:3e9f9b3ed7c8 31
rjpope42 0:3e9f9b3ed7c8 32 volatile bool bleIsConnected = false;
rjpope42 0:3e9f9b3ed7c8 33 volatile uint8_t tick_event = 0;
rjpope42 0:3e9f9b3ed7c8 34
rjpope42 0:3e9f9b3ed7c8 35
rjpope42 0:3e9f9b3ed7c8 36
rjpope42 0:3e9f9b3ed7c8 37 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
rjpope42 0:3e9f9b3ed7c8 38 {
rjpope42 0:3e9f9b3ed7c8 39 bleIsConnected = true;
rjpope42 0:3e9f9b3ed7c8 40 }
rjpope42 0:3e9f9b3ed7c8 41
rjpope42 0:3e9f9b3ed7c8 42 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams)
rjpope42 0:3e9f9b3ed7c8 43 {
rjpope42 0:3e9f9b3ed7c8 44 ble.startAdvertising();
rjpope42 0:3e9f9b3ed7c8 45 bleIsConnected = false;
rjpope42 0:3e9f9b3ed7c8 46 }
rjpope42 0:3e9f9b3ed7c8 47
rjpope42 0:3e9f9b3ed7c8 48 void detect(void)
rjpope42 0:3e9f9b3ed7c8 49 {
rjpope42 0:3e9f9b3ed7c8 50 //LOG("Button pressed\n");
rjpope42 0:3e9f9b3ed7c8 51 //blue = !blue;
rjpope42 0:3e9f9b3ed7c8 52 }
rjpope42 0:3e9f9b3ed7c8 53
rjpope42 0:3e9f9b3ed7c8 54 void led_init(void)
rjpope42 0:3e9f9b3ed7c8 55 {
rjpope42 0:3e9f9b3ed7c8 56
rjpope42 0:3e9f9b3ed7c8 57 //set LED pins to digital output
rjpope42 0:3e9f9b3ed7c8 58 NRF_GPIO->PIN_CNF[LED_BLUE] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
rjpope42 0:3e9f9b3ed7c8 59 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
rjpope42 0:3e9f9b3ed7c8 60 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
rjpope42 0:3e9f9b3ed7c8 61 | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
rjpope42 0:3e9f9b3ed7c8 62 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
rjpope42 0:3e9f9b3ed7c8 63
rjpope42 0:3e9f9b3ed7c8 64 NRF_GPIO->PIN_CNF[LED_GREEN] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
rjpope42 0:3e9f9b3ed7c8 65 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
rjpope42 0:3e9f9b3ed7c8 66 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
rjpope42 0:3e9f9b3ed7c8 67 | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
rjpope42 0:3e9f9b3ed7c8 68 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
rjpope42 0:3e9f9b3ed7c8 69
rjpope42 0:3e9f9b3ed7c8 70 NRF_GPIO->PIN_CNF[LED_RED] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
rjpope42 0:3e9f9b3ed7c8 71 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
rjpope42 0:3e9f9b3ed7c8 72 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
rjpope42 0:3e9f9b3ed7c8 73 | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
rjpope42 0:3e9f9b3ed7c8 74 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
rjpope42 0:3e9f9b3ed7c8 75 // NRF_GPIO - #define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
rjpope42 0:3e9f9b3ed7c8 76 // NRF_GPIO_Type - struct containing possible settings (DIR, INPUT, PULL, DRIVE, SENSE, as well as PIN_CNF[] (configuration array for all 32 outputs)
rjpope42 0:3e9f9b3ed7c8 77 // NRF_GPIO_BASE - #define NRF_GPIO_BASE 0x50000000UL //base register address for GPIO settings
rjpope42 0:3e9f9b3ed7c8 78 // -> just a way of accessing PIN_CNF[pin_we_want_to_mess_with], object oriented programming stuff
rjpope42 0:3e9f9b3ed7c8 79 // GPIO_PIN_CNF_SENSE_Disabled //the appropriate binary value to set sense as disabled
rjpope42 0:3e9f9b3ed7c8 80 // << //bit shift
rjpope42 0:3e9f9b3ed7c8 81 // GPIO_PIN_CNF_SENSE_pos //position that the value of GPIO_PIN_CNF_SENSE_Disabled should be placed at
rjpope42 0:3e9f9b3ed7c8 82 // | //OR all of these values together to set the register
rjpope42 0:3e9f9b3ed7c8 83 }
rjpope42 0:3e9f9b3ed7c8 84
rjpope42 0:3e9f9b3ed7c8 85
rjpope42 0:3e9f9b3ed7c8 86 int main(void)
rjpope42 0:3e9f9b3ed7c8 87 {
rjpope42 0:3e9f9b3ed7c8 88
rjpope42 0:3e9f9b3ed7c8 89 led_init();
rjpope42 0:3e9f9b3ed7c8 90
rjpope42 0:3e9f9b3ed7c8 91 //Turn all LEDs off
rjpope42 0:3e9f9b3ed7c8 92 NRF_GPIO->OUTSET = (1UL << LED_BLUE); //remember that writing zeros with outset and outclear has no effect
rjpope42 0:3e9f9b3ed7c8 93 NRF_GPIO->OUTSET = (1UL << LED_RED);
rjpope42 0:3e9f9b3ed7c8 94 NRF_GPIO->OUTSET = (1UL << LED_GREEN);
rjpope42 0:3e9f9b3ed7c8 95
rjpope42 0:3e9f9b3ed7c8 96 wait(1);
rjpope42 0:3e9f9b3ed7c8 97
rjpope42 0:3e9f9b3ed7c8 98 button.fall(detect);
rjpope42 0:3e9f9b3ed7c8 99
rjpope42 0:3e9f9b3ed7c8 100 //Initialising the nRF51822
rjpope42 0:3e9f9b3ed7c8 101 ble.init();
rjpope42 0:3e9f9b3ed7c8 102 ble.gap().onDisconnection(disconnectionCallback);
rjpope42 0:3e9f9b3ed7c8 103 ble.gap().onConnection(connectionCallback);
rjpope42 0:3e9f9b3ed7c8 104
rjpope42 0:3e9f9b3ed7c8 105
rjpope42 0:3e9f9b3ed7c8 106 /* setup advertising */
rjpope42 0:3e9f9b3ed7c8 107 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
rjpope42 0:3e9f9b3ed7c8 108 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
rjpope42 0:3e9f9b3ed7c8 109 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
rjpope42 0:3e9f9b3ed7c8 110 (const uint8_t *)"PWMtest", sizeof("PWMtest"));
rjpope42 0:3e9f9b3ed7c8 111 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
rjpope42 0:3e9f9b3ed7c8 112 (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
rjpope42 0:3e9f9b3ed7c8 113 DFUService dfu(ble);
rjpope42 0:3e9f9b3ed7c8 114 UARTService uartService(ble);
rjpope42 0:3e9f9b3ed7c8 115 uartServicePtr = &uartService;
rjpope42 0:3e9f9b3ed7c8 116 //uartService.retargetStdout();
rjpope42 0:3e9f9b3ed7c8 117
rjpope42 0:3e9f9b3ed7c8 118 ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
rjpope42 0:3e9f9b3ed7c8 119 ble.gap().startAdvertising();
rjpope42 0:3e9f9b3ed7c8 120 char str[8];
rjpope42 0:3e9f9b3ed7c8 121 str[5]='\r';
rjpope42 0:3e9f9b3ed7c8 122 str[6]='\n';
rjpope42 0:3e9f9b3ed7c8 123 str[7]='\0';
rjpope42 0:3e9f9b3ed7c8 124
rjpope42 0:3e9f9b3ed7c8 125 //int rgb_res = 8; //RGB resolution, TODO define this as a constant later
rjpope42 0:3e9f9b3ed7c8 126 int vals[3] = {0};
rjpope42 0:3e9f9b3ed7c8 127 bool pwmvals[3] = {0};
rjpope42 0:3e9f9b3ed7c8 128
rjpope42 0:3e9f9b3ed7c8 129
rjpope42 0:3e9f9b3ed7c8 130 while (true) {
rjpope42 0:3e9f9b3ed7c8 131 ble.waitForEvent();
rjpope42 0:3e9f9b3ed7c8 132 str[0]=uartService._getc();//set
rjpope42 0:3e9f9b3ed7c8 133 if (str[0]=='S')
rjpope42 0:3e9f9b3ed7c8 134 {
rjpope42 0:3e9f9b3ed7c8 135
rjpope42 0:3e9f9b3ed7c8 136 str[1]=uartService._getc();//R
rjpope42 0:3e9f9b3ed7c8 137 str[2]=uartService._getc();//G
rjpope42 0:3e9f9b3ed7c8 138 str[3]=uartService._getc();//B
rjpope42 0:3e9f9b3ed7c8 139 str[4]=uartService._getc();
rjpope42 0:3e9f9b3ed7c8 140
rjpope42 0:3e9f9b3ed7c8 141 vals[0] = str[1]-0x30;//convert from char to int
rjpope42 0:3e9f9b3ed7c8 142 vals[1] = str[2]-0x30;
rjpope42 0:3e9f9b3ed7c8 143 vals[2] = str[3]-0x30;
rjpope42 0:3e9f9b3ed7c8 144 uartService.writeString(str);
rjpope42 0:3e9f9b3ed7c8 145
rjpope42 0:3e9f9b3ed7c8 146 str[0] = 0;
rjpope42 0:3e9f9b3ed7c8 147 }
rjpope42 0:3e9f9b3ed7c8 148
rjpope42 0:3e9f9b3ed7c8 149 for(uint32_t j = 100000; j>0; j--)//display color for a couple seconds
rjpope42 0:3e9f9b3ed7c8 150 {
rjpope42 0:3e9f9b3ed7c8 151 for(int i = 8; i>0; i--)//
rjpope42 0:3e9f9b3ed7c8 152 {
rjpope42 0:3e9f9b3ed7c8 153 pwmvals[0] = (i - vals[0] == 0);//control brightness by turning LED on after x iterations
rjpope42 0:3e9f9b3ed7c8 154 pwmvals[1] = (i - vals[1] == 0);//could compare directly to str and save an array
rjpope42 0:3e9f9b3ed7c8 155 pwmvals[2] = (i - vals[2] == 0);
rjpope42 0:3e9f9b3ed7c8 156 NRF_GPIO->OUTCLR = (pwmvals[0] << LED_RED)|(pwmvals[1] << LED_GREEN)|(pwmvals[2] << LED_BLUE);
rjpope42 0:3e9f9b3ed7c8 157
rjpope42 0:3e9f9b3ed7c8 158 }
rjpope42 0:3e9f9b3ed7c8 159 NRF_GPIO->OUTSET = (0x7UL << LED_GREEN);//turn all 3 off
rjpope42 0:3e9f9b3ed7c8 160 }
rjpope42 0:3e9f9b3ed7c8 161 }
rjpope42 0:3e9f9b3ed7c8 162 }
rjpope42 0:3e9f9b3ed7c8 163
rjpope42 0:3e9f9b3ed7c8 164