Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Hexiwear HexiwearFinal HexiwearFinal1
Fork of Hexi_KW40Z by
Hexi_KW40Z.cpp
00001 /** BLE KW40Z Driver for Hexiwear 00002 * This file contains BLE and Touch Buttons driver functionality for Hexiwear 00003 * 00004 * Redistribution and use in source and binary forms, with or without modification, 00005 * are permitted provided that the following conditions are met: 00006 * 00007 * Redistributions of source code must retain the above copyright notice, this list 00008 * of conditions and the following disclaimer. 00009 * 00010 * Redistributions in binary form must reproduce the above copyright notice, this 00011 * list of conditions and the following disclaimer in the documentation and/or 00012 * other materials provided with the distribution. 00013 * 00014 * Neither the name of NXP, nor the names of its 00015 * contributors may be used to endorse or promote products derived from this 00016 * software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00021 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00022 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00024 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00025 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00026 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00027 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 * 00029 * visit: http://www.mikroe.com and http://www.nxp.com 00030 * 00031 * get support at: http://www.mikroe.com/forum and https://community.nxp.com 00032 * 00033 * Project HEXIWEAR, 2015 00034 */ 00035 00036 #include "Hexi_KW40Z.h" 00037 00038 #if defined (LIB_DEBUG) 00039 RawSerial pc(USBTX, USBRX); // tx, rx 00040 #endif 00041 00042 KW40Z::KW40Z(PinName txPin,PinName rxPin) : device(txPin, rxPin), mainThread(&KW40Z::mainStarter, this, osPriorityNormal,1024), rxThread(&KW40Z::rxStarter, this, osPriorityNormal,1024) 00043 { 00044 #if defined (LIB_DEBUG) 00045 pc.baud(115200); 00046 pc.printf("Initializing\r\n"); 00047 #endif 00048 00049 device.baud(230400); 00050 device.format(8, Serial::None, 2); 00051 00052 rxBuff = (uint8_t*)&hostInterface_rxPacket; 00053 00054 /* initialize callbacks */ 00055 buttonUpCb = NULL; 00056 buttonDownCb = NULL; 00057 buttonLeftCb = NULL; 00058 buttonRightCb = NULL; 00059 buttonSlideCb = NULL; 00060 alertCb = NULL; 00061 passkeyCb = NULL; 00062 notificationsCb = NULL; 00063 00064 /* intialization finalized, signal to start the threads */ 00065 mainThread.signal_set(START_THREAD); 00066 rxThread.signal_set(START_THREAD); 00067 } 00068 00069 KW40Z::~KW40Z(void) 00070 { 00071 } 00072 00073 void KW40Z::attach_buttonUp(button_t btnFct) 00074 { 00075 buttonUpCb = btnFct; 00076 } 00077 void KW40Z::attach_buttonDown(button_t btnFct) 00078 { 00079 buttonDownCb = btnFct; 00080 } 00081 00082 void KW40Z::attach_buttonLeft(button_t btnFct) 00083 { 00084 buttonLeftCb = btnFct; 00085 } 00086 00087 void KW40Z::attach_buttonRight(button_t btnFct) 00088 { 00089 buttonRightCb = btnFct; 00090 } 00091 00092 void KW40Z::attach_buttonSlide(button_t btnFct) 00093 { 00094 buttonSlideCb = btnFct; 00095 } 00096 00097 void KW40Z::attach_alert(alert_t alertFct) 00098 { 00099 alertCb = alertFct; 00100 } 00101 00102 void KW40Z::attach_passkey(passkey_t passkeyFct) 00103 { 00104 passkeyCb = passkeyFct; 00105 } 00106 00107 void KW40Z::attach_notifications(notifications_t notFct) 00108 { 00109 notificationsCb = notFct; 00110 } 00111 00112 void KW40Z::rxStarter(void const *p) { 00113 KW40Z *instance = (KW40Z*)p; 00114 instance->rxTask(); 00115 } 00116 00117 void KW40Z::mainStarter(void const *p) { 00118 KW40Z *instance = (KW40Z*)p; 00119 instance->mainTask(); 00120 } 00121 00122 void KW40Z::GetVersion() 00123 { 00124 hostInterface_packet_t txPacket = {0}; 00125 00126 txPacket.start1 = gHostInterface_startByte1, 00127 txPacket.start2 = gHostInterface_startByte2, 00128 txPacket.type = packetType_buildVersion, 00129 txPacket.length = 3, 00130 txPacket.data[0] = HEXIWEAR_VERSION_MAJOR; 00131 txPacket.data[1] = HEXIWEAR_VERSION_MINOR; 00132 txPacket.data[2] = HEXIWEAR_VERSION_PATCH; 00133 txPacket.data[3] = gHostInterface_trailerByte; 00134 00135 SendPacket(&txPacket, false); 00136 } 00137 00138 void KW40Z::SendPacket(hostInterface_packet_t * txPacket, bool confirmRequested) 00139 { 00140 uint8_t retries = 0; 00141 confirmReceived = false; 00142 00143 do 00144 { 00145 char * txBuff = (char *)txPacket; 00146 uint8_t length = txPacket->length + gHostInterface_headerSize + 1; 00147 00148 if(confirmRequested == true) 00149 { 00150 txPacket->start2 |= 0x01; 00151 } 00152 00153 for(uint8_t i = 0; i < length; i++) 00154 { 00155 device.putc(*txBuff); 00156 txBuff++; 00157 } 00158 00159 #if defined (LIB_DEBUG) 00160 DebugPrintTxPacket(txPacket); 00161 #endif 00162 00163 retries++; 00164 00165 #if defined (gHostInterface_RxConfirmationEnable) 00166 if((confirmRequested == true) && (confirmReceived == false)) 00167 { 00168 Thread::wait(gHostInterface_retransmitTimeout); 00169 } 00170 #endif 00171 } 00172 while((confirmRequested == true) && 00173 (confirmReceived == false) && 00174 (retries < gHostInterface_retransmitCount)); 00175 } 00176 00177 void KW40Z::mainTask(void) 00178 { 00179 mainThread.signal_wait(START_THREAD); 00180 00181 #if defined (LIB_DEBUG) 00182 pc.printf("MainTask Stared\r\n"); 00183 #endif 00184 00185 while(1) 00186 { 00187 osEvent evt = queue.get(); 00188 if (evt.status == osEventMessage) 00189 { 00190 hostInterface_packet_t *rxPacket = (hostInterface_packet_t*)evt.value.p; 00191 ProcessReceivedPacket(rxPacket); 00192 mpool.free(rxPacket); 00193 } 00194 } 00195 } 00196 00197 void KW40Z::rxTask(void) 00198 { 00199 rxThread.signal_wait(START_THREAD); 00200 00201 #if defined (LIB_DEBUG) 00202 pc.printf("RxTask Stared\r\n"); 00203 #endif 00204 00205 while(1) 00206 { 00207 if(device.readable()) 00208 { 00209 *rxBuff++ = device.getc(); 00210 ProcessBuffer(); 00211 00212 /* check for buffer overflow */ 00213 if(rxBuff >= ((uint8_t*)&hostInterface_rxPacket + sizeof(hostInterface_rxPacket))) 00214 { 00215 rxBuff = (uint8_t*)&hostInterface_rxPacket; 00216 } 00217 } 00218 } 00219 } 00220 00221 #if defined (LIB_DEBUG) 00222 void KW40Z::DebugPrintTxPacket(hostInterface_packet_t * txPacket) 00223 { 00224 char * txBuff = (char *)txPacket; 00225 uint8_t length = txPacket->length + gHostInterface_headerSize + 1; 00226 00227 pc.printf("Tx: "); 00228 for(uint8_t i = 0; i < length; i++) 00229 { 00230 pc.printf("%02X ",*txBuff); 00231 txBuff++; 00232 } 00233 pc.printf("\r\n"); 00234 } 00235 00236 void KW40Z::DebugPrintRxPacket() 00237 { 00238 pc.printf("RX: "); 00239 for(uint8_t * i = (uint8_t*)&hostInterface_rxPacket; i<rxBuff; i++) 00240 { 00241 pc.printf("%02X ",*i); 00242 } 00243 pc.printf("\r\n"); 00244 } 00245 #endif 00246 00247 void KW40Z::ProcessBuffer() 00248 { 00249 /* check if header has been received */ 00250 if(rxBuff > ((uint8_t*)&hostInterface_rxPacket + gHostInterface_headerSize)) 00251 { 00252 /* check packet header */ 00253 if((gHostInterface_startByte1 != hostInterface_rxPacket.start1)|| 00254 (gHostInterface_startByte2 != (hostInterface_rxPacket.start2 & 0xFE))|| 00255 (hostInterface_rxPacket.length > gHostInterface_dataSize)) 00256 { 00257 #if defined (LIB_DEBUG) 00258 DebugPrintRxPacket(); 00259 pc.printf("check header failed\r\n"); 00260 #endif 00261 00262 SearchStartByte(); 00263 } 00264 else 00265 { 00266 /* check data length */ 00267 if(rxBuff > ((uint8_t*)&hostInterface_rxPacket + gHostInterface_headerSize + hostInterface_rxPacket.length)) 00268 { 00269 /* check trailer byte */ 00270 if(gHostInterface_trailerByte != hostInterface_rxPacket.data[hostInterface_rxPacket.length]) 00271 { 00272 #if defined (LIB_DEBUG) 00273 DebugPrintRxPacket(); 00274 pc.printf("trailer byte failed\r\n"); 00275 #endif 00276 00277 SearchStartByte(); 00278 } 00279 else 00280 { 00281 00282 #if defined (gHostInterface_RxConfirmationEnable) 00283 if(hostInterface_rxPacket.type == packetType_OK) 00284 { 00285 confirmReceived = true; 00286 } 00287 #endif 00288 00289 /* send message to main task */ 00290 hostInterface_packet_t *rxPacket = mpool.alloc(); 00291 memcpy(rxPacket, &hostInterface_rxPacket, sizeof(hostInterface_packet_t)); 00292 queue.put(rxPacket); 00293 00294 #if defined (LIB_DEBUG) 00295 DebugPrintRxPacket(); 00296 #endif 00297 /* reset buffer position */ 00298 rxBuff = (uint8_t*)&hostInterface_rxPacket; 00299 } 00300 } 00301 } 00302 } 00303 } 00304 00305 void KW40Z::SearchStartByte() 00306 { 00307 bool found = false; 00308 uint8_t * rdIdx = (uint8_t*)&hostInterface_rxPacket + 1; 00309 00310 while(rdIdx < rxBuff) 00311 { 00312 if(*rdIdx == gHostInterface_startByte1) 00313 { 00314 uint32_t len = rxBuff - rdIdx; 00315 00316 memcpy(&hostInterface_rxPacket,rdIdx,len); 00317 rxBuff -= len; 00318 found = true; 00319 00320 #if defined (LIB_DEBUG) 00321 pc.printf("moving "); 00322 #endif 00323 break; 00324 } 00325 rdIdx++; 00326 } 00327 00328 if(!found) 00329 { 00330 /* reset buffer position */ 00331 rxBuff = (uint8_t*)&hostInterface_rxPacket; 00332 } 00333 00334 #if defined (LIB_DEBUG) 00335 pc.printf("search done\r\n"); 00336 DebugPrintRxPacket(); 00337 #endif 00338 } 00339 00340 void KW40Z::SendPacketOK() 00341 { 00342 hostInterface_packet_t txPacket = {0}; 00343 00344 txPacket.start1 = gHostInterface_startByte1, 00345 txPacket.start2 = gHostInterface_startByte2, 00346 txPacket.type = packetType_OK, 00347 txPacket.length = 0, 00348 txPacket.data[0] = gHostInterface_trailerByte; 00349 00350 SendPacket(&txPacket, false); 00351 } 00352 00353 void KW40Z::ConfirmPacketOK() 00354 { 00355 } 00356 00357 void KW40Z::ProcessReceivedPacket(hostInterface_packet_t * rxPacket) 00358 { 00359 #if defined (LIB_DEBUG) 00360 pc.printf("packet found %d\r\n", rxPacket->type); 00361 #endif 00362 00363 #ifdef gHostInterface_TxConfirmationEnable 00364 // acknowledge the packet reception 00365 if ( 1 == ( rxPacket->start2 & 0x01 ) ) 00366 { 00367 SendPacketOK(); 00368 } 00369 #endif 00370 00371 switch(rxPacket->type) 00372 { 00373 /* button presses */ 00374 case packetType_pressUp: 00375 if(buttonUpCb != NULL) buttonUpCb(); 00376 break; 00377 00378 case packetType_pressDown: 00379 if(buttonDownCb != NULL) buttonDownCb(); 00380 break; 00381 00382 case packetType_pressLeft: 00383 if(buttonLeftCb != NULL) buttonLeftCb(); 00384 break; 00385 00386 case packetType_pressRight: 00387 if(buttonRightCb != NULL) buttonRightCb(); 00388 break; 00389 00390 case packetType_slide: 00391 if(buttonSlideCb != NULL) buttonSlideCb(); 00392 break; 00393 00394 /* Alert Service */ 00395 case packetType_alertIn: 00396 if(alertCb != NULL) alertCb(&rxPacket->data[0], rxPacket->length); 00397 break; 00398 00399 /* Passkey for pairing received */ 00400 case packetType_passDisplay: 00401 if(passkeyCb != NULL) passkeyCb(&rxPacket->data[0]); 00402 break; 00403 00404 /* OTAP messages */ 00405 case packetType_otapCompleted: 00406 case packetType_otapFailed: 00407 break; 00408 00409 /* TSI Status */ 00410 case packetType_buttonsGroupSendActive: 00411 break; 00412 00413 /* Advertisement Mode Info */ 00414 case packetType_advModeSend: 00415 break; 00416 00417 /* Link State */ 00418 case packetType_linkStateSend: 00419 break; 00420 00421 /* ANCS Service Notification Received */ 00422 case packetType_notification: 00423 if(notificationsCb != NULL) notificationsCb(rxPacket->data[0], rxPacket->data[1]); 00424 break; 00425 00426 /* Build version */ 00427 case packetType_buildVersion: 00428 break; 00429 00430 case packetType_OK: 00431 /* do nothing, the flag is set in the RxTask */ 00432 break; 00433 00434 default: 00435 break; 00436 } 00437 }
Generated on Sun Jul 24 2022 11:36:58 by
1.7.2
