Pulse Oximeter (NONIN) communicates with mbed via Bluetooth dongle and sends Heart Rate and Oxygen Saturation via GPRS module

Dependencies:   C12832 GPS GSM mbed

Fork of myBlueUSB_localfix by Nobuaki Aoki

Committer:
samialshorman
Date:
Tue Apr 14 21:48:07 2015 +0000
Revision:
3:55a622e3dbb5
Parent:
0:003889bc474f
Nonin (Pulse Oximeter) connected to mbed lpc 1768 by Bluetooth dongle and sends SMS including Heart Rate and Oxygen saturation by GPRS module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nobukuma 0:003889bc474f 1
nobukuma 0:003889bc474f 2 /*
nobukuma 0:003889bc474f 3 Copyright (c) 2010 Peter Barrett
nobukuma 0:003889bc474f 4
nobukuma 0:003889bc474f 5 Permission is hereby granted, free of charge, to any person obtaining a copy
nobukuma 0:003889bc474f 6 of this software and associated documentation files (the "Software"), to deal
nobukuma 0:003889bc474f 7 in the Software without restriction, including without limitation the rights
nobukuma 0:003889bc474f 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
nobukuma 0:003889bc474f 9 copies of the Software, and to permit persons to whom the Software is
nobukuma 0:003889bc474f 10 furnished to do so, subject to the following conditions:
nobukuma 0:003889bc474f 11
nobukuma 0:003889bc474f 12 The above copyright notice and this permission notice shall be included in
nobukuma 0:003889bc474f 13 all copies or substantial portions of the Software.
nobukuma 0:003889bc474f 14
nobukuma 0:003889bc474f 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
nobukuma 0:003889bc474f 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
nobukuma 0:003889bc474f 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
nobukuma 0:003889bc474f 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
nobukuma 0:003889bc474f 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
nobukuma 0:003889bc474f 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
nobukuma 0:003889bc474f 21 THE SOFTWARE.
nobukuma 0:003889bc474f 22 */
nobukuma 0:003889bc474f 23
nobukuma 0:003889bc474f 24 #include "mbed.h"
nobukuma 0:003889bc474f 25 #include "USBHost.h"
nobukuma 0:003889bc474f 26 #include "Utils.h"
nobukuma 0:003889bc474f 27
nobukuma 0:003889bc474f 28 #define AUTOEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol)
nobukuma 0:003889bc474f 29 #define AUTO_KEYBOARD AUTOEVT(CLASS_HID,1,1)
nobukuma 0:003889bc474f 30 #define AUTO_MOUSE AUTOEVT(CLASS_HID,1,2)
nobukuma 0:003889bc474f 31
nobukuma 0:003889bc474f 32 u8 auto_mouse[4]; // buttons,dx,dy,scroll
nobukuma 0:003889bc474f 33 u8 auto_keyboard[8]; // modifiers,reserved,keycode1..keycode6
nobukuma 0:003889bc474f 34 u8 auto_joystick[4]; // x,y,buttons,throttle
nobukuma 0:003889bc474f 35
nobukuma 0:003889bc474f 36 void AutoEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData) {
nobukuma 0:003889bc474f 37 int evt = (int)userData;
nobukuma 0:003889bc474f 38 switch (evt) {
nobukuma 0:003889bc474f 39 case AUTO_KEYBOARD:
nobukuma 0:003889bc474f 40 printf("AUTO_KEYBOARD ");
nobukuma 0:003889bc474f 41 break;
nobukuma 0:003889bc474f 42 case AUTO_MOUSE:
nobukuma 0:003889bc474f 43 printf("AUTO_MOUSE ");
nobukuma 0:003889bc474f 44 break;
nobukuma 0:003889bc474f 45 default:
nobukuma 0:003889bc474f 46 printf("HUH ");
nobukuma 0:003889bc474f 47 }
nobukuma 0:003889bc474f 48 printfBytes("data",data,len);
nobukuma 0:003889bc474f 49 USBInterruptTransfer(device,endpoint,data,len,AutoEventCallback,userData);
nobukuma 0:003889bc474f 50 }
nobukuma 0:003889bc474f 51
nobukuma 0:003889bc474f 52 // Establish transfers for interrupt events
nobukuma 0:003889bc474f 53 void AddAutoEvent(int device, InterfaceDescriptor* id, EndpointDescriptor* ed) {
nobukuma 0:003889bc474f 54 if ((ed->bmAttributes & 3) != ENDPOINT_INTERRUPT || !(ed->bEndpointAddress & 0x80))
nobukuma 0:003889bc474f 55 return;
nobukuma 0:003889bc474f 56
nobukuma 0:003889bc474f 57 // Make automatic interrupt enpoints for known devices
nobukuma 0:003889bc474f 58 u32 evt = AUTOEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol);
nobukuma 0:003889bc474f 59 u8* dst = 0;
nobukuma 0:003889bc474f 60 int len;
nobukuma 0:003889bc474f 61 switch (evt) {
nobukuma 0:003889bc474f 62 case AUTO_MOUSE:
nobukuma 0:003889bc474f 63 dst = auto_mouse;
nobukuma 0:003889bc474f 64 len = sizeof(auto_mouse);
nobukuma 0:003889bc474f 65 break;
nobukuma 0:003889bc474f 66 case AUTO_KEYBOARD:
nobukuma 0:003889bc474f 67 dst = auto_keyboard;
nobukuma 0:003889bc474f 68 len = sizeof(auto_keyboard);
nobukuma 0:003889bc474f 69 break;
nobukuma 0:003889bc474f 70 default:
nobukuma 0:003889bc474f 71 printf("Interrupt endpoint %02X %08X\n",ed->bEndpointAddress,evt);
nobukuma 0:003889bc474f 72 break;
nobukuma 0:003889bc474f 73 }
nobukuma 0:003889bc474f 74 if (dst) {
nobukuma 0:003889bc474f 75 printf("Auto Event for %02X %08X\n",ed->bEndpointAddress,evt);
nobukuma 0:003889bc474f 76 USBInterruptTransfer(device,ed->bEndpointAddress,dst,len,AutoEventCallback,(void*)evt);
nobukuma 0:003889bc474f 77 }
nobukuma 0:003889bc474f 78 }
nobukuma 0:003889bc474f 79
nobukuma 0:003889bc474f 80 void PrintString(int device, int i) {
nobukuma 0:003889bc474f 81 u8 buffer[256];
nobukuma 0:003889bc474f 82 int le = GetDescriptor(device,DESCRIPTOR_TYPE_STRING,i,buffer,255);
nobukuma 0:003889bc474f 83 if (le < 0)
nobukuma 0:003889bc474f 84 return;
nobukuma 0:003889bc474f 85 char* dst = (char*)buffer;
nobukuma 0:003889bc474f 86 for (int j = 2; j < le; j += 2)
nobukuma 0:003889bc474f 87 *dst++ = buffer[j];
nobukuma 0:003889bc474f 88 *dst = 0;
nobukuma 0:003889bc474f 89 printf("%d:%s\n",i,(const char*)buffer);
nobukuma 0:003889bc474f 90 }
nobukuma 0:003889bc474f 91
nobukuma 0:003889bc474f 92 // Walk descriptors and create endpoints for a given device
nobukuma 0:003889bc474f 93 int StartAutoEvent(int device, int configuration, int interfaceNumber) {
nobukuma 0:003889bc474f 94 u8 buffer[255];
nobukuma 0:003889bc474f 95 int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255);
nobukuma 0:003889bc474f 96 if (err < 0)
nobukuma 0:003889bc474f 97 return err;
nobukuma 0:003889bc474f 98
nobukuma 0:003889bc474f 99 int len = buffer[2] | (buffer[3] << 8);
nobukuma 0:003889bc474f 100 u8* d = buffer;
nobukuma 0:003889bc474f 101 u8* end = d + len;
nobukuma 0:003889bc474f 102 while (d < end) {
nobukuma 0:003889bc474f 103 if (d[1] == DESCRIPTOR_TYPE_INTERFACE) {
nobukuma 0:003889bc474f 104 InterfaceDescriptor* id = (InterfaceDescriptor*)d;
nobukuma 0:003889bc474f 105 if (id->bInterfaceNumber == interfaceNumber) {
nobukuma 0:003889bc474f 106 d += d[0];
nobukuma 0:003889bc474f 107 while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE) {
nobukuma 0:003889bc474f 108 if (d[1] == DESCRIPTOR_TYPE_ENDPOINT)
nobukuma 0:003889bc474f 109 AddAutoEvent(device,id,(EndpointDescriptor*)d);
nobukuma 0:003889bc474f 110 d += d[0];
nobukuma 0:003889bc474f 111 }
nobukuma 0:003889bc474f 112 }
nobukuma 0:003889bc474f 113 }
nobukuma 0:003889bc474f 114 d += d[0];
nobukuma 0:003889bc474f 115 }
nobukuma 0:003889bc474f 116 return 0;
nobukuma 0:003889bc474f 117 }
nobukuma 0:003889bc474f 118
nobukuma 0:003889bc474f 119 // Implemented in main.cpp
nobukuma 0:003889bc474f 120 int OnDiskInsert(int device, unsigned char in, unsigned char out);
nobukuma 0:003889bc474f 121
nobukuma 0:003889bc474f 122 // Implemented in TestShell.cpp
nobukuma 0:003889bc474f 123 int OnBluetoothInsert(int device);
nobukuma 0:003889bc474f 124
nobukuma 0:003889bc474f 125 EndpointDescriptor* GetNextEndpoint(unsigned char *d) {
nobukuma 0:003889bc474f 126 while (d) {
nobukuma 0:003889bc474f 127 switch (d[1]) {
nobukuma 0:003889bc474f 128 case DESCRIPTOR_TYPE_INTERFACE:
nobukuma 0:003889bc474f 129 case DESCRIPTOR_TYPE_CONFIGURATION:
nobukuma 0:003889bc474f 130 return 0;
nobukuma 0:003889bc474f 131 case DESCRIPTOR_TYPE_ENDPOINT:
nobukuma 0:003889bc474f 132 return (EndpointDescriptor*)d;
nobukuma 0:003889bc474f 133 default:
nobukuma 0:003889bc474f 134 printf("Skipping descriptor %02X (%d bytes)\n",d[1],d[0]);
nobukuma 0:003889bc474f 135 }
nobukuma 0:003889bc474f 136 d += d[0];
nobukuma 0:003889bc474f 137 }
nobukuma 0:003889bc474f 138 return 0;
nobukuma 0:003889bc474f 139 }
nobukuma 0:003889bc474f 140
nobukuma 0:003889bc474f 141 EndpointDescriptor* GetEndpoint(InterfaceDescriptor* interfaceDesc, int i) {
nobukuma 0:003889bc474f 142 unsigned char *d = (unsigned char*)interfaceDesc;
nobukuma 0:003889bc474f 143 int n = interfaceDesc->bNumEndpoints;
nobukuma 0:003889bc474f 144 int j = 0;
nobukuma 0:003889bc474f 145 if (i >= n)
nobukuma 0:003889bc474f 146 return 0;
nobukuma 0:003889bc474f 147 d += d[0];//move to first descriptor after the interface descriptor
nobukuma 0:003889bc474f 148 while (j < n) {
nobukuma 0:003889bc474f 149 switch (d[1]) {
nobukuma 0:003889bc474f 150 case DESCRIPTOR_TYPE_INTERFACE:
nobukuma 0:003889bc474f 151 case DESCRIPTOR_TYPE_CONFIGURATION:
nobukuma 0:003889bc474f 152 return 0;
nobukuma 0:003889bc474f 153 case DESCRIPTOR_TYPE_ENDPOINT:
nobukuma 0:003889bc474f 154 if (i == j)
nobukuma 0:003889bc474f 155 return (EndpointDescriptor*)d;
nobukuma 0:003889bc474f 156 j++;
nobukuma 0:003889bc474f 157 break;
nobukuma 0:003889bc474f 158 default:
nobukuma 0:003889bc474f 159 printf("Skipping descriptor %02X (%d bytes)\n",d[1],d[0]);
nobukuma 0:003889bc474f 160 }
nobukuma 0:003889bc474f 161 d += d[0];
nobukuma 0:003889bc474f 162 }
nobukuma 0:003889bc474f 163 return 0;
nobukuma 0:003889bc474f 164 }
nobukuma 0:003889bc474f 165
nobukuma 0:003889bc474f 166 void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) {
nobukuma 0:003889bc474f 167 printf("LoadDevice %d %02X:%02X:%02X\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
nobukuma 0:003889bc474f 168 char s[128];
nobukuma 0:003889bc474f 169 for (int i = 1; i < 3; i++) {
nobukuma 0:003889bc474f 170 if (GetString(device,i,s,sizeof(s)) < 0)
nobukuma 0:003889bc474f 171 break;
nobukuma 0:003889bc474f 172 printf("%d: %s\n",i,s);
nobukuma 0:003889bc474f 173 }
nobukuma 0:003889bc474f 174
nobukuma 0:003889bc474f 175 switch (interfaceDesc->bInterfaceClass) {
nobukuma 0:003889bc474f 176 case CLASS_MASS_STORAGE:
nobukuma 0:003889bc474f 177 if (interfaceDesc->bInterfaceSubClass == 0x06 && interfaceDesc->bInterfaceProtocol == 0x50) {
nobukuma 0:003889bc474f 178 unsigned char epin = 0x81;
nobukuma 0:003889bc474f 179 unsigned char epout = 0x01;
nobukuma 0:003889bc474f 180 for (int i = 0; i < interfaceDesc->bNumEndpoints; i++){
nobukuma 0:003889bc474f 181 EndpointDescriptor* ep = GetEndpoint(interfaceDesc, i);
nobukuma 0:003889bc474f 182 if (ep){
nobukuma 0:003889bc474f 183 if (ep->bEndpointAddress & 0x7F)
nobukuma 0:003889bc474f 184 if (ep->bEndpointAddress & 0x80)
nobukuma 0:003889bc474f 185 epin = ep->bEndpointAddress;
nobukuma 0:003889bc474f 186 else
nobukuma 0:003889bc474f 187 epout = ep->bEndpointAddress;
nobukuma 0:003889bc474f 188 }else break;
nobukuma 0:003889bc474f 189 }
nobukuma 0:003889bc474f 190 printf("In = %02X, Out = %02X\n", epin, epout);
nobukuma 0:003889bc474f 191 OnDiskInsert(device, epin, epout); // it's SCSI!
nobukuma 0:003889bc474f 192 }
nobukuma 0:003889bc474f 193 break;
nobukuma 0:003889bc474f 194 case CLASS_WIRELESS_CONTROLLER:
nobukuma 0:003889bc474f 195 if (interfaceDesc->bInterfaceSubClass == 0x01 && interfaceDesc->bInterfaceProtocol == 0x01)
nobukuma 0:003889bc474f 196 OnBluetoothInsert(device); // it's bluetooth!
nobukuma 0:003889bc474f 197 break;
nobukuma 0:003889bc474f 198 default:
nobukuma 0:003889bc474f 199 StartAutoEvent(device,1,0);
nobukuma 0:003889bc474f 200 break;
nobukuma 0:003889bc474f 201 }
nobukuma 0:003889bc474f 202 }