wayne roberts / Mbed OS alarm_analog_master

Dependencies:   sx12xx_hal

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "radio.h"
00002 
00003 #define NUM_ANALOG_IN       4
00004 
00005 #if defined(SX127x_H) || defined(SX126x_H)
00006     #define BW_KHZ              500
00007     #define SPREADING_FACTOR    11
00008     #define CF_HZ               910800000
00009     #if defined(SX126x_H)
00010         #define TX_DBM              (Radio::chipType == CHIP_TYPE_SX1262 ? 20 : 14) 
00011     #else
00012         #define TX_DBM              17
00013     #endif
00014 #elif defined(SX128x_H)
00015     #define BW_KHZ              200
00016     #define SPREADING_FACTOR    11
00017     #define CF_HZ               2487000000
00018 
00019     #define TX_DBM              5
00020 #endif
00021 
00022 #define PWM_HZ          120
00023 
00024 #if defined(TARGET_FF_MORPHO) && defined(TARGET_FAMILY_STM32)
00025 PinName pin_names[NUM_ANALOG_IN] = {
00026     PC_2, /* CN7-35 */
00027     PC_3, /* CN7-37 */
00028     PC_4, /* CN10-34 */
00029     PC_5  /* CN10-6 */
00030 };
00031 #endif
00032 
00033 #define CMD_PWM_A             0x02
00034 #define CMD_PWM_B             0x03
00035 #define CMD_PWM_C             0x04
00036 #define CMD_PWM_D             0x05
00037 
00038 const uint8_t rfCmds[NUM_ANALOG_IN] = {
00039     CMD_PWM_A,
00040     CMD_PWM_B,
00041     CMD_PWM_C,
00042     CMD_PWM_D
00043 };
00044 
00045 typedef struct {
00046     AnalogIn* ain;
00047     uint16_t prev;
00048     int8_t movement;
00049     bool sent;
00050 } analog_t;
00051 
00052 analog_t _a_[NUM_ANALOG_IN];
00053 
00054 Timer t;
00055 
00056 volatile bool tx_done;
00057 
00058 static uint16_t crc_ccitt( uint8_t *buffer, uint16_t length )
00059 {
00060     // The CRC calculation follows CCITT
00061     const uint16_t polynom = 0x1021;
00062     // CRC initial value
00063     uint16_t crc = 0x0000;
00064 
00065     if( buffer == NULL )
00066     {
00067         return 0;
00068     }
00069 
00070     for( uint16_t i = 0; i < length; ++i )
00071     {
00072         crc ^= ( uint16_t ) buffer[i] << 8;
00073         for( uint16_t j = 0; j < 8; ++j )
00074         {
00075             crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 );
00076         }
00077     }
00078 
00079     return crc;
00080 }
00081 
00082 void transmit(unsigned target, uint8_t cmd, uint16_t ain)
00083 {
00084     unsigned t_diff;
00085     uint16_t crc;
00086 
00087     Radio::radio.tx_buf[0] = cmd;
00088     Radio::radio.tx_buf[1] = PWM_HZ;
00089     Radio::radio.tx_buf[2] = ain >> 8;  // pwm duty
00090     t_diff = target - t.read_us();
00091     Radio::radio.tx_buf[3] = t_diff >> 24;
00092     Radio::radio.tx_buf[4] = t_diff >> 16;
00093     Radio::radio.tx_buf[5] = t_diff >> 8;
00094     Radio::radio.tx_buf[6] = t_diff & 0xff;
00095     crc = crc_ccitt(Radio::radio.tx_buf, 7);
00096     Radio::radio.tx_buf[7] = crc >> 8;
00097     Radio::radio.tx_buf[8] = crc & 0xff;
00098 
00099     Radio::Send(9, 0, 0, 0);
00100 
00101     for (tx_done = false; !tx_done; )
00102         Radio::service();
00103 
00104     printf("t_diff:%u crc:%04x\r\n", t_diff, crc);
00105 }
00106 
00107 #define TARGET_LATENCY      2000000
00108 void send_alarm(uint8_t cmd, uint16_t ain)
00109 {
00110     int i;
00111     unsigned target = t.read_us() + TARGET_LATENCY;
00112     printf("send_alarm() %u\n", target);
00113 
00114     for (i = 0; i < 5; i++) {
00115         transmit(target, cmd, ain);
00116         wait(0.1);
00117     }
00118 }
00119 
00120 void txDoneCB()
00121 {
00122     tx_done = true;
00123 }
00124 
00125 void rxDoneCB(uint8_t size, float Rssi, float Snr)
00126 {
00127 }
00128 
00129 #define AIN_REST_THRESHOLD      96  // 12bit left justified
00130 
00131 void analog_mainloop(analog_t* ana, uint8_t rfCmd)
00132 {
00133     uint16_t ain = ana->ain->read_u16();
00134     uint16_t diff = abs(ain-ana->prev);
00135     if (diff > AIN_REST_THRESHOLD) {
00136         ana->sent = false;
00137         if (ana->movement < 1)
00138             ana->movement = 1;
00139         else {
00140             if (++ana->movement > 16)
00141                 ana->movement = 16;
00142         }
00143     } else {
00144         /* steady state */
00145         if (ana->movement > 0)
00146             ana->movement = 0;
00147         else {
00148             if (--ana->movement < -16) {
00149                 ana->movement = -16;
00150                 if (!ana->sent) {
00151                     printf("## %02x ##\r\n", ain >> 8);
00152                     send_alarm(rfCmd, ain);
00153                     ana->sent = true;
00154                 }
00155             }
00156         }
00157     }
00158     //printf("%05u  diff:%04u  move:%d\r\n", ain, diff, ain_movement);
00159     ana->prev = ain;
00160 }
00161 
00162 void trigger_init()
00163 {
00164     unsigned n;
00165     for (n = 0; n < NUM_ANALOG_IN; n++) {
00166         _a_[n].ain = new AnalogIn(pin_names[n]);
00167         _a_[n].prev = _a_[n].ain->read_u16();
00168         _a_[n].movement = 0;
00169         _a_[n].sent = false;
00170     }
00171 }
00172 
00173 const RadioEvents_t rev = {
00174     /* Dio0_top_half */     NULL,
00175     /* TxDone_topHalf */    NULL,
00176     /* TxDone_botHalf */    txDoneCB,
00177     /* TxTimeout  */        NULL,
00178     /* RxDone  */           rxDoneCB,
00179     /* RxTimeout  */        NULL,
00180     /* RxError  */          NULL,
00181     /* FhssChangeChannel  */NULL,
00182     /* CadDone  */          NULL
00183 };
00184 
00185 int main()
00186 {
00187     printf("\r\nreset-tx\r\n");
00188 
00189     trigger_init();
00190 
00191     t.start();
00192 
00193     Radio::Init(&rev);
00194 
00195     Radio::Standby();
00196     Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1);
00197     Radio::LoRaPacketConfig(8, false, true, false);  // preambleLen, fixLen, crcOn, invIQ
00198     Radio::SetChannel(CF_HZ);
00199 
00200     Radio::set_tx_dbm(TX_DBM);
00201                 
00202     for (;;) {       
00203         unsigned n;
00204         for (n = 0; n < NUM_ANALOG_IN; n++) {
00205             analog_mainloop(&_a_[n], rfCmds[n]);
00206         }
00207         wait_us(5000);
00208     } // ..for (;;)
00209 }