MR16/sx1281-driver-c/example.c

520 lines
20 KiB
C

// /**
// ******************************************************************************
// * File Name : main.c
// * Description : Main program body
// ******************************************************************************
// *
// * COPYRIGHT(c) 2017 STMicroelectronics
// *
// * Redistribution and use in source and binary forms, with or without modification,
// * are permitted provided that the following conditions are met:
// * 1. Redistributions of source code must retain the above copyright notice,
// * this list of conditions and the following disclaimer.
// * 2. Redistributions in binary form must reproduce the above copyright notice,
// * this list of conditions and the following disclaimer in the documentation
// * and/or other materials provided with the distribution.
// * 3. Neither the name of STMicroelectronics nor the names of its contributors
// * may be used to endorse or promote products derived from this software
// * without specific prior written permission.
// *
// * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
// ******************************************************************************
// */
// /* Includes ------------------------------------------------------------------*/
// #include <string.h>
// #include "main.h"
// #include "hw.h"
// #include "radio.h"
// #include "sx1281.h"
// /*!
// * \brief Used to display firmware version UART flow
// */
// #define FIRMWARE_VERSION ( ( char* )"Firmware Version: 170919A" )
// /*!
// * Select mode of operation for the Ping Ping application
// */
// #define MODE_BLE /* Bluetooth Low Energy */
// // #define MODE_LORA /* Long Range */
// // #define MODE_GFSK /* Gaussian Frequency Shift Keying */
// // #define MODE_FLRC /* Fast Long Range Codec */
// #define RF_BL_ADV_CHANNEL_38 2426000000 // Hz
// /*!
// * \brief Defines the nominal frequency
// */
// #define RF_FREQUENCY RF_BL_ADV_CHANNEL_38 // Hz
// /*!
// * \brief Defines the output power in dBm
// *
// * \remark The range of the output power is [-18..+13] dBm
// */
// #define TX_OUTPUT_POWER 13
// /*!
// * \brief Defines the buffer size, i.e. the payload size
// */
// #define BUFFER_SIZE 20
// /*!
// * \brief Number of tick size steps for tx timeout
// */
// #define TX_TIMEOUT_VALUE 10000 // ms
// /*!
// * \brief Number of tick size steps for rx timeout
// */
// #define RX_TIMEOUT_VALUE 1000 // ms
// /*!
// * \brief Size of ticks (used for Tx and Rx timeout)
// */
// #define RX_TIMEOUT_TICK_SIZE RADIO_TICK_SIZE_1000_US
// /*!
// * \brief Defines the size of the token defining message type in the payload
// */
// #define PINGPONGSIZE 4
// /*!
// * \brief Defines the states of the application
// */
// typedef enum
// {
// APP_LOWPOWER,
// APP_RX,
// APP_RX_TIMEOUT,
// APP_RX_ERROR,
// APP_TX,
// APP_TX_TIMEOUT,
// }AppStates_t;
// /*!
// * \brief Function to be executed on Radio Tx Done event
// */
// void OnTxDone( void );
// /*!
// * \brief Function to be executed on Radio Rx Done event
// */
// void OnRxDone( void );
// /*!
// * \brief Function executed on Radio Tx Timeout event
// */
// void OnTxTimeout( void );
// /*!
// * \brief Function executed on Radio Rx Timeout event
// */
// void OnRxTimeout( void );
// /*!
// * \brief Function executed on Radio Rx Error event
// */
// void OnRxError( IrqErrorCode_t );
// /*!
// * \brief Define the possible message type for this application
// */
// const uint8_t PingMsg[] = "PING";
// const uint8_t PongMsg[] = "PONG";
// /*!
// * \brief All the callbacks are stored in a structure
// */
// RadioCallbacks_t Callbacks =
// {
// &OnTxDone, // txDone
// &OnRxDone, // rxDone
// NULL, // syncWordDone
// NULL, // headerDone
// &OnTxTimeout, // txTimeout
// &OnRxTimeout, // rxTimeout
// &OnRxError, // rxError
// NULL, // cadDone
// };
// /*!
// * \brief The size of the buffer
// */
// uint8_t BufferSize = BUFFER_SIZE;
// /*!
// * \brief The buffer
// */
// uint8_t Buffer[BUFFER_SIZE];
// /*!
// * \brief Mask of IRQs to listen to in rx mode
// */
// uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;
// /*!
// * \brief Mask of IRQs to listen to in tx mode
// */
// uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
// /*!
// * \brief The State of the application
// */
// AppStates_t AppState = APP_LOWPOWER;
// #if defined( MODE_BLE )
// /*!
// * \brief In case of BLE, the payload must contain the header
// */
// typedef union
// {
// struct BleAdvHeaderField_s
// {
// uint8_t pduType: 4;
// uint8_t rfu1:2;
// uint8_t txAddr:1;
// uint8_t rxAddr:1;
// uint8_t length:6;
// uint8_t rfu2:2;
// } Fields;
// uint8_t Serial[ 2 ];
// }BleAdvHeaders_t;
// BleAdvHeaders_t ble_header_adv;
// #endif // MODE_BLE
// PacketParams_t packetParams;
// PacketStatus_t packetStatus;
// int main( void )
// {
// bool isMaster = true;
// ModulationParams_t modulationParams;
// HwInit( );
// HAL_Delay( 500 ); // let DC/DC power ramp up
// Radio.Init( &Callbacks );
// Radio.SetRegulatorMode( USE_DCDC ); // Can also be set in LDO mode but consume more power
// memset( &Buffer, 0x00, BufferSize );
// printf( "\n\n\r SX1281 Ping Pong Demo Application. %s\n\n\r", FIRMWARE_VERSION );
// printf( "\n\n\r Radio firmware version 0x%x\n\n\r", Radio.GetFirmwareVersion( ) );
// #if defined( MODE_BLE )
// printf( "\nPing Pong running in BLE mode\n\r" );
// modulationParams.PacketType = PACKET_TYPE_BLE;
// modulationParams.Params.Ble.BitrateBandwidth = GFS_BLE_BR_1_000_BW_1_2;
// modulationParams.Params.Ble.ModulationIndex = GFS_BLE_MOD_IND_0_50;
// modulationParams.Params.Ble.ModulationShaping = RADIO_MOD_SHAPING_BT_0_5;
// packetParams.PacketType = PACKET_TYPE_BLE;
// packetParams.Params.Ble.BlePacketType = BLE_EYELONG_1_0;
// packetParams.Params.Ble.ConnectionState = BLE_ADVERTISER;
// packetParams.Params.Ble.CrcField = BLE_CRC_3B;
// packetParams.Params.Ble.Whitening = RADIO_WHITENING_ON;
// #elif defined( MODE_GFSK )
// printf( "\nPing Pong running in GFSK mode\n\r" );
// modulationParams.PacketType = PACKET_TYPE_GFSK;
// modulationParams.Params.Gfsk.BitrateBandwidth = GFS_BLE_BR_0_125_BW_0_3;
// modulationParams.Params.Gfsk.ModulationIndex = GFS_BLE_MOD_IND_1_00;
// modulationParams.Params.Gfsk.ModulationShaping = RADIO_MOD_SHAPING_BT_1_0;
// packetParams.PacketType = PACKET_TYPE_GFSK;
// packetParams.Params.Gfsk.PreambleLength = PREAMBLE_LENGTH_32_BITS;
// packetParams.Params.Gfsk.SyncWordLength = GFS_SYNCWORD_LENGTH_5_BYTE;
// packetParams.Params.Gfsk.SyncWordMatch = RADIO_RX_MATCH_SYNCWORD_1;
// packetParams.Params.Gfsk.HeaderType = RADIO_PACKET_VARIABLE_LENGTH;
// packetParams.Params.Gfsk.PayloadLength = BUFFER_SIZE;
// packetParams.Params.Gfsk.CrcLength = RADIO_CRC_3_BYTES;
// packetParams.Params.Gfsk.Whitening = RADIO_WHITENING_ON;
// #elif defined( MODE_LORA )
// printf( "\nPing Pong running in LORA mode\n\r" );
// modulationParams.PacketType = PACKET_TYPE_LORA;
// modulationParams.Params.LoRa.SpreadingFactor = LORA_SF12;
// modulationParams.Params.LoRa.Bandwidth = LORA_BW_1600;
// modulationParams.Params.LoRa.CodingRate = LORA_CR_LI_4_7;
// packetParams.PacketType = PACKET_TYPE_LORA;
// packetParams.Params.LoRa.PreambleLength = 12;
// packetParams.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH;
// packetParams.Params.LoRa.PayloadLength = BUFFER_SIZE;
// packetParams.Params.LoRa.CrcMode = LORA_CRC_ON;
// packetParams.Params.LoRa.InvertIQ = LORA_IQ_NORMAL;
// #elif defined( MODE_FLRC )
// printf( "\nPing Pong running in FLRC mode\n\r" );
// modulationParams.PacketType = PACKET_TYPE_FLRC;
// modulationParams.Params.Flrc.BitrateBandwidth = FLRC_BR_0_260_BW_0_3;
// modulationParams.Params.Flrc.CodingRate = FLRC_CR_1_2;
// modulationParams.Params.Flrc.ModulationShaping = RADIO_MOD_SHAPING_BT_1_0;
// packetParams.PacketType = PACKET_TYPE_FLRC;
// packetParams.Params.Flrc.PreambleLength = PREAMBLE_LENGTH_32_BITS;
// packetParams.Params.Flrc.SyncWordLength = FLRC_SYNCWORD_LENGTH_4_BYTE;
// packetParams.Params.Flrc.SyncWordMatch = RADIO_RX_MATCH_SYNCWORD_1;
// packetParams.Params.Flrc.HeaderType = RADIO_PACKET_VARIABLE_LENGTH;
// packetParams.Params.Flrc.PayloadLength = BUFFER_SIZE;
// packetParams.Params.Flrc.CrcLength = RADIO_CRC_3_BYTES;
// packetParams.Params.Flrc.Whitening = RADIO_WHITENING_OFF;
// #else
// #error "Please select the mode of operation for the Ping Ping demo"
// #endif
// Radio.SetStandby( STDBY_RC );
// Radio.SetPacketType( modulationParams.PacketType );
// Radio.SetModulationParams( &modulationParams );
// Radio.SetPacketParams( &packetParams );
// Radio.SetRfFrequency( RF_FREQUENCY );
// Radio.SetBufferBaseAddresses( 0x00, 0x00 );
// Radio.SetTxParams( TX_OUTPUT_POWER, RADIO_RAMP_02_US );
// SX1281SetPollingMode( );
// #if defined( MODE_BLE )
// // only used in GENERIC and BLE mode
// Radio.SetSyncWord( 1, ( uint8_t[] ){ 0xDD, 0xA0, 0x96, 0x69, 0xDD } );
// Radio.WriteRegister(0x9c7, 0x55 );
// Radio.WriteRegister(0x9c8, 0x55 );
// Radio.WriteRegister(0x9c9, 0x55 );
// //Radio.WriteRegister( 0x9c5, 0x33 );
// Radio.SetBleAdvertizerAccessAddress( );
// Radio.SetWhiteningSeed( 0x33 );
// ble_header_adv.Fields.length = PINGPONGSIZE + 2;
// ble_header_adv.Fields.pduType = 2;
// #endif // MODE_BLE
// //可以修改成ws2812做发射/接收指示灯
// // GpioWrite( LED_TX_PORT, LED_TX_PIN, 0 );
// // GpioWrite( LED_RX_PORT, LED_RX_PIN, 0 );
// Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
// AppState = APP_LOWPOWER;
// while( 1 )
// {
// SX1281ProcessIrqs( );
// switch( AppState )
// {
// case APP_RX:
// AppState = APP_LOWPOWER;
// // GpioWrite( LED_RX_PORT, LED_RX_PIN, GpioRead( LED_RX_PORT, LED_RX_PIN ) ^ 1 );
// Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
// #if defined( MODE_BLE )
// // Remove the 2st bytes that are BLE header from Buffer
// memcpy( Buffer, Buffer+2, PINGPONGSIZE );
// #endif // MODE_BLE
// if( isMaster == true )
// {
// if( BufferSize > 0 )
// {
// if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, PINGPONGSIZE ) == 0 )
// {
// printf( "...Pong\r\n" );
// #if defined( MODE_BLE )
// memcpy( Buffer, ble_header_adv.Serial, 2 );
// memcpy( Buffer+2, PingMsg, PINGPONGSIZE );
// #else
// memcpy( Buffer, PingMsg, PINGPONGSIZE );
// #endif
// Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
// }
// else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, PINGPONGSIZE ) == 0 )
// {
// // A master already exists then become a slave
// printf( "...Ping - switch to Slave\r\n" );
// isMaster = false;
// #if defined( MODE_BLE )
// memcpy( Buffer, ble_header_adv.Serial, 2 );
// memcpy( Buffer+2, PongMsg, PINGPONGSIZE );
// #else
// memcpy( Buffer, PongMsg, PINGPONGSIZE );
// #endif
// Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
// }
// else // valid reception but neither a PING or a PONG message
// { // Set device as master ans start again
// isMaster = true;
// #if defined( MODE_BLE )
// memcpy( Buffer, ble_header_adv.Serial, 2 );
// memcpy( Buffer+2, PongMsg, PINGPONGSIZE );
// Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
// #else
// Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
// #endif
// }
// }
// }
// else
// {
// if( BufferSize > 0 )
// {
// if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, PINGPONGSIZE ) == 0 )
// {
// printf( "...Ping\r\n" );
// #if defined( MODE_BLE )
// ble_header_adv.Fields.length = PINGPONGSIZE + 2;
// memcpy( Buffer, ble_header_adv.Serial, 2 );
// memcpy( Buffer+2, PongMsg, PINGPONGSIZE );
// #else
// memcpy( Buffer, PongMsg, PINGPONGSIZE );
// #endif
// Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
// }
// else // valid reception but not a PING as expected
// {
// printf( "...Unexpected packet - switch to master\r\n" );
// isMaster = true;
// Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
// }
// }
// }
// break;
// case APP_TX:
// AppState = APP_LOWPOWER;
// // GpioWrite( LED_TX_PORT, LED_TX_PIN, GpioRead( LED_TX_PORT, LED_TX_PIN ) ^ 1 );
// if( isMaster == true )
// {
// printf( "Ping...\r\n" );
// }
// else
// {
// printf( "Pong...\r\n" );
// }
// Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
// break;
// case APP_RX_TIMEOUT:
// AppState = APP_LOWPOWER;
// if( isMaster == true )
// {
// // Send the next PING frame
// #if defined( MODE_BLE )
// ble_header_adv.Fields.length = PINGPONGSIZE + 2;
// memcpy( Buffer, ble_header_adv.Serial, 2 );
// memcpy( Buffer+2, PingMsg, PINGPONGSIZE );
// #else
// memcpy( Buffer, PingMsg, PINGPONGSIZE );
// #endif
// Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
// }
// else
// {
// Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
// }
// break;
// case APP_RX_ERROR:
// AppState = APP_LOWPOWER;
// // We have received a Packet with a CRC error, send reply as if packet was correct
// if( isMaster == true )
// {
// // Send the next PING frame
// #if defined( MODE_BLE )
// ble_header_adv.Fields.length = PINGPONGSIZE + 2;
// memcpy( Buffer, ble_header_adv.Serial, 2 );
// memcpy( Buffer+2, PingMsg, PINGPONGSIZE );
// #else
// memcpy( Buffer, PingMsg, PINGPONGSIZE );
// #endif
// Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
// }
// else
// {
// // Send the next PONG frame
// #if defined( MODE_BLE )
// ble_header_adv.Fields.length = PINGPONGSIZE + 2;
// memcpy( Buffer, ble_header_adv.Serial, 2 );
// memcpy( Buffer+2, PongMsg, PINGPONGSIZE );
// #else
// memcpy( Buffer, PongMsg, PINGPONGSIZE );
// #endif
// Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
// }
// break;
// case APP_TX_TIMEOUT:
// AppState = APP_LOWPOWER;
// Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
// Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
// break;
// case APP_LOWPOWER:
// break;
// default:
// // Set low power
// break;
// }
// }
// }
// void OnTxDone( void )
// {
// AppState = APP_TX;
// }
// void OnRxDone( void )
// {
// AppState = APP_RX;
// }
// void OnTxTimeout( void )
// {
// AppState = APP_TX_TIMEOUT;
// printf( "<>>>>>>>>TXE\n\r" );
// }
// void OnRxTimeout( void )
// {
// AppState = APP_RX_TIMEOUT;
// }
// void OnRxError( IrqErrorCode_t errorCode )
// {
// AppState = APP_RX_ERROR;
// printf( "RXE<>>>>>>>>\n\r" );
// }
// void OnCadDone( bool channelActivityDetected )
// {
// }