UART console application for testing SX1272/SX1276

Dependencies:   SX127x

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers kermit.cpp Source File

kermit.cpp

00001 #if 0
00002 
00003 #include "kermit.h"
00004 
00005 
00006 #ifdef RADIO_FILE_XFER
00007 typedef enum {
00008     XFER_STATE__NONE = 0,
00009     XFER_STATE_WAIT_S,  // 1
00010     XFER_STATE_S_ACKED, // 2
00011     XFER_STATE_WAIT_F, // 3
00012     XFER_STATE_F_ACKED, // 4
00013     XFER_STATE_WAIT_DATA_ACK,   // 5
00014     XFER_STATE_D_ACKED, // 6
00015     XFER_STATE_WAIT_Z,  // 7
00016     XFER_STATE_Z_ACKED,  // 8
00017     XFER_STATE_WAIT_B,  // 9
00018     XFER_STATE_B_ACKED  // 10
00019 } xfer_state_e;
00020 
00021 typedef struct {
00022     bool radio_initialized;
00023     bool do_tx;
00024     xfer_state_e state;
00025     int fail_length;
00026     float tx_sleep;
00027     char seq_from_rx;
00028     float data_tx_delay;
00029     char data_ack_char; // tmp debug
00030 } radio_xfer_t;
00031 radio_xfer_t radio_xfer;
00032 
00033 #endif /* RADIO_FILE_XFER */
00034 
00035 #ifdef TARGET_NUCLEO_F103RB
00036 /* NUCLEO-F103RB UARTs:
00037  * #  TX       RX        use
00038  * 2  PA_2     PA_3     mbed default
00039  * 1  PA_9     PA_10          PA_9=D8=DIO4a   PA_10=D2=DIO0
00040  * 3  PB_10    PB_11     PB_10=D6=nothing   PB11=C26=4.7uF
00041  * 1  PB_6     PB_7     remap      PB_6=D10=SX1276_NSS   PB7=CN7-21
00042  * 3  PC_10    PC_11    partial remap
00043  * SX127x radio(D11,   D12, D13,    D10,  A0,   D2,   D3); 
00044  */
00045 Serial pc_b(PB_10, PB_11);   //PB_10=D6=nothing   PB11=C26=4.7uF
00046 CRC_HandleTypeDef   CrcHandle;
00047 #endif /* TARGET_NUCLEO_F103RB */
00048 
00049 #ifdef TARGET_LPC11U6X
00050 /* U1_RXD: PIO0_13=A2, PIO1_2=P2-24
00051  * U1_TXD: PIO0_14=A1, PIO1_8=P2-50
00052  * U0_RXD: PIO0_18=mbed, PIO1_26=D5, PIO1_17=J4-4
00053  * U0_TXD: PIO0_19=mbed, PIO1_18=D2, PIO1_27=D6
00054  * U2_RXD: PIO0_20=P2-14, PIO1_6=P2-53
00055  * U2_TXD: PIO1_0=P2-13, PIO1_23=J4-1
00056  * PIO2_3:  U3_RXD=D9
00057  * PIO2_4:  U3_TXD=J8-3
00058  * PIO2_11: U4_RXD
00059 */
00060 Serial pc_b(P1_8, P1_2);    // TX=PIO1_8=P2-50,    RX=PIO1_2=P2-24
00061 #endif
00062 
00063 #define MAX_LEN_FRAME       130 /* */
00064 
00065 Kermit::Kermit(SX127x_lora& _lora) : lora(_lora)
00066 {
00067     uart_rx_enabled = false;
00068 }
00069 
00070 Kermit::~Kermit()
00071 {
00072 }
00073 
00074 uint8_t Kermit::tochar(uint8_t c) { return c + 32; }
00075 uint8_t Kermit::unchar(uint8_t c) { return c - 32; }
00076 uint8_t Kermit::ctl(uint8_t c) { return c ^ 64; }
00077 
00078 void Kermit::rx_callback(uint8_t c)
00079 {
00080     static uint8_t ctrl_c_cnt = 0;    
00081     
00082     if (c == 3) {
00083         if (++ctrl_c_cnt > 3) {
00084             uart_rx_enabled = false;
00085             end_cause = 3;
00086             end = true;
00087             return;
00088         }
00089     } else
00090         ctrl_c_cnt = 0;  
00091               
00092     switch (state) {
00093         case KERMIT_STATE_WAIT_SOH:
00094             if (c == SOH) {
00095                 state = KERMIT_STATE_WAIT_LEN;
00096             }
00097             break;
00098         case KERMIT_STATE_WAIT_LEN:
00099             uart_rx_sum = c;
00100             uart_rx_length = unchar(c) - 2;
00101             state = KERMIT_STATE_WAIT_SEQ;
00102             break;
00103         case KERMIT_STATE_WAIT_SEQ:
00104             uart_rx_sum += c;
00105             uart_rx_seq = unchar(c);
00106             state = KERMIT_STATE_WAIT_TYPE;
00107             break;
00108         case KERMIT_STATE_WAIT_TYPE: 
00109             uart_rx_sum += c;
00110             uart_rx_type = c;
00111             state = KERMIT_STATE_DATA;
00112             uart_rx_data_idx = 0;
00113             break;
00114         case KERMIT_STATE_DATA:
00115             uart_rx_data[uart_rx_data_idx++] = c;
00116             if (uart_rx_data_idx == uart_rx_length) {
00117                 char check = tochar((uart_rx_sum + ((uart_rx_sum & 192)/64)) & 63);
00118                 if (check == c) {
00119                     if (parse_rx()) {
00120                         //kermit_state = KERMIT_STATE_GET_EOL;
00121                         end_cause = 4;
00122                         /////////////////////////
00123                         uart_tx_data_idx = 0;
00124                         uart_tx_data[uart_tx_data_idx++] = 'E';
00125                         uart_tx_data[uart_tx_data_idx++] = uart_rx_type;
00126                         uart_do_tx = true;  
00127                         end_after_tx = true;
00128                         /////////////////////////                           
00129                         break;
00130                     }
00131                 }
00132                 if (uart_rx_type == 'E') {
00133                     state = KERMIT_STATE_GET_EOL;
00134                     end_cause = 2;
00135                 } else
00136                     state = KERMIT_STATE_WAIT_SOH;
00137             } else
00138                 uart_rx_sum += c;
00139             break;
00140         case KERMIT_STATE_GET_EOL:   
00141             uart_rx_enabled = false;
00142             end = true;
00143             if (uart_rx_type == 'E')
00144                 show_error = true;
00145             uart_rx_data[uart_rx_data_idx-1] = 0;  //null terminate, this is ascii text string          
00146             state = KERMIT_STATE_OFF;
00147             break;
00148     } // ..switch (state)    
00149 }
00150 
00151 #ifdef RADIO_FILE_XFER
00152 void Kermit::radio_xfer_rx()
00153 {
00154     radio_xfer.seq_from_rx = lora.m_xcvr.rx_buf[0];
00155     pc_b.printf("rfrx:%02x,%c\r\n", radio_xfer.seq_from_rx, lora.m_xcvr.rx_buf[1]);
00156     
00157     switch (radio_xfer.state) {
00158         case XFER_STATE_WAIT_S: // 'S' response
00159             end_cause = 0;
00160             filename[0] = 0;
00161             uart_tx_data_idx = 0;
00162             if (lora.m_xcvr.rx_buf[1] == 'S') {
00163                 uart_tx_data[uart_tx_data_idx++] = 'Y';
00164                 uart_tx_data[uart_tx_data_idx++] = tochar(94);   // MAXL
00165                 //uart_tx_data[uart_tx_data_idx++] = tochar(kermit.time-1);//TIME
00166                 uart_tx_data[uart_tx_data_idx++] = tochar(1);//TIME (when reply from other radio is bad)
00167                 uart_tx_data[uart_tx_data_idx++] = tochar(0);    //NPAD
00168                 uart_tx_data[uart_tx_data_idx++] = tochar(32);   //PADC
00169                 uart_tx_data[uart_tx_data_idx++] = tochar('\r'); //EOL
00170                 uart_tx_data[uart_tx_data_idx++] = '#';  //QCTL
00171                 uart_tx_data[uart_tx_data_idx++] = 'Y'; //QBIN
00172                 uart_tx_data[uart_tx_data_idx++] = '1'; //CHKT
00173                 uart_tx_data[uart_tx_data_idx++] = '~'; //REPT                
00174             } else
00175                 uart_tx_data[uart_tx_data_idx++] = 'E';
00176                 
00177             uart_do_tx = true;  
00178             radio_xfer.state = XFER_STATE_S_ACKED;
00179             break;
00180         case XFER_STATE_WAIT_F: // 'F' response
00181             uart_tx_data_idx = 0;
00182             if (lora.m_xcvr.rx_buf[1] == 'F') {
00183                 uart_tx_data[uart_tx_data_idx++] = 'Y';
00184             } else
00185                 uart_tx_data[uart_tx_data_idx++] = 'E'; 
00186                 
00187             uart_do_tx = true; 
00188             radio_xfer.state = XFER_STATE_F_ACKED;
00189             break;
00190         case XFER_STATE_WAIT_DATA_ACK:
00191             if (lora.m_xcvr.rx_buf[1] == 'E' || lora.m_xcvr.rx_buf[1] == 'Y' || lora.m_xcvr.rx_buf[1] == 'N') {
00192                 uart_tx_data_idx = 0;
00193                 radio_xfer.data_ack_char = lora.m_xcvr.rx_buf[1];
00194                 uart_tx_data[uart_tx_data_idx++] = lora.m_xcvr.rx_buf[1];
00195                 uart_do_tx = true;
00196                 radio_xfer.state = XFER_STATE_D_ACKED;
00197             }
00198             break;
00199         case XFER_STATE_WAIT_Z:
00200             uart_tx_data_idx = 0;
00201             uart_tx_data[uart_tx_data_idx++] = lora.m_xcvr.rx_buf[1];
00202             uart_do_tx = true; 
00203             radio_xfer.state = XFER_STATE_Z_ACKED;        
00204             break;
00205         case XFER_STATE_WAIT_B:
00206             uart_tx_data_idx = 0;
00207             uart_tx_data[uart_tx_data_idx++] = lora.m_xcvr.rx_buf[1];
00208             uart_do_tx = true; 
00209             end_after_tx = true;
00210             radio_xfer.state = XFER_STATE_B_ACKED;        
00211             break;        
00212     } // ..switch (radio_xfer.state)
00213     //radio_xfer.ack_waiting = false;
00214 }
00215 #endif /* RADIO_FILE_XFER */  
00216 
00217 
00218 #ifdef TARGET_STM
00219 uint32_t Kermit::_HAL_CRC_Calculate(uint32_t pBuffer[], uint32_t BufferLength)
00220 {
00221   uint32_t index = 0;
00222 
00223   /* Reset CRC Calculation Unit */
00224   __HAL_CRC_DR_RESET(&CrcHandle);
00225   __nop();
00226   __nop();
00227   __nop();
00228   __nop();
00229   __nop();
00230 
00231   /* Enter Data to the CRC calculator */
00232   for(index = 0; index < BufferLength; index++)
00233   {
00234     CrcHandle.Instance->DR = pBuffer[index];
00235     //printf("Calc %08x\r\n", CrcHandle.Instance->DR);
00236       __nop();
00237       __nop();
00238       __nop();    
00239   }
00240 
00241   /* Return the CRC computed value */
00242   return CrcHandle.Instance->DR;
00243 }
00244 
00245 
00246  // 20000788 08003101 08007e35 08007e37 08007e39 08007e3b 08007e3d 00000000 00000000 00000000 00000000 08007e3f 08007e41 00000000 08007e43 08007e45 0000311b
00247  void Kermit::test_crc()
00248  {
00249      uint32_t tbuf[17] = { 0x20000788, 0x08003101, 0x08007e35, 0x08007e37, 0x08007e39, 0x08007e3b, 0x08007e3d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08007e3f, 0x08007e41, 0x00000000, 0x08007e43, 0x08007e45, 0x0000311b };
00250      uint32_t crc;
00251      int i;
00252      crc = _HAL_CRC_Calculate(tbuf, 17);
00253      printf("Crc:%08x\r\n", crc);
00254        __HAL_CRC_DR_RESET(&CrcHandle);
00255   __nop();
00256   __nop();
00257   __nop();
00258   __nop();
00259   __nop();
00260     for (i = 0; i < 17; i++) {
00261         CrcHandle.Instance->DR = tbuf[i];
00262         printf("%08x: %08x\r\n", tbuf[i], CrcHandle.Instance->DR);
00263       __nop();
00264       __nop();
00265       __nop();           
00266         
00267     }
00268      printf(": %08x\r\n", CrcHandle.Instance->DR);
00269      
00270 }
00271 #else // !STM...
00272 const uint32_t CrcTable[16] = { // Nibble lookup table for 0x04C11DB7 polynomial
00273         0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
00274         0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD };
00275 uint32_t Kermit::_HAL_CRC_Calculate(uint32_t u32_buf[], uint32_t Size)
00276 {
00277     int i = 0;
00278     uint32_t Crc = 0xffffffff;
00279 
00280     while(Size--)
00281     {
00282         Crc = Crc ^ u32_buf[i++];
00283 
00284         // Process 32-bits, 4 at a time, or 8 rounds
00285         Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // Assumes 32-bit reg, masking index to 4-bits
00286         Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; //  0x04C11DB7 Polynomial used in STM32
00287         Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
00288         Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
00289         Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
00290         Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
00291         Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
00292         Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
00293     }
00294 
00295     return(Crc);
00296 }
00297 uint32_t g_tbuf[17] = { 0x20000788, 0x08003101, 0x08007e35, 0x08007e37, 0x08007e39, 0x08007e3b, 0x08007e3d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08007e3f, 0x08007e41, 0x00000000, 0x08007e43, 0x08007e45, 0x0000311b };
00298 
00299 // 20000788 08003101 08007e35 08007e37 08007e39 08007e3b 08007e3d 00000000 00000000 00000000 00000000 08007e3f 08007e41 00000000 08007e43 08007e45 0000311b
00300 void Kermit::test_crc()
00301 {
00302     //uint32_t tbuf[17] = { 0x20000788, 0x08003101, 0x08007e35, 0x08007e37, 0x08007e39, 0x08007e3b, 0x08007e3d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08007e3f, 0x08007e41, 0x00000000, 0x08007e43, 0x08007e45, 0x0000311b };
00303     uint32_t crc;
00304     //uint32_t *u32_ptr;
00305     //u32_ptr = (uint32_t*)bin_data;
00306     
00307     printf("test_crc...%p\r\n", g_tbuf);
00308     //u32_ptr[0] = 0x20000788;
00309     //u32_ptr[1] = 0x08003101;
00310     
00311     //crc = _HAL_CRC_Calculate((uint32_t*)bin_data, 17);
00312     crc = _HAL_CRC_Calculate(g_tbuf, 17);
00313     printf("crc:%08x\r\n", crc);
00314 }
00315 #endif /* !TARGET_STM */
00316 
00317 
00318 int Kermit::parse_rx()
00319 {
00320     static char prev_uart_rx_seq;
00321     static uint32_t prev_bin_data_idx;
00322     
00323      //pc_b.printf("kermit_parse_rx %02x '%c'\r\n", uart_rx_seq, uartrx_type);
00324 #ifdef RADIO_FILE_XFER    
00325     lora.m_xcvr.tx_buf[0] = uart_rx_seq;
00326     lora.m_xcvr.tx_buf[1] = uart_rx_type;
00327 #endif /* RADIO_FILE_XFER */
00328             
00329     if (uart_rx_type == 'S') {
00330         got_send_init = true;
00331 
00332         if (uart_rx_data_idx > 0)
00333             maxl = unchar(uart_rx_data[0]);
00334         if (uart_rx_data_idx > 1)
00335             time = unchar(uart_rx_data[1]);    
00336         if (uart_rx_data_idx > 2)
00337             npad = unchar(uart_rx_data[2]);
00338         if (uart_rx_data_idx > 3)
00339             padc = unchar(uart_rx_data[3]);
00340         if (uart_rx_data_idx > 4)
00341             eol  = unchar(uart_rx_data[4]);
00342         if (uart_rx_data_idx > 5)
00343             qctl = uart_rx_data[5];   // verbatim
00344         if (uart_rx_data_idx > 6)
00345             qbin = uart_rx_data[6];   // verbatim   'Y'==agree-to-8bit, 'N'=no-8bit '&'==I need this char to do 8bit quoting
00346         if (uart_rx_data_idx > 7)
00347             chkt = uart_rx_data[7];   // verbatim
00348         if (uart_rx_data_idx > 8)
00349             rept = uart_rx_data[8];  
00350 
00351 #ifdef RADIO_FILE_XFER
00352         lora.RegPayloadLength = 2;
00353         lora.m_xcvr.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
00354         radio_xfer.do_tx = true;
00355         radio_xfer.state = XFER_STATE_WAIT_S;
00356 #else
00357         uart_tx_data_idx = 0;
00358         uart_tx_data[uart_tx_data_idx++] = 'Y';
00359         uart_tx_data[uart_tx_data_idx++] = tochar(94);   // MAXL
00360         uart_tx_data[uart_tx_data_idx++] = tochar(kermit.time-1);//TIME
00361         uart_tx_data[uart_tx_data_idx++] = tochar(0);    //NPAD
00362         uart_tx_data[uart_tx_data_idx++] = tochar(32);   //PADC
00363         uart_tx_data[uart_tx_data_idx++] = tochar('\r'); //EOL
00364         uart_tx_data[uart_tx_data_idx++] = '#';  //QCTL
00365         uart_tx_data[uart_tx_data_idx++] = 'Y'; //QBIN
00366         uart_tx_data[uart_tx_data_idx++] = '1'; //CHKT
00367         uart_tx_data[uart_tx_data_idx++] = '~'; //REPT
00368         uart_do_tx = true;
00369 #endif /* !RADIO_FILE_XFER */
00370         pc_b.printf("S\r\n");
00371     } else if (uart_rx_type == 'F') {
00372         /* keep filename if desired */
00373         memcpy(filename, uart_rx_data, uart_rx_data_idx-1);
00374         filename[uart_rx_data_idx-1] = 0;
00375         
00376         total_file_bytes = 0;
00377         prev_uart_rx_seq = uart_rx_seq;
00378         prev_bin_data_idx = 0;
00379 #ifdef XXD_PRINT
00380         xxd_total_file_bytes_so_far = 0;
00381         xxd_remainder = 0;
00382 #endif /* XXD_PRINT */        
00383 
00384 #ifdef RADIO_FILE_XFER
00385         lora.RegPayloadLength = 2;
00386         lora.m_xcvr.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
00387         radio_xfer.do_tx = true;
00388         radio_xfer.tx_sleep = radio_xfer.data_tx_delay;
00389         radio_xfer.state = XFER_STATE_WAIT_F;
00390 #else
00391         uart_tx_data_idx = 0;
00392         uart_tx_data[uart_tx_data_idx++] = 'Y';
00393         /*memcpy(uart_tx_data+1, uart_rx_data, uart_rx_data_idx-1);
00394         uart_tx_data_idx += uart_rx_data_idx-1;*/
00395         uart_do_tx = true;
00396 #endif /* !RADIO_FILE_XFER */   
00397         bin_data = (uint8_t*)bin_data_u32;
00398         pc_b.printf("F\r\n");
00399     } else if (uart_rx_type == 'D') {
00400         int i;
00401 #ifdef RADIO_FILE_XFER
00402         uint8_t len_for_crc;
00403         //uint32_t* u32_ptr;
00404         uint32_t uwCRCValue;
00405 #endif /* RADIO_FILE_XFER */   
00406         
00407         bin_data_idx = 0;
00408 
00409 #ifdef KERMIT_DATA_PRINT
00410         pc_b.printf("%04x: ", kermit.total_file_bytes);
00411 #endif /* */            
00412      
00413         uart_rx_data_idx--;   // cut off trailing sum byte
00414         for (i = 0; i < uart_rx_data_idx; i++) {
00415             if (uart_rx_data[i] == qctl) { // escaped..
00416                 uint8_t in = uart_rx_data[++i];
00417 #ifdef KERMIT_DATA_PRINT
00418                     pc_b.printf("#");
00419 #endif /* */   
00420                 if ((in & 0x7f) == rept || (in & 0x7f) == qctl) {
00421 #ifdef KERMIT_DATA_PRINT
00422                     pc_b.printf(":%02x ", in);
00423 #endif /* */                  
00424                     bin_data[bin_data_idx++] = in;
00425                 } else {
00426 #ifdef KERMIT_DATA_PRINT
00427                     pc_b.printf("ctl:%02x ", ctl(in));
00428 #endif /* */                      
00429                     bin_data[bin_data_idx++] = ctl(in);
00430                 }
00431             } else if (uart_rx_data[i] == rept) {   //repeat..
00432                 uint8_t octet, cnt = unchar(uart_rx_data[++i]);
00433                 i++;    // step past count
00434                 if (uart_rx_data[i] == qctl) {
00435                     uint8_t raw = uart_rx_data[++i];
00436                     octet = ctl(raw);
00437                 } else {
00438                     octet = uart_rx_data[i];
00439                 }
00440                 for (int n = 0; n < cnt; n++) {
00441 #ifdef KERMIT_DATA_PRINT
00442                     pc_b.printf("rep%02x ", octet);
00443 #endif /*  */            
00444                     bin_data[bin_data_idx++] = octet;
00445                 }
00446             } else {
00447 #ifdef KERMIT_DATA_PRINT
00448                     pc_b.printf("%02x ", uart_rx_data[i]);
00449 #endif /*  */    
00450                 bin_data[bin_data_idx++] = uart_rx_data[i];
00451             }
00452         } // ..for()
00453 #ifdef KERMIT_DATA_PRINT
00454         pc_b.printf("\r\n");
00455 #endif /*  */                   
00456         
00457         if (prev_uart_rx_seq == uart_rx_seq) {
00458             // resend of previous 'D' packet
00459             total_file_bytes -= prev_bin_data_idx;
00460         } else {
00461 #ifdef XXD_PRINT
00462             xxd_print(0);
00463 #endif /* XXD_PRINT */            
00464         }
00465 
00466         total_file_bytes += bin_data_idx;
00467         prev_bin_data_idx = bin_data_idx;
00468         prev_uart_rx_seq = uart_rx_seq;        
00469         
00470 #ifdef RADIO_FILE_XFER               
00471         // zero-pad to 4byte size alignment
00472         len_for_crc = bin_data_idx;
00473         while (len_for_crc & 3) {
00474             bin_data[len_for_crc++] = 0;
00475         }
00476         uwCRCValue = _HAL_CRC_Calculate((uint32_t *)bin_data, len_for_crc >> 2);
00477         //kermit.crc32 = uwCRCValue;
00478         //memcpy(crc_buf, bin_data, len_for_crc);
00479         //kermit.len_for_crc = len_for_crc;
00480     
00481         
00482         if (bin_data_idx > MAX_LEN_FRAME) {  // oversized
00483             radio_xfer.fail_length = bin_data_idx;
00484             return 1;   // fail
00485         }
00486         
00487         //u32_ptr = (uint32_t *)&lora.m_xcvr.tx_buf[2];
00488         //pc_b.printf("D-hhh %p\r\n", u32_ptr);
00489         //*u32_ptr = uwCRCValue;
00490         memcpy(&lora.m_xcvr.tx_buf[2], &uwCRCValue, 4);
00491 /*        
00492         if (prev_rx_seq == kermit.rx_seq) {
00493             // resend of previous 'D' packet
00494             radio_xfer.total_file_bytes -= prev_bin_data_idx;
00495         }
00496         radio_xfer.total_file_bytes += bin_data_idx;
00497         prev_bin_data_idx = bin_data_idx;
00498         prev_rx_seq = kermit.rx_seq;
00499 */
00500         
00501         memcpy(lora.m_xcvr.tx_buf+6, bin_data, bin_data_idx);
00502         lora.RegPayloadLength = bin_data_idx+6;
00503         lora.m_xcvr.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
00504         radio_xfer.do_tx = true;
00505         radio_xfer.state = XFER_STATE_WAIT_DATA_ACK;
00506         radio_xfer.tx_sleep = radio_xfer.data_tx_delay;
00507 #else 
00508         /* send ACK.. */
00509         while (uart_do_tx);
00510         uart_tx_data_idx = 0;
00511         uart_tx_data[uart_tx_data_idx++] = 'Y';
00512         uart_do_tx = true;        
00513 #endif /* !RADIO_FILE_XFER */
00514         return 0;
00515     } else if (uart_rx_type == 'Z') {
00516 #ifdef RADIO_FILE_XFER  
00517         lora.RegPayloadLength = 2;
00518         lora.m_xcvr.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
00519         radio_xfer.do_tx = true;
00520         radio_xfer.tx_sleep = radio_xfer.data_tx_delay;
00521         radio_xfer.state = XFER_STATE_WAIT_Z;
00522 #else
00523         /* send ACK.. */
00524         while (uart_do_tx);
00525         uart_tx_data_idx = 0;
00526         uart_tx_data[uart_tx_data_idx++] = 'Y';
00527         uart_do_tx = true;               
00528         uart_tx_sleep = 0.1;
00529 #endif /* !RADIO_FILE_XFER */
00530         pc_b.printf("Z\r\n");
00531         return 0;
00532     } else if (uart_rx_type == 'B') {
00533 #ifdef RADIO_FILE_XFER  
00534         lora.RegPayloadLength = 2;
00535         lora.m_xcvr.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
00536         radio_xfer.do_tx = true;
00537         radio_xfer.tx_sleep = radio_xfer.data_tx_delay;
00538         radio_xfer.state = XFER_STATE_WAIT_B;
00539 #else
00540         uart_tx_data_idx = 0;
00541         uart_tx_data[uart_tx_data_idx++] = 'Y';
00542         uart_do_tx = true;               
00543         uart_tx_sleep = 0.1;
00544 #endif /* RADIO_FILE_XFER */
00545 #ifdef XXD_PRINT
00546         xxd_print(1);
00547 #endif /* XXD_PRINT */        
00548         pc_b.printf("B\r\n");
00549         return 0;
00550     } else {
00551         // unknown packet, prevent further packets from overwriting
00552         return 1;
00553     }
00554     
00555     return 0;
00556 }
00557 
00558 void Kermit::kermit_uart_tx()
00559 {
00560     uint8_t buf[128];
00561     uint8_t idx = 0;
00562     int i;
00563     uint32_t sum;
00564            
00565     buf[idx++] = SOH;   // MARK
00566     buf[idx++] = 0;   // length to be inserted later
00567 #ifdef RADIO_FILE_XFER
00568     buf[idx++] = tochar(radio_xfer.seq_from_rx); // SEQ
00569 #else
00570     buf[idx++] = tochar(uart_rx_seq);   // SEQ
00571 #endif
00572     // TYPE is uart_tx_data[0]
00573     for (i = 0; i < uart_tx_data_idx; i++) {
00574         buf[idx++] = uart_tx_data[i];
00575     }
00576     
00577     buf[1] = tochar(idx - 1); // LEN  (-1 because block check hasnt been included in idx yet)
00578     
00579     sum = 0;
00580     for (i = 1; i < idx; i++) {
00581         sum += buf[i];
00582     }
00583     buf[idx++] = tochar((sum + ((sum & 192)/64)) & 63);
00584     buf[idx++] = eol;
00585     
00586     for (i = 0; i < idx; i++)
00587         putc(buf[i], stdout);
00588        //pc.putc(buf[i]);
00589 
00590 }
00591 
00592 void Kermit::service()
00593 {
00594     if (end) {
00595         if (show_error) {
00596             printf("kermit error:\"%s\"\r\n", uart_rx_data);
00597             show_error = false;
00598         }
00599         printf("kermit_end\r\n");
00600         printf("total_file_bytes:%d\r\n", total_file_bytes);
00601         end = false;
00602     }
00603     
00604     if (uart_do_tx) {
00605         if (uart_tx_sleep > 0.001) {
00606             wait(uart_tx_sleep);
00607             uart_tx_sleep = 0;
00608         }
00609         kermit_uart_tx();
00610         uart_do_tx = false;
00611         if (end_after_tx) {
00612             //know this cause -- end_cause = 1;
00613             uart_rx_enabled = false;
00614             end = true;   
00615             state = KERMIT_STATE_OFF;            
00616             end_after_tx = false;
00617         }
00618     } // ...if (uart_do_tx)
00619     
00620 #ifdef RADIO_FILE_XFER
00621     if (!radio_xfer.radio_initialized) {
00622         lora.m_xcvr.set_opmode(RF_OPMODE_STANDBY);   
00623         lora.m_xcvr.write_reg(REG_LR_SYNC_BYTE, 0x34);
00624         lora.setBw_KHz(500);
00625         lora.setSf(7); 
00626         lora.m_xcvr.set_frf_MHz(915.0);
00627         lora.invert_tx(true);
00628         radio_xfer.fail_length = -1;
00629         radio_xfer.radio_initialized = true;
00630     }
00631 
00632     if (radio_xfer.do_tx) {
00633         pc_b.printf("rfTX:%02x\r\n", lora.m_xcvr.tx_buf[0]);
00634         if (radio_xfer.tx_sleep > 0.001) {
00635             wait(radio_xfer.tx_sleep);
00636             radio_xfer.tx_sleep = 0;
00637         }
00638         lora.start_tx(lora.RegPayloadLength);
00639         radio_xfer.do_tx = false;
00640     }
00641 #endif /* RADIO_FILE_XFER */    
00642 }
00643 
00644 void Kermit::uart_rx_enable()
00645 {
00646     got_send_init = false;
00647     uart_rx_enabled = true;
00648     state = KERMIT_STATE_WAIT_LEN;
00649 #ifdef RADIO_FILE_XFER    
00650     radio_xfer.radio_initialized = false;   // causes radio initialization for transfer
00651 #endif /* RADIO_FILE_XFER */    
00652 }
00653 #endif /* #if 0 */