raises pin at time instructed by received LoRa packet.

Dependencies:   sx126x 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.

Transmitter side is at Alarm Slave project page.
Output is observed on nucleo morpho connector pins pin[A-D]: see code for actual pins used.

Committer:
dudmuck
Date:
Fri Jan 26 01:19:39 2018 +0000
Revision:
2:bf201940a9db
Parent:
1:6a3a48d657a9
Child:
3:f81d64ff0164
support DISCO-L072CZ-LRWAN

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:b6ec8db2edbf 1 #include "sx127x_lora.h"
dudmuck 0:b6ec8db2edbf 2
dudmuck 0:b6ec8db2edbf 3 DigitalOut myled(LED1);
dudmuck 2:bf201940a9db 4 #ifdef TARGET_DISCO_L072CZ_LRWAN1
dudmuck 2:bf201940a9db 5
dudmuck 2:bf201940a9db 6 SPI spi(PA_7, PA_6, PB_3); // mosi, miso, sclk
dudmuck 2:bf201940a9db 7 // dio0, dio1, nss, spi, rst
dudmuck 2:bf201940a9db 8 SX127x radio(PB_4, PB_1, PA_15, spi, PC_0);
dudmuck 2:bf201940a9db 9
dudmuck 2:bf201940a9db 10 #define CRF1 PA_1
dudmuck 2:bf201940a9db 11 #define CRF2 PC_2
dudmuck 2:bf201940a9db 12 #define CRF3 PC_1
dudmuck 2:bf201940a9db 13 DigitalOut Vctl1(CRF1);
dudmuck 2:bf201940a9db 14 DigitalOut Vctl2(CRF2);
dudmuck 2:bf201940a9db 15 DigitalOut Vctl3(CRF3);
dudmuck 2:bf201940a9db 16
dudmuck 2:bf201940a9db 17 void rfsw_callback()
dudmuck 2:bf201940a9db 18 {
dudmuck 2:bf201940a9db 19 if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
dudmuck 2:bf201940a9db 20 Vctl1 = 0;
dudmuck 2:bf201940a9db 21 if (radio.RegPaConfig.bits.PaSelect) {
dudmuck 2:bf201940a9db 22 Vctl2 = 0;
dudmuck 2:bf201940a9db 23 Vctl3 = 1;
dudmuck 2:bf201940a9db 24 } else {
dudmuck 2:bf201940a9db 25 Vctl2 = 1;
dudmuck 2:bf201940a9db 26 Vctl3 = 0;
dudmuck 2:bf201940a9db 27 }
dudmuck 2:bf201940a9db 28 } else {
dudmuck 2:bf201940a9db 29 if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE)
dudmuck 2:bf201940a9db 30 Vctl1 = 1;
dudmuck 2:bf201940a9db 31 else
dudmuck 2:bf201940a9db 32 Vctl1 = 0;
dudmuck 2:bf201940a9db 33
dudmuck 2:bf201940a9db 34 Vctl2 = 0;
dudmuck 2:bf201940a9db 35 Vctl3 = 0;
dudmuck 2:bf201940a9db 36 }
dudmuck 2:bf201940a9db 37 }
dudmuck 2:bf201940a9db 38
dudmuck 2:bf201940a9db 39 DigitalOut pinA(PB_12);
dudmuck 2:bf201940a9db 40 DigitalOut pinB(PB_13);
dudmuck 2:bf201940a9db 41 DigitalOut pinC(PB_14);
dudmuck 2:bf201940a9db 42 DigitalOut pinD(PB_15);
dudmuck 2:bf201940a9db 43 #else
dudmuck 2:bf201940a9db 44 SPI spi(D11, D12, D13); // mosi, miso, sclk
dudmuck 2:bf201940a9db 45 // dio0, dio1, nss, spi, rst
dudmuck 2:bf201940a9db 46 SX127x radio( D2, D3, D10, spi, A0); // sx1276 arduino shield
dudmuck 2:bf201940a9db 47
dudmuck 2:bf201940a9db 48 DigitalInOut rfsw(A4); // for SX1276 arduino shield
dudmuck 2:bf201940a9db 49
dudmuck 2:bf201940a9db 50 void rfsw_callback()
dudmuck 2:bf201940a9db 51 {
dudmuck 2:bf201940a9db 52 if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER)
dudmuck 2:bf201940a9db 53 rfsw = 1;
dudmuck 2:bf201940a9db 54 else
dudmuck 2:bf201940a9db 55 rfsw = 0;
dudmuck 2:bf201940a9db 56 }
dudmuck 2:bf201940a9db 57
dudmuck 2:bf201940a9db 58 DigitalOut pinA(PC_3);
dudmuck 2:bf201940a9db 59 DigitalOut pinB(PC_2);
dudmuck 2:bf201940a9db 60 DigitalOut pinC(PC_6);
dudmuck 2:bf201940a9db 61 DigitalOut pinD(PC_8);
dudmuck 2:bf201940a9db 62 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */
dudmuck 2:bf201940a9db 63
dudmuck 2:bf201940a9db 64 /**********************************************************************/
dudmuck 0:b6ec8db2edbf 65 SX127x_lora lora(radio);
dudmuck 2:bf201940a9db 66
dudmuck 1:6a3a48d657a9 67 DigitalOut* pin;
dudmuck 0:b6ec8db2edbf 68 Timeout to;
dudmuck 0:b6ec8db2edbf 69
dudmuck 1:6a3a48d657a9 70 #define PIN_ASSERT_us 500000
dudmuck 1:6a3a48d657a9 71
dudmuck 2:bf201940a9db 72 #define CMD_PINA 0x02
dudmuck 2:bf201940a9db 73 #define CMD_PINB 0x03
dudmuck 2:bf201940a9db 74 #define CMD_PINC 0x06
dudmuck 2:bf201940a9db 75 #define CMD_PIND 0x08
dudmuck 0:b6ec8db2edbf 76
dudmuck 0:b6ec8db2edbf 77 void alarm_pin_clr()
dudmuck 0:b6ec8db2edbf 78 {
dudmuck 1:6a3a48d657a9 79 pin->write(0);
dudmuck 0:b6ec8db2edbf 80 }
dudmuck 0:b6ec8db2edbf 81
dudmuck 0:b6ec8db2edbf 82 void alarm_pin_set()
dudmuck 0:b6ec8db2edbf 83 {
dudmuck 1:6a3a48d657a9 84 pin->write(1);
dudmuck 0:b6ec8db2edbf 85 to.attach_us(&alarm_pin_clr, PIN_ASSERT_us);
dudmuck 0:b6ec8db2edbf 86 }
dudmuck 0:b6ec8db2edbf 87
dudmuck 0:b6ec8db2edbf 88 static uint16_t crc_ccitt( uint8_t *buffer, uint16_t length )
dudmuck 0:b6ec8db2edbf 89 {
dudmuck 0:b6ec8db2edbf 90 // The CRC calculation follows CCITT
dudmuck 0:b6ec8db2edbf 91 const uint16_t polynom = 0x1021;
dudmuck 0:b6ec8db2edbf 92 // CRC initial value
dudmuck 0:b6ec8db2edbf 93 uint16_t crc = 0x0000;
dudmuck 0:b6ec8db2edbf 94
dudmuck 0:b6ec8db2edbf 95 if( buffer == NULL )
dudmuck 0:b6ec8db2edbf 96 {
dudmuck 0:b6ec8db2edbf 97 return 0;
dudmuck 0:b6ec8db2edbf 98 }
dudmuck 0:b6ec8db2edbf 99
dudmuck 0:b6ec8db2edbf 100 for( uint16_t i = 0; i < length; ++i )
dudmuck 0:b6ec8db2edbf 101 {
dudmuck 0:b6ec8db2edbf 102 crc ^= ( uint16_t ) buffer[i] << 8;
dudmuck 0:b6ec8db2edbf 103 for( uint16_t j = 0; j < 8; ++j )
dudmuck 0:b6ec8db2edbf 104 {
dudmuck 0:b6ec8db2edbf 105 crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 );
dudmuck 0:b6ec8db2edbf 106 }
dudmuck 0:b6ec8db2edbf 107 }
dudmuck 0:b6ec8db2edbf 108
dudmuck 0:b6ec8db2edbf 109 return crc;
dudmuck 0:b6ec8db2edbf 110 }
dudmuck 0:b6ec8db2edbf 111
dudmuck 0:b6ec8db2edbf 112 void get_alarm()
dudmuck 0:b6ec8db2edbf 113 {
dudmuck 0:b6ec8db2edbf 114 uint16_t rx_crc, crc = crc_ccitt(radio.rx_buf, 5);
dudmuck 0:b6ec8db2edbf 115 rx_crc = radio.rx_buf[5];
dudmuck 0:b6ec8db2edbf 116 rx_crc <<= 8;
dudmuck 0:b6ec8db2edbf 117 rx_crc += radio.rx_buf[6];
dudmuck 0:b6ec8db2edbf 118 //printf("%u) crc rx:%04x, calc:%04x\r\n", lora.RegRxNbBytes, rx_crc, crc);
dudmuck 0:b6ec8db2edbf 119 if (crc == rx_crc) {
dudmuck 1:6a3a48d657a9 120 uint8_t c = radio.rx_buf[0];
dudmuck 1:6a3a48d657a9 121 //if (radio.rx_buf[0] == CMD_ALARM)
dudmuck 2:bf201940a9db 122 if (c == CMD_PINA || c == CMD_PINB || c == CMD_PINC || c == CMD_PIND) {
dudmuck 0:b6ec8db2edbf 123 unsigned delay;
dudmuck 0:b6ec8db2edbf 124 delay = radio.rx_buf[1];
dudmuck 0:b6ec8db2edbf 125 delay <<= 8;
dudmuck 0:b6ec8db2edbf 126 delay += radio.rx_buf[2];
dudmuck 0:b6ec8db2edbf 127 delay <<= 8;
dudmuck 0:b6ec8db2edbf 128 delay += radio.rx_buf[3];
dudmuck 0:b6ec8db2edbf 129 delay <<= 8;
dudmuck 0:b6ec8db2edbf 130 delay += radio.rx_buf[4];
dudmuck 1:6a3a48d657a9 131 switch (c) {
dudmuck 2:bf201940a9db 132 case CMD_PINA: pin = &pinA; break;
dudmuck 2:bf201940a9db 133 case CMD_PINB: pin = &pinB; break;
dudmuck 2:bf201940a9db 134 case CMD_PINC: pin = &pinC; break;
dudmuck 2:bf201940a9db 135 case CMD_PIND: pin = &pinD; break;
dudmuck 1:6a3a48d657a9 136 }
dudmuck 0:b6ec8db2edbf 137 to.attach_us(&alarm_pin_set, delay);
dudmuck 0:b6ec8db2edbf 138 printf("delay:%u\r\n", delay);
dudmuck 0:b6ec8db2edbf 139 } else
dudmuck 0:b6ec8db2edbf 140 printf("cmd? %02x\r\n", radio.rx_buf[0]);
dudmuck 0:b6ec8db2edbf 141 } else
dudmuck 0:b6ec8db2edbf 142 printf("crc fail %04x, %04x\r\n", rx_crc, crc);
dudmuck 0:b6ec8db2edbf 143 }
dudmuck 0:b6ec8db2edbf 144
dudmuck 0:b6ec8db2edbf 145 int main()
dudmuck 0:b6ec8db2edbf 146 {
dudmuck 0:b6ec8db2edbf 147 printf("\r\nreset-rx\r\n");
dudmuck 0:b6ec8db2edbf 148 radio.rf_switch = rfsw_callback;
dudmuck 0:b6ec8db2edbf 149
dudmuck 0:b6ec8db2edbf 150 radio.set_frf_MHz(910.8);
dudmuck 0:b6ec8db2edbf 151 lora.enable();
dudmuck 0:b6ec8db2edbf 152 lora.setBw_KHz(500);
dudmuck 0:b6ec8db2edbf 153 lora.setSf(11);
dudmuck 0:b6ec8db2edbf 154
dudmuck 2:bf201940a9db 155 radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
dudmuck 2:bf201940a9db 156 #ifdef TARGET_DISCO_L072CZ_LRWAN1
dudmuck 2:bf201940a9db 157 radio.RegPaConfig.bits.PaSelect = 1;
dudmuck 2:bf201940a9db 158 #else
dudmuck 0:b6ec8db2edbf 159 /* RFO or PABOOST choice:
dudmuck 0:b6ec8db2edbf 160 * SX1276 shield: RFO if using 900MHz, or PA_BOOST if using 433MHz
dudmuck 0:b6ec8db2edbf 161 */
dudmuck 0:b6ec8db2edbf 162 rfsw.input();
dudmuck 0:b6ec8db2edbf 163 if (rfsw.read()) {
dudmuck 0:b6ec8db2edbf 164 printf("LAS\r\n");
dudmuck 0:b6ec8db2edbf 165 /* LAS HF=PA_BOOST LF=RFO */
dudmuck 0:b6ec8db2edbf 166 if (radio.HF)
dudmuck 0:b6ec8db2edbf 167 radio.RegPaConfig.bits.PaSelect = 1;
dudmuck 0:b6ec8db2edbf 168 else
dudmuck 0:b6ec8db2edbf 169 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 0:b6ec8db2edbf 170 } else {
dudmuck 0:b6ec8db2edbf 171 /* MAS shield board, only RFO TX */
dudmuck 0:b6ec8db2edbf 172 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 0:b6ec8db2edbf 173 printf("MAS\r\n");
dudmuck 0:b6ec8db2edbf 174 }
dudmuck 0:b6ec8db2edbf 175 rfsw.output();
dudmuck 2:bf201940a9db 176 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */
dudmuck 0:b6ec8db2edbf 177 radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
dudmuck 0:b6ec8db2edbf 178
dudmuck 0:b6ec8db2edbf 179 lora.start_rx(RF_OPMODE_RECEIVER);
dudmuck 0:b6ec8db2edbf 180
dudmuck 0:b6ec8db2edbf 181 for (;;) {
dudmuck 0:b6ec8db2edbf 182 if (lora.service() == SERVICE_READ_FIFO) {
dudmuck 0:b6ec8db2edbf 183 /*int i;
dudmuck 0:b6ec8db2edbf 184 for (i = 0; i < lora.RegRxNbBytes; i++) {
dudmuck 0:b6ec8db2edbf 185 printf("%02x ", radio.rx_buf[i]);
dudmuck 0:b6ec8db2edbf 186 }
dudmuck 0:b6ec8db2edbf 187 printf("\r\n");*/
dudmuck 0:b6ec8db2edbf 188 get_alarm();
dudmuck 0:b6ec8db2edbf 189 }
dudmuck 0:b6ec8db2edbf 190 }
dudmuck 0:b6ec8db2edbf 191 }