Alarm generator, transmitter side

Dependencies:   sx12xx_hal

radio chip selection

Radio chip driver is not included, allowing choice of radio device.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
if you're using SX1280, then import sx1280 driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.

This is transmitter project; Receiver side is Alarm Slave project.
This project generates alarm (transmits) from grounding certain pins.
To find the actual pins used, refer to the code where pin[A-D] is declared as DigitalIn.

Alarm message is sent N times with future timestamp indicating when alarm is to occur. This accommodates dropped packets, resulting in alarm occurring when as few as 1 packet is received.

Committer:
dudmuck
Date:
Tue Aug 22 10:06:40 2017 -0700
Revision:
0:cb38da4f4b04
Child:
1:3199506bc2e5
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:cb38da4f4b04 1 #include "sx127x_lora.h"
dudmuck 0:cb38da4f4b04 2
dudmuck 0:cb38da4f4b04 3 SPI spi(D11, D12, D13); // mosi, miso, sclk
dudmuck 0:cb38da4f4b04 4 // dio0, dio1, nss, spi, rst
dudmuck 0:cb38da4f4b04 5 SX127x radio( D2, D3, D10, spi, A0); // sx1276 arduino shield
dudmuck 0:cb38da4f4b04 6
dudmuck 0:cb38da4f4b04 7 SX127x_lora lora(radio);
dudmuck 0:cb38da4f4b04 8 DigitalInOut rfsw(A4); // for SX1276 arduino shield
dudmuck 0:cb38da4f4b04 9
dudmuck 0:cb38da4f4b04 10 void rfsw_callback()
dudmuck 0:cb38da4f4b04 11 {
dudmuck 0:cb38da4f4b04 12 if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
dudmuck 0:cb38da4f4b04 13 rfsw = 1;
dudmuck 0:cb38da4f4b04 14 } else {
dudmuck 0:cb38da4f4b04 15 rfsw = 0;
dudmuck 0:cb38da4f4b04 16 }
dudmuck 0:cb38da4f4b04 17 }
dudmuck 0:cb38da4f4b04 18 /**********************************************************************/
dudmuck 0:cb38da4f4b04 19
dudmuck 0:cb38da4f4b04 20 DigitalIn user_button(USER_BUTTON);
dudmuck 0:cb38da4f4b04 21 Timer t;
dudmuck 0:cb38da4f4b04 22 #define CMD_ALARM 0x01
dudmuck 0:cb38da4f4b04 23
dudmuck 0:cb38da4f4b04 24 static uint16_t crc_ccitt( uint8_t *buffer, uint16_t length )
dudmuck 0:cb38da4f4b04 25 {
dudmuck 0:cb38da4f4b04 26 // The CRC calculation follows CCITT
dudmuck 0:cb38da4f4b04 27 const uint16_t polynom = 0x1021;
dudmuck 0:cb38da4f4b04 28 // CRC initial value
dudmuck 0:cb38da4f4b04 29 uint16_t crc = 0x0000;
dudmuck 0:cb38da4f4b04 30
dudmuck 0:cb38da4f4b04 31 if( buffer == NULL )
dudmuck 0:cb38da4f4b04 32 {
dudmuck 0:cb38da4f4b04 33 return 0;
dudmuck 0:cb38da4f4b04 34 }
dudmuck 0:cb38da4f4b04 35
dudmuck 0:cb38da4f4b04 36 for( uint16_t i = 0; i < length; ++i )
dudmuck 0:cb38da4f4b04 37 {
dudmuck 0:cb38da4f4b04 38 crc ^= ( uint16_t ) buffer[i] << 8;
dudmuck 0:cb38da4f4b04 39 for( uint16_t j = 0; j < 8; ++j )
dudmuck 0:cb38da4f4b04 40 {
dudmuck 0:cb38da4f4b04 41 crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 );
dudmuck 0:cb38da4f4b04 42 }
dudmuck 0:cb38da4f4b04 43 }
dudmuck 0:cb38da4f4b04 44
dudmuck 0:cb38da4f4b04 45 return crc;
dudmuck 0:cb38da4f4b04 46 }
dudmuck 0:cb38da4f4b04 47
dudmuck 0:cb38da4f4b04 48 void transmit(unsigned target)
dudmuck 0:cb38da4f4b04 49 {
dudmuck 0:cb38da4f4b04 50 unsigned t_diff;
dudmuck 0:cb38da4f4b04 51 uint16_t crc;
dudmuck 0:cb38da4f4b04 52
dudmuck 0:cb38da4f4b04 53 radio.tx_buf[0] = CMD_ALARM;
dudmuck 0:cb38da4f4b04 54 t_diff = target - t.read_us();
dudmuck 0:cb38da4f4b04 55 radio.tx_buf[1] = t_diff >> 24;
dudmuck 0:cb38da4f4b04 56 radio.tx_buf[2] = t_diff >> 16;
dudmuck 0:cb38da4f4b04 57 radio.tx_buf[3] = t_diff >> 8;
dudmuck 0:cb38da4f4b04 58 radio.tx_buf[4] = t_diff & 0xff;
dudmuck 0:cb38da4f4b04 59 crc = crc_ccitt(radio.tx_buf, 5);
dudmuck 0:cb38da4f4b04 60 radio.tx_buf[5] = crc >> 8;
dudmuck 0:cb38da4f4b04 61 radio.tx_buf[6] = crc & 0xff;
dudmuck 0:cb38da4f4b04 62
dudmuck 0:cb38da4f4b04 63
dudmuck 0:cb38da4f4b04 64 lora.start_tx(lora.RegPayloadLength); /* begin transmission */
dudmuck 0:cb38da4f4b04 65
dudmuck 0:cb38da4f4b04 66 while (lora.service() != SERVICE_TX_DONE) /* wait for transmission to complete */
dudmuck 0:cb38da4f4b04 67 ;
dudmuck 0:cb38da4f4b04 68
dudmuck 0:cb38da4f4b04 69 printf("t_diff:%u crc:%04x\r\n", t_diff, crc);
dudmuck 0:cb38da4f4b04 70 }
dudmuck 0:cb38da4f4b04 71
dudmuck 0:cb38da4f4b04 72 #define TARGET_LATENCY 2000000
dudmuck 0:cb38da4f4b04 73 void send_alarm()
dudmuck 0:cb38da4f4b04 74 {
dudmuck 0:cb38da4f4b04 75 int i;
dudmuck 0:cb38da4f4b04 76 unsigned target = t.read_us() + TARGET_LATENCY;
dudmuck 0:cb38da4f4b04 77 printf("send_alarm() %u\n", target);
dudmuck 0:cb38da4f4b04 78
dudmuck 0:cb38da4f4b04 79 for (i = 0; i < 3; i++) {
dudmuck 0:cb38da4f4b04 80 transmit(target);
dudmuck 0:cb38da4f4b04 81 wait(0.1);
dudmuck 0:cb38da4f4b04 82 }
dudmuck 0:cb38da4f4b04 83 }
dudmuck 0:cb38da4f4b04 84
dudmuck 0:cb38da4f4b04 85 int main()
dudmuck 0:cb38da4f4b04 86 {
dudmuck 0:cb38da4f4b04 87 printf("\r\nreset-tx\r\n");
dudmuck 0:cb38da4f4b04 88 t.start();
dudmuck 0:cb38da4f4b04 89 radio.rf_switch = rfsw_callback;
dudmuck 0:cb38da4f4b04 90
dudmuck 0:cb38da4f4b04 91 radio.set_frf_MHz(910.8);
dudmuck 0:cb38da4f4b04 92 lora.enable();
dudmuck 0:cb38da4f4b04 93 lora.setBw_KHz(500);
dudmuck 0:cb38da4f4b04 94 lora.setSf(11);
dudmuck 0:cb38da4f4b04 95
dudmuck 0:cb38da4f4b04 96 /* RFO or PABOOST choice:
dudmuck 0:cb38da4f4b04 97 * SX1276 shield: RFO if using 900MHz, or PA_BOOST if using 433MHz
dudmuck 0:cb38da4f4b04 98 */
dudmuck 0:cb38da4f4b04 99 rfsw.input();
dudmuck 0:cb38da4f4b04 100 if (rfsw.read()) {
dudmuck 0:cb38da4f4b04 101 printf("LAS\r\n");
dudmuck 0:cb38da4f4b04 102 /* LAS HF=PA_BOOST LF=RFO */
dudmuck 0:cb38da4f4b04 103 if (radio.HF)
dudmuck 0:cb38da4f4b04 104 radio.RegPaConfig.bits.PaSelect = 1;
dudmuck 0:cb38da4f4b04 105 else
dudmuck 0:cb38da4f4b04 106 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 0:cb38da4f4b04 107 } else {
dudmuck 0:cb38da4f4b04 108 /* MAS shield board, only RFO TX */
dudmuck 0:cb38da4f4b04 109 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 0:cb38da4f4b04 110 printf("MAS\r\n");
dudmuck 0:cb38da4f4b04 111 }
dudmuck 0:cb38da4f4b04 112 rfsw.output();
dudmuck 0:cb38da4f4b04 113 radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
dudmuck 0:cb38da4f4b04 114
dudmuck 0:cb38da4f4b04 115 /* constant payload length */
dudmuck 0:cb38da4f4b04 116 lora.RegPayloadLength = 7;
dudmuck 0:cb38da4f4b04 117 radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
dudmuck 0:cb38da4f4b04 118
dudmuck 0:cb38da4f4b04 119 for (;;) {
dudmuck 0:cb38da4f4b04 120 if (!user_button.read()) {
dudmuck 0:cb38da4f4b04 121 int i;
dudmuck 0:cb38da4f4b04 122 for (i = 0; i < 5; i++) {
dudmuck 0:cb38da4f4b04 123 wait(0.01);
dudmuck 0:cb38da4f4b04 124 if (user_button.read()) {
dudmuck 0:cb38da4f4b04 125 printf("trans\r\n");
dudmuck 0:cb38da4f4b04 126 break;
dudmuck 0:cb38da4f4b04 127 }
dudmuck 0:cb38da4f4b04 128 }
dudmuck 0:cb38da4f4b04 129 if (i == 5)
dudmuck 0:cb38da4f4b04 130 send_alarm();
dudmuck 0:cb38da4f4b04 131
dudmuck 0:cb38da4f4b04 132 while (!user_button.read())
dudmuck 0:cb38da4f4b04 133 ;
dudmuck 0:cb38da4f4b04 134 }
dudmuck 0:cb38da4f4b04 135
dudmuck 0:cb38da4f4b04 136 } // ..for (;;)
dudmuck 0:cb38da4f4b04 137 }