UART BLE tested for IDB05A1 on STM32F411RE - communication between PC terminal and BLE terminal

Dependencies:   mbed X_NUCLEO_IDB0XA1 BLE_API

Fork of BLE_UART_perso by Joël Imbaud

Committer:
Nthnthj
Date:
Wed Nov 20 14:01:15 2019 +0000
Revision:
12:097314fded0c
Parent:
11:266332086ba5
Bon chance !

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pinofal 10:2d4a768ae727 1 #include "mbed.h"
pinofal 10:2d4a768ae727 2 #include "ble/BLE.h"
pinofal 10:2d4a768ae727 3 #include "ble/services/UARTService.h"
pinofal 10:2d4a768ae727 4 #include "Serial.h"
pinofal 10:2d4a768ae727 5
pinofal 10:2d4a768ae727 6 #define UART_BUFFER (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN*10)
pinofal 10:2d4a768ae727 7
pinofal 10:2d4a768ae727 8 const static char DEVICE_NAME[] = "UART";
pinofal 10:2d4a768ae727 9 UARTService *uartServicePtr;
pinofal 10:2d4a768ae727 10
jimbaud 11:266332086ba5 11 // Def Peripheriques
jimbaud 11:266332086ba5 12 DigitalOut Led1(LED1); // LED
jimbaud 11:266332086ba5 13 Serial pcUSB(USBTX,USBRX); // Terminal PC
jimbaud 11:266332086ba5 14 DigitalIn myButton(USER_BUTTON); // USER BUTTON
pinofal 10:2d4a768ae727 15
pinofal 10:2d4a768ae727 16
jimbaud 11:266332086ba5 17 // Tableau et index de communication avec UART
pinofal 10:2d4a768ae727 18 static uint8_t uartBuff[UART_BUFFER];
pinofal 10:2d4a768ae727 19 static uint8_t uartBuffPos=0;
pinofal 10:2d4a768ae727 20
jimbaud 11:266332086ba5 21 // Routine de traitement des erreurs
pinofal 10:2d4a768ae727 22 void onBleError(ble_error_t error);
pinofal 10:2d4a768ae727 23
jimbaud 11:266332086ba5 24 // Signal de vie
pinofal 10:2d4a768ae727 25 Ticker LifeTicker;
pinofal 10:2d4a768ae727 26
pinofal 10:2d4a768ae727 27 /****************************************************/
jimbaud 11:266332086ba5 28 /* Ticker actif lorsque la connexion BLE est présente */
pinofal 10:2d4a768ae727 29 /****************************************************/
pinofal 10:2d4a768ae727 30 void ConnectedBLE(void)
pinofal 10:2d4a768ae727 31 {
jimbaud 11:266332086ba5 32 // Signal de vie: allumer et éteindre la LED
pinofal 10:2d4a768ae727 33 Led1 = !Led1;
pinofal 10:2d4a768ae727 34 }
pinofal 10:2d4a768ae727 35
jimbaud 11:266332086ba5 36 /***************************/
jimbaud 11:266332086ba5 37 /* Rx d'USB et Tx vers BLE */
jimbaud 11:266332086ba5 38 /***************************/
pinofal 10:2d4a768ae727 39 void uartRx(void)
pinofal 10:2d4a768ae727 40 {
jimbaud 11:266332086ba5 41 // Capturez les caractères depuis le terminal jusqu'à la fin du message: a '\ r' ou '\ n' ou jusqu'à ce que la taille maximale du message soit atteinte
jimbaud 11:266332086ba5 42 if(pcUSB.readable()) {
pinofal 10:2d4a768ae727 43 uartBuff[uartBuffPos] = pcUSB.getc();
jimbaud 11:266332086ba5 44 if((uartBuff[uartBuffPos] == '\r') || (uartBuff[uartBuffPos] == '\n') || (uartBuffPos >= UART_BUFFER)) {
jimbaud 11:266332086ba5 45 // insère un NUL dans la dernière position de la chaîne
pinofal 10:2d4a768ae727 46 uartBuff[uartBuffPos] = '\0';
jimbaud 11:266332086ba5 47 // Envoie la chaîne entière même si elle est inférieure à BLE_UART_SERVICE_MAX_DATA_LEN, sinon attente
pinofal 10:2d4a768ae727 48 uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN);
jimbaud 11:266332086ba5 49 // Envoie une confirmation au terminal PC avec la chaîne envoyée au BLE
jimbaud 11:266332086ba5 50 pcUSB.printf("TX : %s\r\n", uartBuff);
jimbaud 11:266332086ba5 51 // Réinitialiser la chaîne uartBuff en entrant 0 dans les premiers caractères UART_BUFFER
pinofal 10:2d4a768ae727 52 memset(uartBuff, 0, UART_BUFFER);
pinofal 10:2d4a768ae727 53 uartBuffPos = 0;
jimbaud 11:266332086ba5 54 } else {
jimbaud 11:266332086ba5 55 // Si la fin du message n'a pas été atteinte, augmentez le compteur pour recevoir le caractère suivant
pinofal 10:2d4a768ae727 56 uartBuffPos++;
pinofal 10:2d4a768ae727 57 }
pinofal 10:2d4a768ae727 58 }
pinofal 10:2d4a768ae727 59 }
pinofal 10:2d4a768ae727 60
jimbaud 11:266332086ba5 61 /*************************/
jimbaud 11:266332086ba5 62 /* Connexion BLE réussie */
jimbaud 11:266332086ba5 63 /*************************/
jimbaud 11:266332086ba5 64 void BleConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
pinofal 10:2d4a768ae727 65 {
pinofal 10:2d4a768ae727 66 pcUSB.printf("BLE Client Connected!\n\r");
pinofal 10:2d4a768ae727 67 pcUSB.printf("Please type a string and press return\r\n");
pinofal 10:2d4a768ae727 68
jimbaud 11:266332086ba5 69 // Signal de connexion BLE: allume / éteint la LED avec une période de 1 seconde
pinofal 10:2d4a768ae727 70 LifeTicker.attach(ConnectedBLE, 1);
pinofal 10:2d4a768ae727 71 }
pinofal 10:2d4a768ae727 72
jimbaud 11:266332086ba5 73 /*****************************/
jimbaud 11:266332086ba5 74 /* Déconnexion du client BLE */
jimbaud 11:266332086ba5 75 /*****************************/
pinofal 10:2d4a768ae727 76 void BleDisconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
pinofal 10:2d4a768ae727 77 {
pinofal 10:2d4a768ae727 78 (void)params;
pinofal 10:2d4a768ae727 79 pcUSB.printf("BLE Client Disconnected!\r\n");
jimbaud 11:266332086ba5 80 // Désactiver le signal de connexion BLE: allumer / éteindre la LED avec une période de 1 seconde
pinofal 10:2d4a768ae727 81 LifeTicker.detach();
jimbaud 11:266332086ba5 82
jimbaud 11:266332086ba5 83 // Redémarrer la publicité
jimbaud 11:266332086ba5 84 BLE::Instance().gap().startAdvertising();
pinofal 10:2d4a768ae727 85 Led1=0;
pinofal 10:2d4a768ae727 86 }
pinofal 10:2d4a768ae727 87
jimbaud 11:266332086ba5 88 /***************************/
jimbaud 11:266332086ba5 89 /* Rx de BLE et Rx vers USB*/
jimbaud 11:266332086ba5 90 /***************************/
jimbaud 11:266332086ba5 91 void BleOnDataWrittenCallback(const GattWriteCallbackParams *params)
pinofal 10:2d4a768ae727 92 {
jimbaud 11:266332086ba5 93 // Chaîne de réponse en cas de réception pas OK
jimbaud 11:266332086ba5 94 #define REPLYNOTOK "Rx not Ok :("
jimbaud 11:266332086ba5 95 // Chaîne de réponse en cas de réception OK
jimbaud 11:266332086ba5 96 #define REPLYOK "Rx Ok :)"
jimbaud 11:266332086ba5 97 // Chaîne de référence
jimbaud 11:266332086ba5 98 #define REFERENCESTRING "bho"
jimbaud 11:266332086ba5 99
pinofal 10:2d4a768ae727 100 char caReply[UART_BUFFER];
pinofal 10:2d4a768ae727 101 //uint8_t uaAux[UART_BUFFER];
pinofal 10:2d4a768ae727 102 int nReplyLength;
jimbaud 11:266332086ba5 103
jimbaud 11:266332086ba5 104 // Résultat de la comparaison entre srting
jimbaud 11:266332086ba5 105 int nResult;
jimbaud 11:266332086ba5 106
jimbaud 11:266332086ba5 107 // Réinitialiser la chaîne auxiliaire pour composer les réponses
pinofal 10:2d4a768ae727 108 memset(caReply, 0, UART_BUFFER);
jimbaud 11:266332086ba5 109
jimbaud 11:266332086ba5 110 // Reçoit une chaîne de BLE
jimbaud 11:266332086ba5 111 if (params->handle == uartServicePtr->getTXCharacteristicHandle()) {
jimbaud 11:266332086ba5 112 // Envoie la chaîne reçue au PC
jimbaud 11:266332086ba5 113 pcUSB.printf("RX: %s\r\n", params->data);
jimbaud 11:266332086ba5 114
jimbaud 11:266332086ba5 115 uartServicePtr->write(uartBuff, (uartBuffPos/UARTService::BLE_UART_SERVICE_MAX_DATA_LEN +1) * UARTService::BLE_UART_SERVICE_MAX_DATA_LEN);
jimbaud 11:266332086ba5 116
pinofal 10:2d4a768ae727 117 }
pinofal 10:2d4a768ae727 118 }
pinofal 10:2d4a768ae727 119
jimbaud 11:266332086ba5 120 /***************************/
jimbaud 11:266332086ba5 121 /* Erreur sur le canal BLE */
jimbaud 11:266332086ba5 122 /***************************/
jimbaud 11:266332086ba5 123
jimbaud 11:266332086ba5 124 void onBleError(ble_error_t error)
jimbaud 11:266332086ba5 125 {
pinofal 10:2d4a768ae727 126 pcUSB.printf("BLE Error: %d\r\n");
jimbaud 11:266332086ba5 127 /* Entrer le traitement des erreurs */
jimbaud 11:266332086ba5 128 }
pinofal 10:2d4a768ae727 129
jimbaud 11:266332086ba5 130 /**************************************/
jimbaud 11:266332086ba5 131 /* Initialisation du service BLE UART */
jimbaud 11:266332086ba5 132 /**************************************/
jimbaud 11:266332086ba5 133
jimbaud 11:266332086ba5 134 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
pinofal 10:2d4a768ae727 135 {
pinofal 10:2d4a768ae727 136 BLE& ble = params->ble;
pinofal 10:2d4a768ae727 137 ble_error_t error = params->error;
pinofal 10:2d4a768ae727 138
jimbaud 11:266332086ba5 139 if (error != BLE_ERROR_NONE) {
jimbaud 11:266332086ba5 140
jimbaud 11:266332086ba5 141 /* En cas d'erreur, transmettez le traitement d'erreur à onBleInitError*/
pinofal 10:2d4a768ae727 142 onBleError(error);
pinofal 10:2d4a768ae727 143 return;
pinofal 10:2d4a768ae727 144 }
pinofal 10:2d4a768ae727 145
jimbaud 11:266332086ba5 146 /* Assurez-vous qu'il s'agit de l'instance par défaut de BLE */
jimbaud 11:266332086ba5 147 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
pinofal 10:2d4a768ae727 148 return;
pinofal 10:2d4a768ae727 149 }
pinofal 10:2d4a768ae727 150
pinofal 10:2d4a768ae727 151 ble.gap().onConnection(BleConnectionCallback);
pinofal 10:2d4a768ae727 152 ble.gap().onDisconnection(BleDisconnectionCallback);
pinofal 10:2d4a768ae727 153 ble.gattServer().onDataWritten(BleOnDataWrittenCallback);
pinofal 10:2d4a768ae727 154
pinofal 10:2d4a768ae727 155 pcUSB.printf("BLE UARTService: ");
jimbaud 11:266332086ba5 156
jimbaud 11:266332086ba5 157 /* Configuration du service primaire. */
pinofal 10:2d4a768ae727 158 UARTService uartService(ble);
pinofal 10:2d4a768ae727 159 uartServicePtr = &uartService;
jimbaud 11:266332086ba5 160
pinofal 10:2d4a768ae727 161 pcUSB.printf("Started\r\n");
pinofal 10:2d4a768ae727 162
jimbaud 11:266332086ba5 163 /* Configurer la publicité */
pinofal 10:2d4a768ae727 164 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
pinofal 10:2d4a768ae727 165 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
pinofal 10:2d4a768ae727 166 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
pinofal 10:2d4a768ae727 167 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
pinofal 10:2d4a768ae727 168 ble.gap().setAdvertisingInterval(500); /* 500ms. */
pinofal 10:2d4a768ae727 169 ble.gap().startAdvertising();
pinofal 10:2d4a768ae727 170
jimbaud 11:266332086ba5 171 // Attend les événements sur BLE
jimbaud 11:266332086ba5 172 while (true) {
pinofal 10:2d4a768ae727 173 ble.waitForEvent();
pinofal 10:2d4a768ae727 174 }
pinofal 10:2d4a768ae727 175 }
pinofal 10:2d4a768ae727 176
pinofal 10:2d4a768ae727 177 /********/
pinofal 10:2d4a768ae727 178 /* MAIN */
pinofal 10:2d4a768ae727 179 /********/
pinofal 10:2d4a768ae727 180 int main(void)
pinofal 10:2d4a768ae727 181 {
jimbaud 11:266332086ba5 182
jimbaud 11:266332086ba5 183 // Configurer la vitesse de communication série sur USB-VirtualCom et envoyer un message de bienvenue
jimbaud 11:266332086ba5 184 pcUSB.baud(9600); //9600 bps
pinofal 10:2d4a768ae727 185
jimbaud 11:266332086ba5 186 // Message de bienvenue
jimbaud 11:266332086ba5 187 pcUSB.printf("\r\n*** Bluetooth to PC serial communication ***\r\n");
jimbaud 11:266332086ba5 188
jimbaud 11:266332086ba5 189 //Définit le fonctionnement du bouton sur "PullDown": Open = '0'. L’autre mode de fonctionnement est PullUp
pinofal 10:2d4a768ae727 190 myButton.mode(PullDown);
jimbaud 11:266332086ba5 191
jimbaud 11:266332086ba5 192 // Initialiser LED
pinofal 10:2d4a768ae727 193 Led1=0;
jimbaud 11:266332086ba5 194
jimbaud 11:266332086ba5 195 // IRQ associée à la réception de caractères de série à USB depuis un PC
pinofal 10:2d4a768ae727 196 pcUSB.attach(uartRx,Serial::RxIrq);
jimbaud 11:266332086ba5 197
jimbaud 11:266332086ba5 198 /****** START Initialiser BLE **********/
pinofal 10:2d4a768ae727 199 BLE &ble = BLE::Instance();
pinofal 10:2d4a768ae727 200 ble.init(bleInitComplete);
jimbaud 11:266332086ba5 201 /******* FIN initialise BLE ***********/
pinofal 10:2d4a768ae727 202 }
pinofal 10:2d4a768ae727 203