Damian Gabino / picoGW_mcu
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cmdUSB.cpp Source File

cmdUSB.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007   (C)2017 Semtech
00008 
00009 */
00010 
00011 #include "cmdUSB.h"
00012 #include "usb_device.h"
00013 #include "usbd_cdc_if.h"
00014 #include "loragw_hal.h"
00015 #include "loragw_reg.h"
00016 #include "mbed.h"
00017 #include "board.h"
00018 
00019 #define DELAY_COM_INIT 1000
00020 #define DELAY_RESET 200
00021 
00022 /*
00023 /Class INTERFACE definition
00024 */
00025 
00026 INTERFACE::INTERFACE()
00027 {
00028 }
00029 
00030 /*
00031 /Class COMUSB definition
00032 */
00033 
00034 COMUSB::COMUSB() : INTERFACE()
00035 {
00036 }
00037 void COMUSB::Init() {
00038     __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
00039     MX_USB_DEVICE_Init();
00040 }
00041 
00042 void COMUSB::Receive(uint8_t * Buffer, uint32_t * size) {
00043     CDC_Receive_FSP(Buffer,size);// wait interrrupt manage in HAL_PCD_DataOutStageCallback
00044 }
00045 
00046 void COMUSB::Transmit(uint8_t * Buffer, uint16_t size) {
00047     if ((size % 64) == 0) { // for ZLP
00048         size = size + 1;
00049     } else {
00050         size = size;
00051     }
00052     while (CDC_Transmit_FS(Buffer, size) != USBD_OK){
00053     }
00054 }
00055 
00056 /*
00057 /Class COMUART definition
00058 */
00059 
00060 COMUART::COMUART(PinName Tx, PinName Rx) : Serial(Tx, Rx), INTERFACE()
00061 {
00062     //do nothing
00063 }
00064 
00065 void COMUART::Init() {
00066     baud(BAUDRATE);
00067 }
00068 
00069 void COMUART::Receive(uint8_t * Buffer, uint32_t * size) {
00070     uint16_t localSize = 0;
00071     uint16_t cmdLength = 0;
00072 
00073     while (localSize < CMD_HEADER_RX_SIZE) {
00074         if (readable() == true) {
00075             Buffer[localSize]= getc();
00076             localSize++;
00077         }
00078     }
00079     localSize = 0;
00080     cmdLength = (Buffer[CMD_LENGTH_MSB] << 8) + Buffer[CMD_LENGTH_LSB];
00081     while (localSize < cmdLength){
00082         if (readable() == true) {
00083             Buffer[localSize + CMD_HEADER_RX_SIZE ]= getc();
00084             localSize++;
00085         }
00086     }
00087     *size = (uint32_t)(cmdLength + CMD_HEADER_RX_SIZE);
00088 }
00089 
00090 void COMUART::Transmit(uint8_t * Buffer, uint16_t size) {
00091     if ((size % 64) == 0) { // for ZLP Keep the same way than for USB transfer
00092         size = size + 1;
00093     } else {
00094         size = size;
00095     }
00096     for (int g = 0; g < size; g++){
00097         putc(Buffer[g]);
00098     }
00099 } 
00100 
00101 #ifdef  USE_UART 
00102 CMDMANAGER::CMDMANAGER(PinName Tx, PinName Rx) 
00103 {
00104     kill = false;
00105     ActiveInterface = (INTERFACE *) new COMUART (Tx, Rx);
00106     ActiveCom = ISUARTINTERFACE;
00107 }
00108 #else
00109 CMDMANAGER::CMDMANAGER(PinName Tx, PinName Rx)
00110 {
00111     kill = false;
00112     ActiveInterface = (INTERFACE *) new COMUSB ();
00113     ActiveCom = ISUSBINTERFACE;
00114 }
00115 #endif
00116 
00117 void CMDMANAGER::InitBufFromHost() {
00118     memset(BufFromHost, 0, sizeof BufFromHost);
00119     memset(BufFromHostChunk, 0, sizeof BufFromHostChunk);
00120     receivelength[0] = 0;
00121     count = 1; 
00122 }
00123 
00124 void CMDMANAGER::InitBufToHost() {
00125     memset(BufToHost, 0, sizeof BufToHost);
00126 }
00127 
00128 void CMDMANAGER::Init() {
00129     ActiveInterface->Init();
00130     wait_ms(DELAY_COM_INIT);
00131 }
00132 
00133 void CMDMANAGER::ReceiveCmd (){
00134     InitBufFromHost();
00135     if (ActiveCom == ISUARTINTERFACE)
00136     {
00137         ActiveInterface->Receive(&BufFromHost[0], &receivelength[0]);
00138     } else {
00139         ActiveInterface->Receive(&BufFromHostChunk[0], &receivelength[0]);
00140         count = 1;
00141         while (count > 0) {// wait until receive cmd 
00142         }
00143         count = 1;
00144     }
00145     InitBufToHost();
00146 }
00147 
00148 void CMDMANAGER::TransmitCmd (){
00149     uint16_t size;
00150     size = (uint16_t)((BufToHost[CMD_LENGTH_MSB] << 8) + BufToHost[CMD_LENGTH_LSB] + CMD_HEADER_TX_SIZE);
00151     ActiveInterface->Transmit(BufToHost, size);
00152     /* Check if a reset has been requested */
00153     if (kill == true) {
00154         wait_ms(DELAY_RESET);
00155         NVIC_SystemReset();
00156     }
00157 }
00158 
00159 /********************************************************/
00160 /*   cmd name   |      description                      */
00161 /*------------------------------------------------------*/
00162 /*  r           |Read register                          */
00163 /*  s           |Read long burst First packet           */
00164 /*  t           |Read long burst Middle packet          */
00165 /*  u           |Read long burst End packet             */
00166 /*  p           |Read atomic burst packet               */
00167 /*  w           |Write register                         */
00168 /*  x           |Write long burst First packet          */
00169 /*  y           |Write long burst Middle packet         */
00170 /*  z           |Write long burst End packet            */
00171 /*  a           |Write atomic burst packet              */
00172 /*------------------------------------------------------*/
00173 /*  b           |lgw_receive cmd                        */
00174 /*  c           |lgw_rxrf_setconf cmd                   */
00175 /*  d           |int lgw_rxif_setconf_cmd               */
00176 /*  f           |int lgw_send cmd                       */
00177 /*  h           |lgw_txgain_setconf                     */
00178 /*  q           |lgw_get_trigcnt                        */
00179 /*  i           |lgw_board_setconf                      */
00180 /*  j           |lgw_mcu_commit_radio_calibration       */
00181 /*  l           |lgw_check_fw_version                   */
00182 /*  m           |Reset SX1308 and STM32                 */
00183 /*  n           |Jump to bootloader                     */
00184 /********************************************************/
00185 int CMDMANAGER::DecodeCmd() {
00186     int i = 0;
00187     int adressreg;
00188     int val;
00189     int size;
00190     int x;
00191     CmdSettings_t cmdSettings_FromHost;
00192 
00193     if (BufFromHost[0] == 0) {
00194         return (CMD_ERROR);
00195     }
00196 
00197     cmdSettings_FromHost.id = BufFromHost[0];
00198 
00199     if (CheckCmd(cmdSettings_FromHost.id) == false) {
00200         BufToHost[0] = 'k';
00201         BufToHost[1] = 0;
00202         BufToHost[2] = 0;
00203         BufToHost[3] = ACK_K0;
00204         return(CMD_K0);
00205     }
00206 
00207     switch (cmdSettings_FromHost.id) {
00208 
00209         case 'r': { // cmd Read register
00210                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00211                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00212                 adressreg = BufFromHost[3];
00213                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00214                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00215                 }
00216                 val = Sx1308.spiRead(adressreg);
00217                 BufToHost[0] = 'r';
00218                 BufToHost[1] = 0;
00219                 BufToHost[2] = 1;
00220                 BufToHost[3] = ACK_OK;
00221                 BufToHost[4] = val;
00222                 return(CMD_OK);
00223             }
00224         case 's': { // cmd Read burst register first
00225                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00226                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00227                 adressreg = BufFromHost[3];
00228                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00229                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00230                 }
00231                 size = (cmdSettings_FromHost.cmd_data[0] << 8) + cmdSettings_FromHost.cmd_data[1];
00232                 BufToHost[0] = 's';
00233                 BufToHost[1] = cmdSettings_FromHost.cmd_data[0];
00234                 BufToHost[2] = cmdSettings_FromHost.cmd_data[1];
00235                 BufToHost[3] = ACK_OK;
00236                 Sx1308.spiReadBurstF(adressreg, &BufToHost[4 + 0], size);
00237                 return(CMD_OK);
00238             }
00239         case 't': { // cmd Read burst register middle
00240                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00241                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00242                 adressreg = BufFromHost[3];
00243 
00244                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00245                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00246                 }
00247                 size = (cmdSettings_FromHost.cmd_data[0] << 8) + cmdSettings_FromHost.cmd_data[1];
00248 
00249                 BufToHost[0] = 't';
00250                 BufToHost[1] = cmdSettings_FromHost.cmd_data[0];
00251                 BufToHost[2] = cmdSettings_FromHost.cmd_data[1];
00252                 BufToHost[3] = ACK_OK;
00253                 Sx1308.spiReadBurstM(adressreg, &BufToHost[4 + 0], size);
00254                 return(CMD_OK);
00255             }
00256         case 'u': { // cmd Read burst register end
00257                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00258                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00259                 adressreg = BufFromHost[3];
00260                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00261                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00262                 }
00263                 size = (cmdSettings_FromHost.cmd_data[0] << 8) + cmdSettings_FromHost.cmd_data[1];
00264                 BufToHost[0] = 'u';
00265                 BufToHost[1] = cmdSettings_FromHost.cmd_data[0];
00266                 BufToHost[2] = cmdSettings_FromHost.cmd_data[1];
00267                 BufToHost[3] = ACK_OK;
00268                 Sx1308.spiReadBurstE(adressreg, &BufToHost[4 + 0], size);
00269                 return(CMD_OK);
00270             }
00271         case 'p': { // cmd Read burst register atomic
00272                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00273                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00274                 adressreg = BufFromHost[3];
00275                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00276                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00277                 }
00278                 size = (cmdSettings_FromHost.cmd_data[0] << 8) + cmdSettings_FromHost.cmd_data[1];
00279                 BufToHost[0] = 'p';
00280                 BufToHost[1] = cmdSettings_FromHost.cmd_data[0];
00281                 BufToHost[2] = cmdSettings_FromHost.cmd_data[1];
00282                 BufToHost[3] = ACK_OK;
00283                 Sx1308.spiReadBurst(adressreg, &BufToHost[4 + 0], size);
00284                 return(CMD_OK);
00285             }
00286         case 'w': { // cmd write register
00287                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00288                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00289                 adressreg = BufFromHost[3];
00290                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00291                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00292                 }
00293                 val = cmdSettings_FromHost.cmd_data[0];
00294                 Sx1308.spiWrite(adressreg, val);
00295                 BufToHost[0] = 'w';
00296                 BufToHost[1] = 0;
00297                 BufToHost[2] = 0;
00298                 BufToHost[3] = ACK_OK;
00299                 return(CMD_OK);
00300             }
00301         case 'x': { // cmd write burst register
00302                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00303                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00304                 adressreg = BufFromHost[3];
00305                 size = cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8);
00306                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00307                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00308                 }
00309                 Sx1308.spiWriteBurstF(adressreg, &cmdSettings_FromHost.cmd_data[0], size);
00310                 BufToHost[0] = 'x';
00311                 BufToHost[1] = 0;
00312                 BufToHost[2] = 0;
00313                 BufToHost[3] = ACK_OK;
00314                 return(CMD_OK);
00315             }
00316         case 'y': { // cmd write burst register
00317                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00318                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00319                 adressreg = BufFromHost[3];
00320                 size = cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8);
00321                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00322                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00323                 }
00324                 Sx1308.spiWriteBurstM(adressreg, &cmdSettings_FromHost.cmd_data[0], size);
00325                 BufToHost[0] = 'y';
00326                 BufToHost[1] = 0;
00327                 BufToHost[2] = 0;
00328                 BufToHost[3] = ACK_OK;
00329                 return(CMD_OK);
00330             }
00331         case 'z': { // cmd write burst register
00332                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00333                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00334                 adressreg = BufFromHost[3];
00335                 size = cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8);
00336                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00337                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00338                 }
00339                 Sx1308.spiWriteBurstE(adressreg, &cmdSettings_FromHost.cmd_data[0], size);
00340                 BufToHost[0] = 'z';
00341                 BufToHost[1] = 0;
00342                 BufToHost[2] = 0;
00343                 BufToHost[3] = ACK_OK;
00344                 return(CMD_OK);
00345             }
00346         case 'a': { // cmd write burst atomic register
00347                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00348                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00349                 adressreg = BufFromHost[3];
00350                 size = cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8);
00351                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00352                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00353                 }
00354                 Sx1308.spiWriteBurst(adressreg, &cmdSettings_FromHost.cmd_data[0], size);
00355                 BufToHost[0] = 'a';
00356                 BufToHost[1] = 0;
00357                 BufToHost[2] = 0;
00358                 BufToHost[3] = ACK_OK;
00359                 return(CMD_OK);
00360             }
00361         case 'b': { // lgw_receive
00362                 static struct lgw_pkt_rx_s pkt_data[16]; //16 max packets TBU
00363                 int nbpacket = 0;
00364                 int j = 0;
00365                 int sizeatomic = sizeof(lgw_pkt_rx_s) / sizeof(uint8_t);
00366                 int cptalc = 0;
00367                 int pt = 0;
00368                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00369                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00370                 adressreg = BufFromHost[3];
00371                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00372                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00373                 }
00374                 nbpacket = lgw_receive(cmdSettings_FromHost.cmd_data[0], &pkt_data[0]);
00375                 BufToHost[0] = 'b';
00376                 BufToHost[3] = ((nbpacket >= 0) ? ACK_OK : ACK_K0); 
00377                 BufToHost[4] = nbpacket;
00378                 for (j = 0; j < nbpacket; j++) {
00379                     for (i = 0; i < (pkt_data[j].size + (sizeatomic - 256)); i++) {
00380                         BufToHost[5 + i + pt] = *((uint8_t *)(&pkt_data[j]) + i);
00381                         cptalc++;
00382                     }
00383                     pt = cptalc;
00384                 }
00385                 cptalc = cptalc + 1; // + 1 for nbpacket
00386                 BufToHost[1] = (uint8_t)((cptalc >> 8) & 0xFF);
00387                 BufToHost[2] = (uint8_t)((cptalc >> 0) & 0xFF);
00388                 return(CMD_OK);
00389             }
00390         case 'c': { // lgw_rxrf_setconf
00391                 uint8_t rf_chain ;
00392                 uint8_t conf[20];
00393                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00394                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00395                 rf_chain = BufFromHost[3];
00396                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00397                     conf[i] = BufFromHost[4 + i];
00398                 }
00399                 x = lgw_rxrf_setconf(rf_chain, *(lgw_conf_rxrf_s *)conf);
00400                 BufToHost[0] = 'c';
00401                 BufToHost[1] = 0;
00402                 BufToHost[2] = 0;
00403                 BufToHost[3] = ((x == 0) ? ACK_OK : ACK_K0);
00404                 return(CMD_OK);
00405             }
00406         case 'h': { // lgw_txgain_setconf
00407                 uint8_t conf[(LGW_MULTI_NB * TX_GAIN_LUT_SIZE_MAX) + 4];
00408                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00409                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00410                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00411                     conf[i] = BufFromHost[4 + i];
00412                 }
00413                 x = lgw_txgain_setconf((lgw_tx_gain_lut_s *)conf);
00414                 BufToHost[0] = 'h';
00415                 BufToHost[1] = 0;
00416                 BufToHost[2] = 0;
00417                 BufToHost[3] = ((x == 0) ? ACK_OK : ACK_K0);
00418                 return(CMD_OK);
00419             }
00420         case 'd': { // lgw_rxif_setconf
00421                 uint8_t if_chain ;
00422                 uint8_t conf[(sizeof(struct lgw_conf_rxif_s) / sizeof(uint8_t))];
00423                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00424                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00425                 if_chain = BufFromHost[3];
00426                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00427                     conf[i] = BufFromHost[4 + i];
00428                 }
00429                 x = lgw_rxif_setconf(if_chain, *(lgw_conf_rxif_s *)conf);
00430                 BufToHost[0] = 'd';
00431                 BufToHost[1] = 0;
00432                 BufToHost[2] = 0;
00433                 BufToHost[3] = ((x == 0) ? ACK_OK : ACK_K0);
00434                 return(CMD_OK);
00435             }
00436         case 'f': { // lgw_send
00437                 uint32_t count_us;
00438                 int32_t txcontinuous;
00439                 uint8_t conf[(sizeof(struct lgw_pkt_tx_s) / sizeof(uint8_t))];
00440                 Timer timer_tx_timeout;
00441 
00442                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00443                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00444                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00445                     conf[i] = BufFromHost[4 + i];
00446                 }
00447 
00448                 /* Switch off SX1308 correlators to reduce power consumption during transmit */
00449 #ifdef V2
00450                 HSCLKEN = 0;
00451 #else
00452                 lgw_reg_w(LGW_CLKHS_EN, 0);
00453 #endif
00454 
00455                 /* Send packet */
00456                 Sx1308.txongoing = 1;
00457                 Sx1308.waittxend = 1;
00458                 x = lgw_send(*(lgw_pkt_tx_s *)conf);
00459                 if (x < 0) {
00460                     //pc.printf("lgw_send() failed\n");
00461                 }
00462                 
00463                 /* In case of TX continuous, return the answer immediatly */
00464                 lgw_reg_r(LGW_TX_MODE, &txcontinuous); // to switch off the timeout in case of tx continuous
00465                 if (txcontinuous == 1) {
00466                     BufToHost[0] = 'f';
00467                     BufToHost[1] = 0;
00468                     BufToHost[2] = 0;
00469                     BufToHost[3] = ACK_OK;
00470                     return(CMD_OK);
00471                 }
00472 
00473                 /* Wait for TX_DONE interrupt, or 10 seconds timeout */
00474                 timer_tx_timeout.reset();
00475                 timer_tx_timeout.start();
00476                 while (Sx1308.waittxend && (timer_tx_timeout.read() < (float)10.0)) {
00477                 }
00478                 timer_tx_timeout.stop();
00479 
00480                 /* Align SX1308 internal counter and STM32 counter */
00481                 if (Sx1308.firsttx == true) {
00482                     lgw_get_trigcnt(&count_us);
00483                     Sx1308.offtmstpstm32ref = (Sx1308.timerstm32ref.read_us() - count_us ) + 60;
00484                     Sx1308.firsttx = false;
00485                 }
00486 
00487                 /* reset Sx1308 */
00488                 Sx1308.dig_reset();
00489 
00490                 /* Switch SX1308 correlators back on  */
00491 #ifdef V2
00492                 HSCLKEN = 1;
00493 #else
00494                 lgw_reg_w(LGW_CLKHS_EN, 1);
00495 #endif
00496 
00497                 /* restart SX1308 */
00498                 x = lgw_start();
00499                 if (x < 0) {
00500                     //pc.printf("lgw_start() failed\n");
00501                 }
00502 
00503                 /* Send command answer */
00504                 BufToHost[0] = 'f';
00505                 BufToHost[1] = 0;
00506                 BufToHost[2] = 0;
00507                 BufToHost[3] = ((x == 0) ? ACK_OK : ACK_K0);
00508 
00509                 return(CMD_OK);
00510             }
00511         case 'q': { // lgw_get_trigcnt
00512                 uint32_t timestamp;
00513                 x = lgw_get_trigcnt(&timestamp);
00514                 timestamp += Sx1308.offtmstpstm32;
00515                 BufToHost[0] = 'q';
00516                 BufToHost[1] = 0;
00517                 BufToHost[2] = 4;
00518                 BufToHost[3] = ((x == 0) ? ACK_OK : ACK_K0);
00519                 BufToHost[4] = (uint8_t)(timestamp >> 24);
00520                 BufToHost[5] = (uint8_t)((timestamp & 0x00FF0000) >> 16);
00521                 BufToHost[6] = (uint8_t)((timestamp & 0x0000FF00) >> 8);
00522                 BufToHost[7] = (uint8_t)((timestamp & 0x000000FF));
00523                 return(CMD_OK);
00524             }
00525         case 'i': { // lgw_board_setconf
00526                 uint8_t  conf[(sizeof(struct lgw_conf_board_s) / sizeof(uint8_t))];
00527                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00528                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00529                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00530                     conf[i] = BufFromHost[4 + i];
00531                 }
00532 
00533                 x = lgw_board_setconf(*(lgw_conf_board_s *)conf);
00534                 BufToHost[0] = 'i';
00535                 BufToHost[1] = 0;
00536                 BufToHost[2] = 0;
00537                 BufToHost[3] = ((x == 0) ? ACK_OK : ACK_K0);
00538                 return(CMD_OK);
00539             }
00540         case 'j': { // lgw_calibration_snapshot
00541                 lgw_calibration_offset_transfer(BufFromHost[4], BufFromHost[5]);
00542                 BufToHost[0] = 'j';
00543                 BufToHost[1] = 0;
00544                 BufToHost[2] = 0;
00545                 BufToHost[3] = ACK_OK;
00546                 return(CMD_OK);
00547             }
00548         case 'l': { // lgw_mcu_commit_radio_calibration
00549                 int fwfromhost;
00550                 cmdSettings_FromHost.len_msb = BufFromHost[1];
00551                 cmdSettings_FromHost.len_lsb = BufFromHost[2];
00552                 for (i = 0; i < cmdSettings_FromHost.len_lsb + (cmdSettings_FromHost.len_msb << 8); i++) {
00553                     cmdSettings_FromHost.cmd_data[i] = BufFromHost[4 + i];
00554                 }
00555                 fwfromhost = (BufFromHost[4] << 24) + (BufFromHost[5] << 16) + (BufFromHost[6] << 8) + (BufFromHost[7]);
00556                 BufToHost[0] = 'l';
00557                 BufToHost[1] = 0;
00558                 BufToHost[2] = 8;
00559                 if (fwfromhost == FWVERSION) {
00560                     BufToHost[3] = ACK_OK;
00561                 } else {
00562                     BufToHost[3] = ACK_K0;
00563                 }
00564                 BufToHost[4] = *(uint8_t *)0x1fff7a18;   //unique STM32 register base adresse
00565                 BufToHost[5] = *(uint8_t *)0x1fff7a19;
00566                 BufToHost[6] = *(uint8_t *)0x1fff7a1a;
00567                 BufToHost[7] = *(uint8_t *)0x1fff7a1b;
00568                 BufToHost[8] = *(uint8_t *)0x1fff7a10;
00569                 BufToHost[9] = *(uint8_t *)0x1fff7a11;
00570                 BufToHost[10] = *(uint8_t *)0x1fff7a12;
00571                 BufToHost[11] = *(uint8_t *)0x1fff7a13;
00572                 return(CMD_OK);
00573             }
00574         case 'm': { // Reset SX1308 and STM32
00575                 /* reset SX1308 */
00576                 lgw_soft_reset();
00577                 /* Prepare command answer */
00578                 BufToHost[0] = 'm';
00579                 BufToHost[1] = 0;
00580                 BufToHost[2] = 0;
00581                 BufToHost[3] = ACK_OK;
00582                 /* Indicate that STM32 reset has to be triggered */
00583                 kill = true;
00584                 return(CMD_OK);
00585             }
00586         case 'n': { // Jump to bootloader to allow reflashing (DFU, UART bootloader...)
00587                 FLASH_Prog(DATA_EEPROM_BASE, GOTO_BOOTLOADER);
00588                 BufToHost[0] = 'n';
00589                 BufToHost[1] = 0;
00590                 BufToHost[2] = 0;
00591                 BufToHost[3] = ACK_OK;
00592                 kill = true;
00593                 return(CMD_OK);
00594             }
00595         default:
00596             BufToHost[0] = 'k';
00597             BufToHost[1] = 0;
00598             BufToHost[2] = 0;
00599             BufToHost[3] = ACK_K0;
00600             return(CMD_K0);
00601     }
00602 }
00603 
00604 bool CMDMANAGER::CheckCmd(char id) {
00605     switch (id) {
00606         case 'r': /* read register */
00607         case 's': /* read burst - first chunk */
00608         case 't': /* read burst - middle chunk */
00609         case 'u': /* read burst - end chunk */
00610         case 'p': /* read burst - atomic */
00611         case 'w': /* write register */
00612         case 'x': /* write burst - first chunk */
00613         case 'y': /* write burst - middle chunk */
00614         case 'z': /* write burst - end chunk */
00615         case 'a': /* write burst - atomic */
00616         case 'b': /* lgw_receive */
00617         case 'c': /* lgw_rxrf_setconf */
00618         case 'd': /* lgw_rxif_setconf */
00619         case 'f': /* lgw_send */
00620         case 'h': /* lgw_txgain_setconf */
00621         case 'q': /* lgw_get_trigcnt */
00622         case 'i': /* lgw_board_setconf */
00623         case 'j': /* lgw_mcu_commit_radio_calibration */
00624         case 'l': /* lgw_check_fw_version */
00625         case 'm': /* reset STM32 */
00626         case 'n': /* Go to Bootloader */
00627             return true;
00628         default:
00629             return false;
00630     }
00631 }
00632 
00633 int CMDMANAGER::Convert2charsToByte(uint8_t a, uint8_t  b) {
00634     if (a > 96) {
00635         a = a - 87;
00636     } else {
00637         a = a - 48;
00638     }
00639     if (b > 96) {
00640         b = b - 87;
00641     } else {
00642         b = b - 48;
00643     }
00644     return(b + (a << 4));
00645 }