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:
Thu Aug 31 23:15:04 2017 +0000
Revision:
1:3199506bc2e5
Parent:
0:cb38da4f4b04
Child:
2:0b7620bda2c9
use 4 input pins

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 1:3199506bc2e5 20 DigitalIn pc3(PC_3);
dudmuck 1:3199506bc2e5 21 DigitalIn pc2(PC_2);
dudmuck 1:3199506bc2e5 22 DigitalIn pc6(PC_6);
dudmuck 1:3199506bc2e5 23 DigitalIn pc8(PC_8);
dudmuck 0:cb38da4f4b04 24 Timer t;
dudmuck 1:3199506bc2e5 25 #define CMD_PC2 0x02
dudmuck 1:3199506bc2e5 26 #define CMD_PC3 0x03
dudmuck 1:3199506bc2e5 27 #define CMD_PC6 0x06
dudmuck 1:3199506bc2e5 28 #define CMD_PC8 0x08
dudmuck 0:cb38da4f4b04 29
dudmuck 0:cb38da4f4b04 30 static uint16_t crc_ccitt( uint8_t *buffer, uint16_t length )
dudmuck 0:cb38da4f4b04 31 {
dudmuck 0:cb38da4f4b04 32 // The CRC calculation follows CCITT
dudmuck 0:cb38da4f4b04 33 const uint16_t polynom = 0x1021;
dudmuck 0:cb38da4f4b04 34 // CRC initial value
dudmuck 0:cb38da4f4b04 35 uint16_t crc = 0x0000;
dudmuck 0:cb38da4f4b04 36
dudmuck 0:cb38da4f4b04 37 if( buffer == NULL )
dudmuck 0:cb38da4f4b04 38 {
dudmuck 0:cb38da4f4b04 39 return 0;
dudmuck 0:cb38da4f4b04 40 }
dudmuck 0:cb38da4f4b04 41
dudmuck 0:cb38da4f4b04 42 for( uint16_t i = 0; i < length; ++i )
dudmuck 0:cb38da4f4b04 43 {
dudmuck 0:cb38da4f4b04 44 crc ^= ( uint16_t ) buffer[i] << 8;
dudmuck 0:cb38da4f4b04 45 for( uint16_t j = 0; j < 8; ++j )
dudmuck 0:cb38da4f4b04 46 {
dudmuck 0:cb38da4f4b04 47 crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 );
dudmuck 0:cb38da4f4b04 48 }
dudmuck 0:cb38da4f4b04 49 }
dudmuck 0:cb38da4f4b04 50
dudmuck 0:cb38da4f4b04 51 return crc;
dudmuck 0:cb38da4f4b04 52 }
dudmuck 0:cb38da4f4b04 53
dudmuck 1:3199506bc2e5 54 void transmit(unsigned target, uint8_t cmd)
dudmuck 0:cb38da4f4b04 55 {
dudmuck 0:cb38da4f4b04 56 unsigned t_diff;
dudmuck 0:cb38da4f4b04 57 uint16_t crc;
dudmuck 0:cb38da4f4b04 58
dudmuck 1:3199506bc2e5 59 radio.tx_buf[0] = cmd;
dudmuck 0:cb38da4f4b04 60 t_diff = target - t.read_us();
dudmuck 0:cb38da4f4b04 61 radio.tx_buf[1] = t_diff >> 24;
dudmuck 0:cb38da4f4b04 62 radio.tx_buf[2] = t_diff >> 16;
dudmuck 0:cb38da4f4b04 63 radio.tx_buf[3] = t_diff >> 8;
dudmuck 0:cb38da4f4b04 64 radio.tx_buf[4] = t_diff & 0xff;
dudmuck 0:cb38da4f4b04 65 crc = crc_ccitt(radio.tx_buf, 5);
dudmuck 0:cb38da4f4b04 66 radio.tx_buf[5] = crc >> 8;
dudmuck 0:cb38da4f4b04 67 radio.tx_buf[6] = crc & 0xff;
dudmuck 0:cb38da4f4b04 68
dudmuck 0:cb38da4f4b04 69
dudmuck 0:cb38da4f4b04 70 lora.start_tx(lora.RegPayloadLength); /* begin transmission */
dudmuck 0:cb38da4f4b04 71
dudmuck 1:3199506bc2e5 72 while (lora.service() != SERVICE_TX_DONE) { /* wait for transmission to complete */
dudmuck 1:3199506bc2e5 73 }
dudmuck 0:cb38da4f4b04 74
dudmuck 0:cb38da4f4b04 75 printf("t_diff:%u crc:%04x\r\n", t_diff, crc);
dudmuck 0:cb38da4f4b04 76 }
dudmuck 0:cb38da4f4b04 77
dudmuck 0:cb38da4f4b04 78 #define TARGET_LATENCY 2000000
dudmuck 1:3199506bc2e5 79 void send_alarm(uint8_t cmd)
dudmuck 0:cb38da4f4b04 80 {
dudmuck 0:cb38da4f4b04 81 int i;
dudmuck 0:cb38da4f4b04 82 unsigned target = t.read_us() + TARGET_LATENCY;
dudmuck 0:cb38da4f4b04 83 printf("send_alarm() %u\n", target);
dudmuck 0:cb38da4f4b04 84
dudmuck 1:3199506bc2e5 85 for (i = 0; i < 5; i++) {
dudmuck 1:3199506bc2e5 86 transmit(target, cmd);
dudmuck 0:cb38da4f4b04 87 wait(0.1);
dudmuck 0:cb38da4f4b04 88 }
dudmuck 0:cb38da4f4b04 89 }
dudmuck 1:3199506bc2e5 90
dudmuck 1:3199506bc2e5 91 void debounce(DigitalIn* pin, uint8_t cmd)
dudmuck 1:3199506bc2e5 92 {
dudmuck 1:3199506bc2e5 93 if (!pin->read()) {
dudmuck 1:3199506bc2e5 94 int i;
dudmuck 1:3199506bc2e5 95 for (i = 0; i < 5; i++) {
dudmuck 1:3199506bc2e5 96 wait(0.01);
dudmuck 1:3199506bc2e5 97 if (pin->read()) {
dudmuck 1:3199506bc2e5 98 printf("trans\r\n");
dudmuck 1:3199506bc2e5 99 break;
dudmuck 1:3199506bc2e5 100 }
dudmuck 1:3199506bc2e5 101 }
dudmuck 1:3199506bc2e5 102 if (i == 5)
dudmuck 1:3199506bc2e5 103 send_alarm(cmd);
dudmuck 1:3199506bc2e5 104
dudmuck 1:3199506bc2e5 105 while (!pin->read())
dudmuck 1:3199506bc2e5 106 ;
dudmuck 1:3199506bc2e5 107 }
dudmuck 1:3199506bc2e5 108 }
dudmuck 0:cb38da4f4b04 109
dudmuck 0:cb38da4f4b04 110 int main()
dudmuck 0:cb38da4f4b04 111 {
dudmuck 0:cb38da4f4b04 112 printf("\r\nreset-tx\r\n");
dudmuck 0:cb38da4f4b04 113 t.start();
dudmuck 1:3199506bc2e5 114
dudmuck 1:3199506bc2e5 115 pc3.mode(PullUp);
dudmuck 1:3199506bc2e5 116 pc2.mode(PullUp);
dudmuck 1:3199506bc2e5 117 pc6.mode(PullUp);
dudmuck 1:3199506bc2e5 118 pc8.mode(PullUp);
dudmuck 1:3199506bc2e5 119
dudmuck 0:cb38da4f4b04 120 radio.rf_switch = rfsw_callback;
dudmuck 0:cb38da4f4b04 121
dudmuck 0:cb38da4f4b04 122 radio.set_frf_MHz(910.8);
dudmuck 0:cb38da4f4b04 123 lora.enable();
dudmuck 0:cb38da4f4b04 124 lora.setBw_KHz(500);
dudmuck 0:cb38da4f4b04 125 lora.setSf(11);
dudmuck 0:cb38da4f4b04 126
dudmuck 0:cb38da4f4b04 127 /* RFO or PABOOST choice:
dudmuck 0:cb38da4f4b04 128 * SX1276 shield: RFO if using 900MHz, or PA_BOOST if using 433MHz
dudmuck 0:cb38da4f4b04 129 */
dudmuck 0:cb38da4f4b04 130 rfsw.input();
dudmuck 0:cb38da4f4b04 131 if (rfsw.read()) {
dudmuck 0:cb38da4f4b04 132 printf("LAS\r\n");
dudmuck 0:cb38da4f4b04 133 /* LAS HF=PA_BOOST LF=RFO */
dudmuck 0:cb38da4f4b04 134 if (radio.HF)
dudmuck 0:cb38da4f4b04 135 radio.RegPaConfig.bits.PaSelect = 1;
dudmuck 0:cb38da4f4b04 136 else
dudmuck 0:cb38da4f4b04 137 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 0:cb38da4f4b04 138 } else {
dudmuck 0:cb38da4f4b04 139 /* MAS shield board, only RFO TX */
dudmuck 0:cb38da4f4b04 140 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 0:cb38da4f4b04 141 printf("MAS\r\n");
dudmuck 0:cb38da4f4b04 142 }
dudmuck 0:cb38da4f4b04 143 rfsw.output();
dudmuck 0:cb38da4f4b04 144 radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
dudmuck 0:cb38da4f4b04 145
dudmuck 0:cb38da4f4b04 146 /* constant payload length */
dudmuck 0:cb38da4f4b04 147 lora.RegPayloadLength = 7;
dudmuck 0:cb38da4f4b04 148 radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
dudmuck 0:cb38da4f4b04 149
dudmuck 0:cb38da4f4b04 150 for (;;) {
dudmuck 1:3199506bc2e5 151 debounce(&pc3, CMD_PC3);
dudmuck 1:3199506bc2e5 152 debounce(&pc2, CMD_PC2);
dudmuck 1:3199506bc2e5 153 debounce(&pc6, CMD_PC6);
dudmuck 1:3199506bc2e5 154 debounce(&pc8, CMD_PC8);
dudmuck 0:cb38da4f4b04 155 } // ..for (;;)
dudmuck 0:cb38da4f4b04 156 }