H261 decoder

Dependencies:   SDL_lib2 SX1276Lib mbed

Revision:
0:5bd441b8ab2d
Child:
1:1ed97958d0f3
diff -r 000000000000 -r 5bd441b8ab2d lora.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lora.h	Thu Sep 22 00:04:30 2016 +0000
@@ -0,0 +1,624 @@
+//Author: Miguel Ruiz García
+//Company: University of Cantabria. 2016
+//mail: mrg47@alumnos.unican.es
+//code for TX & RX
+#include "mbed.h"
+#include "lora2.h"
+#include "sx1276-hal.h"
+#include "debug.h"
+//#include "functions.h"
+/* Set this flag to '1' to display debug messages on the console */
+#define DEBUG_MESSAGE   1
+
+
+/* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */
+#define USE_MODEM_LORA  1
+#define USE_MODEM_FSK   !USE_MODEM_LORA
+
+#define RF_FREQUENCY                                    869000000 // Hz
+#define TX_OUTPUT_POWER                                 14        // 14 dBm
+
+#if USE_MODEM_LORA == 1
+
+    #define LORA_BANDWIDTH                              1         // [0: 125 kHz,
+                                                                  //  1: 250 kHz,
+                                                                  //  2: 500 kHz,
+                                                                  //  3: Reserved]
+    #define LORA_SPREADING_FACTOR                       10         // [SF7..SF12]
+    #define LORA_CODINGRATE                             1         // [1: 4/5,
+                                                                  //  2: 4/6,
+                                                                  //  3: 4/7,
+                                                                  //  4: 4/8]
+    #define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
+    #define LORA_SYMBOL_TIMEOUT                         5         // Symbols
+    #define LORA_FIX_LENGTH_PAYLOAD_ON                  false
+    #define LORA_FHSS_ENABLED                           true  
+    #define LORA_NB_SYMB_HOP                            4     
+    #define LORA_IQ_INVERSION_ON                        false
+    #define LORA_CRC_ENABLED                            true
+    
+#elif USE_MODEM_FSK == 1
+
+    #define FSK_FDEV                                    25000     // Hz
+    #define FSK_DATARATE                                19200     // bps
+    #define FSK_BANDWIDTH                               50000     // Hz
+    #define FSK_AFC_BANDWIDTH                           83333     // Hz
+    #define FSK_PREAMBLE_LENGTH                         5         // Same for Tx and Rx
+    #define FSK_FIX_LENGTH_PAYLOAD_ON                   false
+    #define FSK_CRC_ENABLED                             true
+    
+#else
+    #error "Please define a modem in the compiler options."
+#endif
+
+#define RX_TIMEOUT_VALUE                                3500000   // in us
+#define BUFFER_SIZE                                     255        // Define the payload size here [min:1 max:255]
+
+#if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
+DigitalOut led(LED2);
+#else
+DigitalOut led(LED1);
+#endif
+
+
+/*
+ *  Global variables declarations
+ */
+typedef enum
+{
+    LOWPOWER = 0,
+    IDLE,
+    
+    RX,
+    RX_TIMEOUT,
+    RX_ERROR,
+    
+    TX,
+    TX_TIMEOUT,
+    
+    CAD,
+    CAD_DONE
+}AppStates_t;
+
+volatile AppStates_t State = LOWPOWER;
+
+/*!
+ * Radio events function pointer
+ */
+static RadioEvents_t RadioEvents;
+
+/*
+ *  Global variables declarations
+ */
+SX1276MB1xAS Radio( NULL );
+
+const uint8_t PingMsg[] = "PING";
+const uint8_t PongMsg[] = "PONG";
+const uint8_t AckMsg[] = "ACK";
+const uint8_t EOPMsg[] = "EOP";
+const uint8_t RfSMsg[] = "RfS";
+int py=0,pu=0,pv=0,py2=0,pu2=0,pv2=0;
+int py_ant=0,pu_ant=0,pv_ant=0;
+int flag_y=0,flag_u=0,flag_v=0;
+uint16_t BufferSize = BUFFER_SIZE;
+uint8_t Buffer[BUFFER_SIZE];
+//uint8_t Buffer2[4];
+
+int16_t RssiValue = 0.0;
+int8_t SnrValue = 0.0;
+
+bool first_y=true,first_u=true,first_v=true;
+void lora(short int *temp1,short int index1,short int *temp2,short int index2,short int *temp3,short int index3) 
+{
+    //index1=300;index2=300;index3=300;
+    uint8_t i;
+    bool isMaster = false;//MASTER (TX) OR SLAVE(RX) ?
+    
+    //pc.baud(BPS);
+    //pc.format (BITS,SerialBase::None, STOP_BITS) ;
+   
+
+    
+    //debug( "\n\n\r     SX1276 Ping Pong Demo Application \n\n\r" );
+    //pc.printf("\n\n\r     SX1276 Image transfer Application \n\n\r");
+
+    // Initialize Radio driver
+    RadioEvents.TxDone = OnTxDone;
+    RadioEvents.RxDone = OnRxDone;
+    RadioEvents.RxError = OnRxError;
+    RadioEvents.TxTimeout = OnTxTimeout;
+    RadioEvents.RxTimeout = OnRxTimeout;
+    RadioEvents.FhssChangeChannel = OnFhssChangeChannel;
+    Radio.Init( &RadioEvents );
+    
+    // verify the connection with the board
+    goto start;
+    while( Radio.Read( REG_VERSION ) == 0x00  )
+    {
+        //debug( "Radio could not be detected!\n\r", NULL );
+        //pc.printf( "Radio could not be detected!\n\r", NULL );
+        wait( 1 );
+    }
+    start:        
+    //debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1LAS ) ) , "\n\r > Board Type: SX1276MB1LAS < \n\r" );
+    //debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1MAS ) ) , "\n\r > Board Type: SX1276MB1MAS < \n\r" );
+    
+    Radio.SetChannel( HoppingFrequencies[0] ); 
+
+#if USE_MODEM_LORA == 1
+    
+    //debug_if( LORA_FHSS_ENABLED, "\n\n\r             > LORA FHSS Mode < \n\n\r");
+    //debug_if( !LORA_FHSS_ENABLED, "\n\n\r             > LORA Mode < \n\n\r");
+
+    Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
+                         LORA_SPREADING_FACTOR, LORA_CODINGRATE,
+                         LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
+                         LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
+                         LORA_IQ_INVERSION_ON, 4000000 );
+    
+    Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
+                         LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
+                         LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
+                         LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
+                         LORA_IQ_INVERSION_ON, true );
+                         
+#elif USE_MODEM_FSK == 1
+
+    debug("\n\n\r              > FSK Mode < \n\n\r");
+    Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
+                         FSK_DATARATE, 0,
+                         FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
+                         FSK_CRC_ENABLED, 0, 0, 0, 3000000 );
+    
+    Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
+                         0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
+                         0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
+                         0, 0, false, true );
+                         
+#else
+
+#error "Please define a modem in the compiler options."
+
+#endif
+    
+    //debug_if( DEBUG_MESSAGE, "Starting image transmission loop\r\n" ); 
+    //pc.printf("Starting image transmission loop\r\n");
+        
+    led = 0;
+   
+    Radio.Rx( RX_TIMEOUT_VALUE );
+    State=RX;//Estado inicial para el receptor
+    while( 1 )
+    {
+        switch( State )
+        {
+        case RX:
+            if( isMaster == true )
+            {
+                //debug( "waiting for response....\r\n" );
+                if( BufferSize > 0 )
+                {
+                    
+                    if( strncmp( ( const char* )Buffer, ( const char* )AckMsg, 3 ) != 0 )
+                    {
+                        led = !led;
+                        //debug( "Packet acknoledged....\r\n" );
+      //                  pc.printf( "Packet acknoledged....\r\n" );
+                        // Send the next  frame            
+                        State = TX;
+                    }
+                    
+                    else if( strncmp( ( const char* )Buffer, ( const char* )RfSMsg, 3 ) == 0 ){
+                        
+                            led = !led;
+                            debug( "Retransmit packet....\r\n" );
+        //                    pc.printf( "Retransmit packet....\r\n" );
+                            // Send the next  frame            
+                            State = TX;
+                            py=py_ant; pu=pu_ant; pv=pv_ant;//Si hay que reenviar el paquete se reestablecen los valores de punteros.
+                    }                        
+                    
+                    else // valid reception but neither a  message
+                    {    // Set device as master ans start again
+                      debug( "no message received...\r\n" );
+          //          pc.printf( "hola...\r\n" );
+                        isMaster = true;//this intruction is DANGEROUS!!!!!!
+                        Radio.Rx( RX_TIMEOUT_VALUE );
+                    }    
+                }
+            }
+            else
+            {
+                if( BufferSize > 0 )
+                {
+                    
+                        led = !led;
+                        debug( "Reading... \r\n" );
+            //            pc.printf( "Reading... \r\n" );
+                        
+                    int pointer=0;
+                    int length_y=0,length_v=0,length_u=0;
+                    for(pointer=0;pointer<254;pointer+=4){
+                        if(flag_y==0) {//se comprueba si se ha cargado en el buffer de transmisión cada una de las componentes
+                            if(first_y == true) {//EL PRIMER DATO ES LA LONGITUD
+                                length_y=0xff & Buffer[pointer+1];
+                                length_y=length_y<<8;
+                                length_y=length_y | Buffer[pointer];
+                                first_y = false;
+                                temp1=(short int *)malloc(sizeof(short int)*length_y);
+                                pointer-=2;//this is to avoid lose the first byte of the component
+                                //in the cycle 'pointer+=4' but in the first package of the component there´s no a pair [length,value]
+                                
+                            }
+                            else{
+                                if(Buffer[pointer]!='\t'){//VERIFY the character is not EOC (end of component y u v)
+                        
+                                    short int num=0;
+                                    num=0xff & Buffer[pointer+1];
+                                    num=num<<8;
+                                    num=num | Buffer[pointer];
+                                    *(temp1+py2)=num;
+                                    py2++;
+                                    
+                                    if (py2 > length_y) {flag_y=1;}
+                                    
+                                    num=0xff & Buffer[pointer+3];
+                                    num=num<<8;
+                                    num=num | Buffer[pointer+2];
+                                    *(temp1+py2)=num;
+                                     py2++;
+                                     
+                                     if (py2 > length_y) {flag_y=1;}//if all bytes of the component are read, indicator is raised
+                                     //originally designed with goto.
+                                }
+                                else {
+                                    flag_y=1;
+                                }
+                            }
+                        }
+                            
+                        
+                        else if(flag_u==0){
+                            if(first_u == true) {
+                                length_u=0xff & Buffer[pointer+1];
+                                length_u=length_u<<8;
+                                length_u=length_u | Buffer[pointer];
+                                first_u = false;
+                                temp2=(short int *)malloc(sizeof(short int)*length_u);
+                                pointer-=2;
+                            }
+                            else{
+                                if(Buffer[pointer]!='\t'){//VERIFY the character is not "end of component"
+                        
+                                    short int num=0;
+                                    num=0xff & Buffer[pointer+1];
+                                    num=num<<8;
+                                    num=num | Buffer[pointer];
+                                    *(temp2+pu2)=num;
+                                    pu2++;
+                                    
+                                    if (pu2 > length_u) {flag_u=1;}
+                                    
+                                    num=0xff & Buffer[pointer+3];
+                                    num=num<<8;
+                                    num=num | Buffer[pointer+2];
+                                    *(temp2+pu2)=num;
+                                     pu2++;
+                                     
+                                     if (pu2 > length_u) {flag_u=1;}
+                                }
+                                else {
+                                    flag_u=1;
+                                }
+                            }
+                        }
+                        
+                        else{
+                            if(first_v == true) {
+                                length_v=0xff & Buffer[pointer+1];
+                                length_v=length_v<<8;
+                                length_v=length_v | Buffer[pointer];
+                                first_v = false;
+                                temp3=(short int *)malloc(sizeof(short int)*length_v);
+                                pointer-=2;
+                            }
+                            else{
+                                if(Buffer[pointer]!='\n'){//VERIFY the character is not EOT
+                        
+                                    short int num=0;
+                                    num=0xff & Buffer[pointer+1];
+                                    num=num<<8;
+                                    num=num | Buffer[pointer];
+                                    *(temp3+pv2)=num;
+                                    py2++;
+                                    
+                                    if (pv2 > length_v) {flag_v=1;}
+                                    
+                                    num=0xff & Buffer[pointer+3];
+                                    num=num<<8;
+                                    num=num | Buffer[pointer+2];
+                                    *(temp3+pv2)=num;
+                                     pv2++;
+                                     
+                                     if (pv2 > length_v) {flag_v=1;}
+                                }
+                                else {
+                                    flag_v=1;
+                                    break;
+                                }
+                            }
+                        }
+         
+                        
+                    }
+                    if(flag_y==1 && flag_u==1 && flag_v ==1){ 
+                        strcpy( ( char* )Buffer, ( char* )AckMsg );
+                        // We fill the buffer with numbers for the payload 
+                            for( i = 4; i < BufferSize; i++ )
+                            {
+                            Buffer[i] = i - 4;
+                            }
+                        wait_ms( 10 );  
+                        Radio.Send( Buffer, BufferSize );
+                        
+                        first_y=true;first_u=true;first_v=true;
+                        
+                       // debug( "Packet received \r\n" );
+              //          pc.printf( "Packet received \r\n" );
+                        State = LOWPOWER;
+                        goto end;
+                       
+                    }
+                    
+                    State=TX;
+                }
+            }
+            
+            break;
+        case TX:    
+            led = !led; 
+            if( isMaster == true )  
+            {
+                //debug( "transmission of packet (320x8)...\r\n" );
+                //pc.printf( "transmission of packet (320x8)...\r\n" );
+                int pointer=0;
+                
+                
+                    py_ant=py;pu_ant=pu;pv_ant=pv;
+                    for(pointer=0;pointer<254;pointer+=2){
+                    
+                        if(flag_y==0) {//se comprueba si se ha cargado en el buffer de transmisión cada una de las componentes
+                            if(first_y == true) {//en primer lugar se manda la longitud de la componente y u v despues del rlc
+                                Buffer[pointer]=index1&0xff;
+                                Buffer[pointer+1]=(index1>>8)&0xff;
+                                first_y = false;
+                                 //debug( "transmitting y length...\r\n" );
+                            }
+                            else{
+                                Buffer[pointer]=*(temp1+py) & 0x00ff;
+                                Buffer[pointer+1]=(*(temp1+py)>>8) & 0x00ff;
+                                py++;
+                                // debug( "transmitting y data..\r\n" );
+                                if(py >= index1) {
+                                    flag_y=1;
+                                    Buffer[pointer+2]='\t';
+                                    pointer+=2;
+                                }
+                            }
+                        }
+                        else if(flag_u==0){
+                            if(first_u == true) {
+                                Buffer[pointer]=index2&0xff;
+                                Buffer[pointer+1]=(index2>>8)&0xff;
+                                first_u = false;
+                                //debug( "transmitting u length...\r\n" );
+                            }
+                            else{
+                                Buffer[pointer]=*(temp2+pu) & 0x00ff;
+                                Buffer[pointer+1]=(*(temp2+pu)>>8) & 0x00ff;
+                                pu++;
+                                //debug( "transmitting u data...\r\n" );
+                                if(pu>= index2) {
+                                    flag_u=1;
+                                    Buffer[pointer+2]='\t';
+                                    pointer+=2;
+                                }
+                            }
+                        }
+                        
+                        else{
+                            if(first_v == true) {
+                                Buffer[pointer]=index2&0xff;
+                                Buffer[pointer+1]=(index2>>8)&0xff;
+                                first_v = false;
+                                //debug( "transmitting v length...\r\n" );
+                            }
+                            else{
+                                Buffer[pointer]=*(temp3+pv) & 0x00ff;
+                                Buffer[pointer+1]=(*(temp3+pv)>>8) & 0x00ff;
+                                pv++;
+                                //debug( "transmitting v data ...\r\n" );
+                                if(pv >= index3) {
+                                    flag_v=1;
+                                    Buffer[pointer+2]='\n';//salto de línea es EOT  
+                                    pointer+=2;
+                                    break;
+                                }
+                            }
+                        }
+                        
+                        
+                    }
+                    
+                    if(flag_y==1 && flag_u==1 && flag_v==1){
+                        Buffer[pointer]='\n';//salto de línea es EOT  
+                        flag_y=0;flag_u=0;flag_v=0;
+                        //debug( "finished transmission ...\r\n" );
+                        first_y=true;first_u=true;first_v=true;
+                        goto end;
+                        for( i = Buffer[pointer]; i < BufferSize; i++ )
+                        {
+                            Buffer[i] = i - 4;
+                        }
+                    }
+                    else{
+                        for( i = Buffer[pointer]; i < BufferSize; i++ )
+                        {
+                            Buffer[i] = i - 4;
+                        }
+                    }
+
+                
+
+                wait_ms( 10 ); 
+                //debug( "Sending packet...\r\n" );
+                Radio.Send( Buffer, BufferSize );
+                
+               // pc.printf( "Sending packet...\r\n" );
+            }
+                
+            else
+            {
+                //debug( "hola...\r\n" );
+                //pc.printf( "hola...\r\n" );
+                strcpy( ( char* )Buffer, ( char* )AckMsg );
+                for( i = 4; i < BufferSize; i++ )
+                {
+                    Buffer[i] = i - 4;
+                }
+                wait_ms( 10 ); 
+                Radio.Send( Buffer, BufferSize );
+                Radio.Rx( RX_TIMEOUT_VALUE );  
+            }  
+            
+            State = RX;
+            break;
+        case RX_TIMEOUT:
+            if( isMaster == true )
+            {
+                //debug( "hola rx_timeout...\r\n" );
+                //pc.printf( "hola...\r\n" );
+                // Send the next PING frame
+                strcpy( ( char* )Buffer, ( char* )RfSMsg );
+                for( i = 4; i < BufferSize; i++ )
+                {
+                    Buffer[i] = i - 4;
+                }
+                wait_ms( 10 ); 
+                Radio.Send( Buffer, BufferSize );
+            }
+            else
+            {
+                //debug( "hola...\r\n" );
+                //pc.printf( "hola...\r\n" );
+                strcpy( ( char* )Buffer, ( char* )RfSMsg );
+                for( i = 4; i < BufferSize; i++ )
+                {
+                    Buffer[i] = i - 4;
+                }
+                wait_ms( 10 ); 
+                Radio.Send( Buffer, BufferSize );
+                Radio.Rx( RX_TIMEOUT_VALUE );  
+            }             
+            State = LOWPOWER;
+            break;
+
+        case RX_ERROR:
+            // We have received a Packet with a CRC error, request packet again.
+            if( isMaster == true )
+            {
+                
+                //debug( "hola rx_error...\r\n" );
+                //pc.printf( "hola...\r\n" );
+                strcpy( ( char* )Buffer, ( char* )RfSMsg);
+                for( i = 4; i < BufferSize; i++ )
+                {
+                    Buffer[i] = i - 4;
+                }
+                
+                wait_ms( 10 );  
+                Radio.Send( Buffer, BufferSize );
+                State = LOWPOWER;
+            }
+            else
+            {
+                //debug( "hola ...\r\n" );
+                //pc.printf( "hola...\r\n" );
+                // Send the RfS again
+                strcpy( ( char* )Buffer, ( char* )RfSMsg);
+                for( i = 4; i < BufferSize; i++ )
+                {
+                    Buffer[i] = i - 4;
+                }
+                py=py_ant;pu=pu_ant;pv=pv_ant;
+                wait_ms( 10 );  
+                Radio.Send( Buffer, BufferSize );
+                State = LOWPOWER;
+            }
+            //State = LOWPOWER;
+            break;
+        case TX_TIMEOUT:
+            Radio.Rx( RX_TIMEOUT_VALUE );
+            State = LOWPOWER;
+            break;
+        case LOWPOWER:
+            break;
+        default:
+            State = LOWPOWER;
+            break;
+        }    
+    }
+    end:
+    int a;
+}
+
+void OnTxDone( void )
+{
+    Radio.SetChannel( HoppingFrequencies[0] );
+    Radio.Sleep( );
+    State = TX;
+    debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
+}
+
+void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
+{
+    Radio.SetChannel( HoppingFrequencies[0] );
+    Radio.Sleep( );
+    BufferSize = size;
+    memcpy( Buffer, payload, BufferSize );
+    RssiValue = rssi;
+    SnrValue = snr;
+    State = RX;
+    debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
+}
+
+void OnTxTimeout( void )
+{
+    Radio.SetChannel( HoppingFrequencies[0] );
+    Radio.Sleep( );
+    State = TX_TIMEOUT;
+    //debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
+}
+
+void OnRxTimeout( void )
+{
+    Radio.SetChannel( HoppingFrequencies[0] );
+    Radio.Sleep( );
+    Buffer[ BufferSize ] = 0;
+    State = RX_TIMEOUT;
+    //debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
+}
+
+void OnRxError( void )
+{
+    Radio.SetChannel( HoppingFrequencies[0] );
+    Radio.Sleep( );
+    State = RX_ERROR;
+    debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
+}
+
+void OnFhssChangeChannel( uint8_t channelIndex )
+{
+    Radio.SetChannel( HoppingFrequencies[channelIndex] );
+    debug_if( DEBUG_MESSAGE, "F%d-", channelIndex);
+}