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:
Fri Jan 26 01:19:48 2018 +0000
Revision:
3:d8b57eca8c45
Parent:
2:0b7620bda2c9
Child:
4:19056d9707ef
support DISCO-L072CZ-LRWAN

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:cb38da4f4b04 1 #include "sx127x_lora.h"
dudmuck 0:cb38da4f4b04 2
dudmuck 3:d8b57eca8c45 3 #ifdef TARGET_DISCO_L072CZ_LRWAN1
dudmuck 3:d8b57eca8c45 4
dudmuck 3:d8b57eca8c45 5 SPI spi(PA_7, PA_6, PB_3); // mosi, miso, sclk
dudmuck 3:d8b57eca8c45 6 // dio0, dio1, nss, spi, rst
dudmuck 3:d8b57eca8c45 7 SX127x radio(PB_4, PB_1, PA_15, spi, PC_0);
dudmuck 3:d8b57eca8c45 8
dudmuck 3:d8b57eca8c45 9 #define CRF1 PA_1
dudmuck 3:d8b57eca8c45 10 #define CRF2 PC_2
dudmuck 3:d8b57eca8c45 11 #define CRF3 PC_1
dudmuck 3:d8b57eca8c45 12 DigitalOut Vctl1(CRF1);
dudmuck 3:d8b57eca8c45 13 DigitalOut Vctl2(CRF2);
dudmuck 3:d8b57eca8c45 14 DigitalOut Vctl3(CRF3);
dudmuck 3:d8b57eca8c45 15
dudmuck 3:d8b57eca8c45 16 void rfsw_callback()
dudmuck 3:d8b57eca8c45 17 {
dudmuck 3:d8b57eca8c45 18 if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
dudmuck 3:d8b57eca8c45 19 Vctl1 = 0;
dudmuck 3:d8b57eca8c45 20 if (radio.RegPaConfig.bits.PaSelect) {
dudmuck 3:d8b57eca8c45 21 Vctl2 = 0;
dudmuck 3:d8b57eca8c45 22 Vctl3 = 1;
dudmuck 3:d8b57eca8c45 23 } else {
dudmuck 3:d8b57eca8c45 24 Vctl2 = 1;
dudmuck 3:d8b57eca8c45 25 Vctl3 = 0;
dudmuck 3:d8b57eca8c45 26 }
dudmuck 3:d8b57eca8c45 27 } else {
dudmuck 3:d8b57eca8c45 28 if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE)
dudmuck 3:d8b57eca8c45 29 Vctl1 = 1;
dudmuck 3:d8b57eca8c45 30 else
dudmuck 3:d8b57eca8c45 31 Vctl1 = 0;
dudmuck 3:d8b57eca8c45 32
dudmuck 3:d8b57eca8c45 33 Vctl2 = 0;
dudmuck 3:d8b57eca8c45 34 Vctl3 = 0;
dudmuck 3:d8b57eca8c45 35 }
dudmuck 3:d8b57eca8c45 36 }
dudmuck 3:d8b57eca8c45 37
dudmuck 3:d8b57eca8c45 38 DigitalIn pinA(PB_12);
dudmuck 3:d8b57eca8c45 39 DigitalIn pinB(PB_13);
dudmuck 3:d8b57eca8c45 40 DigitalIn pinC(PB_14);
dudmuck 3:d8b57eca8c45 41 DigitalIn pinD(PB_15);
dudmuck 3:d8b57eca8c45 42 #else
dudmuck 3:d8b57eca8c45 43 SPI spi(D11, D12, D13); // mosi, miso, sclk
dudmuck 3:d8b57eca8c45 44 // dio0, dio1, nss, spi, rst
dudmuck 3:d8b57eca8c45 45 SX127x radio( D2, D3, D10, spi, A0); // sx1276 arduino shield
dudmuck 3:d8b57eca8c45 46
dudmuck 3:d8b57eca8c45 47 DigitalInOut rfsw(A4); // for SX1276 arduino shield
dudmuck 3:d8b57eca8c45 48
dudmuck 3:d8b57eca8c45 49 void rfsw_callback()
dudmuck 3:d8b57eca8c45 50 {
dudmuck 3:d8b57eca8c45 51 if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
dudmuck 3:d8b57eca8c45 52 rfsw = 1;
dudmuck 3:d8b57eca8c45 53 } else {
dudmuck 3:d8b57eca8c45 54 rfsw = 0;
dudmuck 3:d8b57eca8c45 55 }
dudmuck 0:cb38da4f4b04 56 }
dudmuck 3:d8b57eca8c45 57
dudmuck 3:d8b57eca8c45 58 DigitalIn pinA(PC_3);
dudmuck 3:d8b57eca8c45 59 DigitalIn pinB(PC_2);
dudmuck 3:d8b57eca8c45 60 DigitalIn pinC(PC_6);
dudmuck 3:d8b57eca8c45 61 DigitalIn pinD(PC_8);
dudmuck 3:d8b57eca8c45 62 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */
dudmuck 3:d8b57eca8c45 63
dudmuck 0:cb38da4f4b04 64 /**********************************************************************/
dudmuck 0:cb38da4f4b04 65
dudmuck 3:d8b57eca8c45 66 SX127x_lora lora(radio);
dudmuck 0:cb38da4f4b04 67 Timer t;
dudmuck 3:d8b57eca8c45 68 #define CMD_PINA 0x02
dudmuck 3:d8b57eca8c45 69 #define CMD_PINB 0x03
dudmuck 3:d8b57eca8c45 70 #define CMD_PINC 0x06
dudmuck 3:d8b57eca8c45 71 #define CMD_PIND 0x08
dudmuck 0:cb38da4f4b04 72
dudmuck 0:cb38da4f4b04 73 static uint16_t crc_ccitt( uint8_t *buffer, uint16_t length )
dudmuck 0:cb38da4f4b04 74 {
dudmuck 0:cb38da4f4b04 75 // The CRC calculation follows CCITT
dudmuck 0:cb38da4f4b04 76 const uint16_t polynom = 0x1021;
dudmuck 0:cb38da4f4b04 77 // CRC initial value
dudmuck 0:cb38da4f4b04 78 uint16_t crc = 0x0000;
dudmuck 0:cb38da4f4b04 79
dudmuck 0:cb38da4f4b04 80 if( buffer == NULL )
dudmuck 0:cb38da4f4b04 81 {
dudmuck 0:cb38da4f4b04 82 return 0;
dudmuck 0:cb38da4f4b04 83 }
dudmuck 0:cb38da4f4b04 84
dudmuck 0:cb38da4f4b04 85 for( uint16_t i = 0; i < length; ++i )
dudmuck 0:cb38da4f4b04 86 {
dudmuck 0:cb38da4f4b04 87 crc ^= ( uint16_t ) buffer[i] << 8;
dudmuck 0:cb38da4f4b04 88 for( uint16_t j = 0; j < 8; ++j )
dudmuck 0:cb38da4f4b04 89 {
dudmuck 0:cb38da4f4b04 90 crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 );
dudmuck 0:cb38da4f4b04 91 }
dudmuck 0:cb38da4f4b04 92 }
dudmuck 0:cb38da4f4b04 93
dudmuck 0:cb38da4f4b04 94 return crc;
dudmuck 0:cb38da4f4b04 95 }
dudmuck 0:cb38da4f4b04 96
dudmuck 1:3199506bc2e5 97 void transmit(unsigned target, uint8_t cmd)
dudmuck 0:cb38da4f4b04 98 {
dudmuck 0:cb38da4f4b04 99 unsigned t_diff;
dudmuck 0:cb38da4f4b04 100 uint16_t crc;
dudmuck 0:cb38da4f4b04 101
dudmuck 1:3199506bc2e5 102 radio.tx_buf[0] = cmd;
dudmuck 0:cb38da4f4b04 103 t_diff = target - t.read_us();
dudmuck 0:cb38da4f4b04 104 radio.tx_buf[1] = t_diff >> 24;
dudmuck 0:cb38da4f4b04 105 radio.tx_buf[2] = t_diff >> 16;
dudmuck 0:cb38da4f4b04 106 radio.tx_buf[3] = t_diff >> 8;
dudmuck 0:cb38da4f4b04 107 radio.tx_buf[4] = t_diff & 0xff;
dudmuck 0:cb38da4f4b04 108 crc = crc_ccitt(radio.tx_buf, 5);
dudmuck 0:cb38da4f4b04 109 radio.tx_buf[5] = crc >> 8;
dudmuck 0:cb38da4f4b04 110 radio.tx_buf[6] = crc & 0xff;
dudmuck 0:cb38da4f4b04 111
dudmuck 0:cb38da4f4b04 112
dudmuck 0:cb38da4f4b04 113 lora.start_tx(lora.RegPayloadLength); /* begin transmission */
dudmuck 0:cb38da4f4b04 114
dudmuck 1:3199506bc2e5 115 while (lora.service() != SERVICE_TX_DONE) { /* wait for transmission to complete */
dudmuck 1:3199506bc2e5 116 }
dudmuck 0:cb38da4f4b04 117
dudmuck 0:cb38da4f4b04 118 printf("t_diff:%u crc:%04x\r\n", t_diff, crc);
dudmuck 0:cb38da4f4b04 119 }
dudmuck 0:cb38da4f4b04 120
dudmuck 0:cb38da4f4b04 121 #define TARGET_LATENCY 2000000
dudmuck 1:3199506bc2e5 122 void send_alarm(uint8_t cmd)
dudmuck 0:cb38da4f4b04 123 {
dudmuck 0:cb38da4f4b04 124 int i;
dudmuck 0:cb38da4f4b04 125 unsigned target = t.read_us() + TARGET_LATENCY;
dudmuck 0:cb38da4f4b04 126 printf("send_alarm() %u\n", target);
dudmuck 0:cb38da4f4b04 127
dudmuck 1:3199506bc2e5 128 for (i = 0; i < 5; i++) {
dudmuck 1:3199506bc2e5 129 transmit(target, cmd);
dudmuck 0:cb38da4f4b04 130 wait(0.1);
dudmuck 0:cb38da4f4b04 131 }
dudmuck 0:cb38da4f4b04 132 }
dudmuck 1:3199506bc2e5 133
dudmuck 1:3199506bc2e5 134 void debounce(DigitalIn* pin, uint8_t cmd)
dudmuck 1:3199506bc2e5 135 {
dudmuck 1:3199506bc2e5 136 if (!pin->read()) {
dudmuck 1:3199506bc2e5 137 int i;
dudmuck 1:3199506bc2e5 138 for (i = 0; i < 5; i++) {
dudmuck 1:3199506bc2e5 139 wait(0.01);
dudmuck 1:3199506bc2e5 140 if (pin->read()) {
dudmuck 1:3199506bc2e5 141 printf("trans\r\n");
dudmuck 1:3199506bc2e5 142 break;
dudmuck 1:3199506bc2e5 143 }
dudmuck 1:3199506bc2e5 144 }
dudmuck 1:3199506bc2e5 145 if (i == 5)
dudmuck 1:3199506bc2e5 146 send_alarm(cmd);
dudmuck 1:3199506bc2e5 147
dudmuck 1:3199506bc2e5 148 while (!pin->read())
dudmuck 1:3199506bc2e5 149 ;
dudmuck 1:3199506bc2e5 150 }
dudmuck 1:3199506bc2e5 151 }
dudmuck 2:0b7620bda2c9 152
dudmuck 2:0b7620bda2c9 153 void cmd_op(int dbm)
dudmuck 2:0b7620bda2c9 154 {
dudmuck 2:0b7620bda2c9 155 int i = dbm;
dudmuck 2:0b7620bda2c9 156 RegPdsTrim1_t pds_trim;
dudmuck 2:0b7620bda2c9 157 uint8_t adr;
dudmuck 2:0b7620bda2c9 158 if (radio.type == SX1276)
dudmuck 2:0b7620bda2c9 159 adr = REG_PDSTRIM1_SX1276;
dudmuck 2:0b7620bda2c9 160 else
dudmuck 2:0b7620bda2c9 161 adr = REG_PDSTRIM1_SX1272;
dudmuck 2:0b7620bda2c9 162
dudmuck 2:0b7620bda2c9 163 pds_trim.octet = radio.read_reg(adr);
dudmuck 2:0b7620bda2c9 164
dudmuck 2:0b7620bda2c9 165 if (radio.RegPaConfig.bits.PaSelect) {
dudmuck 2:0b7620bda2c9 166 /* PABOOST used: +2dbm to +17, or +20 */
dudmuck 2:0b7620bda2c9 167 if (i == 20) {
dudmuck 2:0b7620bda2c9 168 printf("+20dBm PADAC bias\r\n");
dudmuck 2:0b7620bda2c9 169 i -= 3;
dudmuck 2:0b7620bda2c9 170 pds_trim.bits.prog_txdac = 7;
dudmuck 2:0b7620bda2c9 171 radio.write_reg(adr, pds_trim.octet);
dudmuck 2:0b7620bda2c9 172 }
dudmuck 2:0b7620bda2c9 173 if (i > 1)
dudmuck 2:0b7620bda2c9 174 radio.RegPaConfig.bits.OutputPower = i - 2;
dudmuck 2:0b7620bda2c9 175 } else {
dudmuck 2:0b7620bda2c9 176 /* RFO used: -1 to +14dbm */
dudmuck 2:0b7620bda2c9 177 if (i < 15)
dudmuck 2:0b7620bda2c9 178 radio.RegPaConfig.bits.OutputPower = i + 1;
dudmuck 2:0b7620bda2c9 179 }
dudmuck 2:0b7620bda2c9 180 radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
dudmuck 2:0b7620bda2c9 181
dudmuck 2:0b7620bda2c9 182 radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
dudmuck 2:0b7620bda2c9 183 if (radio.RegPaConfig.bits.PaSelect) {
dudmuck 2:0b7620bda2c9 184 printf("PA_BOOST ");
dudmuck 2:0b7620bda2c9 185 dbm = radio.RegPaConfig.bits.OutputPower + pds_trim.bits.prog_txdac - 2;
dudmuck 2:0b7620bda2c9 186 } else {
dudmuck 2:0b7620bda2c9 187 printf("RFO ");
dudmuck 2:0b7620bda2c9 188 dbm = radio.RegPaConfig.bits.OutputPower - 1;
dudmuck 2:0b7620bda2c9 189 }
dudmuck 2:0b7620bda2c9 190 printf("OutputPower:%ddBm\r\n", dbm);
dudmuck 2:0b7620bda2c9 191 }
dudmuck 2:0b7620bda2c9 192
dudmuck 0:cb38da4f4b04 193 int main()
dudmuck 0:cb38da4f4b04 194 {
dudmuck 0:cb38da4f4b04 195 printf("\r\nreset-tx\r\n");
dudmuck 0:cb38da4f4b04 196 t.start();
dudmuck 1:3199506bc2e5 197
dudmuck 3:d8b57eca8c45 198 pinA.mode(PullUp);
dudmuck 3:d8b57eca8c45 199 pinB.mode(PullUp);
dudmuck 3:d8b57eca8c45 200 pinC.mode(PullUp);
dudmuck 3:d8b57eca8c45 201 pinD.mode(PullUp);
dudmuck 1:3199506bc2e5 202
dudmuck 0:cb38da4f4b04 203 radio.rf_switch = rfsw_callback;
dudmuck 0:cb38da4f4b04 204
dudmuck 0:cb38da4f4b04 205 radio.set_frf_MHz(910.8);
dudmuck 0:cb38da4f4b04 206 lora.enable();
dudmuck 0:cb38da4f4b04 207 lora.setBw_KHz(500);
dudmuck 0:cb38da4f4b04 208 lora.setSf(11);
dudmuck 0:cb38da4f4b04 209
dudmuck 3:d8b57eca8c45 210 radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
dudmuck 3:d8b57eca8c45 211 #ifdef TARGET_DISCO_L072CZ_LRWAN1
dudmuck 3:d8b57eca8c45 212 radio.RegPaConfig.bits.PaSelect = 1;
dudmuck 3:d8b57eca8c45 213 #else
dudmuck 0:cb38da4f4b04 214 /* RFO or PABOOST choice:
dudmuck 0:cb38da4f4b04 215 * SX1276 shield: RFO if using 900MHz, or PA_BOOST if using 433MHz
dudmuck 0:cb38da4f4b04 216 */
dudmuck 0:cb38da4f4b04 217 rfsw.input();
dudmuck 0:cb38da4f4b04 218 if (rfsw.read()) {
dudmuck 0:cb38da4f4b04 219 printf("LAS\r\n");
dudmuck 0:cb38da4f4b04 220 /* LAS HF=PA_BOOST LF=RFO */
dudmuck 0:cb38da4f4b04 221 if (radio.HF)
dudmuck 0:cb38da4f4b04 222 radio.RegPaConfig.bits.PaSelect = 1;
dudmuck 0:cb38da4f4b04 223 else
dudmuck 0:cb38da4f4b04 224 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 2:0b7620bda2c9 225 cmd_op(20);
dudmuck 0:cb38da4f4b04 226 } else {
dudmuck 0:cb38da4f4b04 227 /* MAS shield board, only RFO TX */
dudmuck 0:cb38da4f4b04 228 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 0:cb38da4f4b04 229 printf("MAS\r\n");
dudmuck 2:0b7620bda2c9 230 cmd_op(14);
dudmuck 0:cb38da4f4b04 231 }
dudmuck 0:cb38da4f4b04 232 rfsw.output();
dudmuck 3:d8b57eca8c45 233 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */
dudmuck 0:cb38da4f4b04 234 radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
dudmuck 0:cb38da4f4b04 235
dudmuck 0:cb38da4f4b04 236 /* constant payload length */
dudmuck 0:cb38da4f4b04 237 lora.RegPayloadLength = 7;
dudmuck 0:cb38da4f4b04 238 radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
dudmuck 0:cb38da4f4b04 239
dudmuck 0:cb38da4f4b04 240 for (;;) {
dudmuck 3:d8b57eca8c45 241 debounce(&pinA, CMD_PINA);
dudmuck 3:d8b57eca8c45 242 debounce(&pinB, CMD_PINB);
dudmuck 3:d8b57eca8c45 243 debounce(&pinC, CMD_PINC);
dudmuck 3:d8b57eca8c45 244 debounce(&pinD, CMD_PIND);
dudmuck 0:cb38da4f4b04 245 } // ..for (;;)
dudmuck 0:cb38da4f4b04 246 }