8 コミット

作成者 SHA1 メッセージ 日付
  Bernd Gottschlag 9cc2488996 Put send functions into a separate file 5年前
  Bernd Gottschlag 4f83ec8bef Add handling of the salt 5年前
  Bernd Gottschlag b31efd8359 Fix decryption function 5年前
  Bernd Gottschlag 08546c2e36 Re-enable dynamic packet length 5年前
  Bernd Gottschlag fe5cd5fc86 Add delay after setting the pull ups for pin programming 5年前
  Bernd Gottschlag 9694fa3913 Fix the rx0 address 5年前
  Bernd Gottschlag f78e2f65c6 Disable the dynamic packet length 5年前
  Bernd Gottschlag 608a6ee253 Fix generation of the salt 5年前

+ 1
- 1
weather-sensor/firmware/encryption.c ファイルの表示

@@ -65,7 +65,7 @@ void Decrypt(uint32_t * data, uint8_t dataLength, uint64_t salt, const uint32_t
65 65
 
66 66
 		/* Setup for next block */
67 67
 		currentCipherBlock = previousCipherBlock;
68
-		if (previousCipherBlock != (uint8_t*) data + LENGTH_OF_BLOCK)
68
+		if (previousCipherBlock != (uint8_t*) data)
69 69
 		{
70 70
 			previousCipherBlock -= LENGTH_OF_BLOCK;
71 71
 		}

+ 37
- 49
weather-sensor/firmware/main.c ファイルの表示

@@ -15,13 +15,11 @@
15 15
 #include "bme280_interface.h"
16 16
 #include "bme280_defs.h"
17 17
 #include "pin_programming.h"
18
-#include "crc.h"
19
-#include "encryption.h"
18
+#include "radio.h"
20 19
 
21 20
 
22 21
 
23 22
 uint8_t ownId;
24
-const uint8_t encryptionKey[16] = {0x9e, 0x37, 0x79, 0xb9, 0x9b, 0x97, 0x73, 0xe9, 0xb9, 0x79, 0x37, 0x9e, 0x6b, 0x69, 0x51, 0x56}; /* TODO: use exernal file with the keys */
25 23
 uint64_t salt;
26 24
 
27 25
 char bool_case = 0;
@@ -36,25 +34,15 @@ volatile uint8_t interruptCounter;
36 34
 volatile uint8_t executionFlag;
37 35
 
38 36
 
39
-
40
-static PACKET reportPacket;
37
+static uint8_t messageBuffer[PACKET_LENGTH];
38
+static PACKET * packet = (PACKET*) messageBuffer;
41 39
 
42 40
 
43 41
 void Enter_Power_Save_Mode(void);
44 42
 void Exit_Power_Save_Mode(void);
45 43
 
46 44
 
47
-/* TODO Notes for power saving:
48
- * - Power-save-mode needed -> SM2...0 bits written to 011
49
- * - Entering by issuing the SLEEP instruction -> What call in C?
50
- *   - Before executing the SLEEP instruction, write bit SE of the SMCR to 1
51
- * - Let Timer/Counter2 run with the necessary period and enable an interrupt.
52
- *   -> The Global Interrupt Enable bit in SREG has to be set.
53
- * - asynchronous/synchronous clock source?
54
- * - When waking up
55
- *   - Set PRR bits for needed peripherals
56
- * - 
57
- */
45
+
58 46
 void Set_Up_Power_Save_Mode(void);
59 47
 void Enter_Power_Save_Mode(void);
60 48
 
@@ -72,7 +60,7 @@ ISR(PCINT2_vect)
72 60
 int main (void)
73 61
 {
74 62
 	struct bme280_data sensorData;
75
-	uint16_t crc;
63
+	bool saltReceived = false;
76 64
 
77 65
 	/* Enable the debug LED */
78 66
 	LED_DDR |= (1 << LED_PIN);
@@ -96,8 +84,34 @@ int main (void)
96 84
 	Set_Up_Power_Save_Mode();
97 85
 
98 86
 	/* Initialize the salt */
99
-	salt = 0xFFFFFFFFFFFFFFFFull;
100
-	salt &= ~ownId;
87
+	salt = 0x0ull;
88
+	salt |= ownId;
89
+
90
+
91
+	/* Request a salt from the base station */
92
+	LED_PORT |= (1 << LED_PIN);
93
+	do
94
+	{
95
+		if (Send_Get_Salt_Message(packet, &salt) == true)
96
+		{
97
+			memset(messageBuffer, 0x0F, 32);
98
+			if (NRF24L01_Receive_Message(messageBuffer, 100 /*ms*/) == true)
99
+			{
100
+				_delay_ms(10);
101
+				saltReceived = Read_Salt_Message(packet, &salt);
102
+			}
103
+		}
104
+		else
105
+		{
106
+			/* TODO: enter power save mode instead to make the battery life longer */
107
+			_delay_ms(100);
108
+		}
109
+	} while (saltReceived == false);
110
+	LED_PORT &= ~(1 << LED_PIN);
111
+
112
+	salt &= 0xFFFFFFFFFFFFFF00ull;
113
+	salt |= ownId;
114
+
101 115
 
102 116
 	/* Delay the change of the operating frequency by the function Enter_Power_Save_Mode for the
103 117
 	 * first function pass. If it is changed before the ISP can flash the MCU the clocks of the ISP
@@ -119,37 +133,10 @@ int main (void)
119 133
 			/* Get measurement and send it */
120 134
 			BME280_Get_Measurement(&sensorData);
121 135
 
136
+			/* Send the report */
137
+			Send_Report_Message(packet, &salt, &sensorData);
122 138
 
123
-			memset((uint8_t*)&reportPacket, 0, sizeof(reportPacket)); //Reinitialize the buffer with zeros
124
-
125
-			salt &= ~(1ull<<55);
126
-			reportPacket.salt = salt;
127
-			reportPacket.payload.values.packetIdentifier.elementCount = 3;
128
-			reportPacket.payload.values.packetIdentifier.packetType = PACKET_TYPE_REPORT;
129
-
130
-			/* Fill in the payload */
131
-			reportPacket.payload.values.valueTypeTemperature = VALUE_TYPE_TEMPERATURE;
132
-			reportPacket.payload.values.temperature = sensorData.temperature/10;
133
-			reportPacket.payload.values.valueTypePressure = VALUE_TYPE_PRESSURE;
134
-			reportPacket.payload.values.pressure = sensorData.pressure;
135
-			reportPacket.payload.values.valueTypeHumidity = VALUE_TYPE_HUMIDITY;
136
-			reportPacket.payload.values.humidity = sensorData.humidity * 100/1024;
137
-
138
-			/* Calculate the CRC */
139
-			crc = Calculate_Crc(reportPacket.payload.buffer, PACKET_BUFFER_LENGTH);
140
-			reportPacket.crc = crc;
141
-
142
-			/* Encrypt the packet */
143
-			/* TODO: 
144
-			 * - increment the salt for every packet
145
-			 * - Receive salt from the base station
146
-			 */
147
-			Encrypt((uint32_t*) &reportPacket.payload.buffer,
148
-			        PACKET_BUFFER_LENGTH + sizeof(crc),
149
-			        salt, (uint32_t*) encryptionKey);
150
-
151
-			NRF24L01_Send_Message((uint8_t*)&reportPacket, sizeof(reportPacket));
152
-
139
+			LED_PORT |= (1 << LED_PIN);
153 140
 			_delay_ms(100); /* TODO: only for debugging, remove this later! */
154 141
 			LED_PORT &= ~(1 << LED_PIN);
155 142
 
@@ -225,3 +212,4 @@ void Exit_Power_Save_Mode(void)
225 212
 	PRR &= ~(1<<PRSPI); // Enable SPI
226 213
 	Initialize_SPI(); // reinitalize SPI
227 214
 }
215
+

+ 3
- 3
weather-sensor/firmware/makefile ファイルの表示

@@ -1,5 +1,5 @@
1 1
 CFLAGS = -DF_CPU=1000000UL -D BME280_32BIT_ENABLE -I BME280_driver -mmcu=atmega88p -Os -flto -Wall -Wextra -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
2
-DEPS = spi.h nrf24l01.h nrf24l01_definitions.h bme280_interface.h BME280_driver/bme280.h led.h pin_programming.h crc.h encryption.h
2
+DEPS = spi.h nrf24l01.h nrf24l01_definitions.h bme280_interface.h BME280_driver/bme280.h led.h pin_programming.h crc.h encryption.h radio.h
3 3
 
4 4
 all: main.hex
5 5
 
@@ -9,7 +9,7 @@ clean:
9 9
 	rm -f obj/*.o
10 10
 
11 11
 flash: main.hex
12
-	sudo avrdude -c buspirate -b 115200 -P /dev/ttyUSB1 -p m88p -v -U flash:w:main.hex
12
+	sudo avrdude -c buspirate -b 115200 -P /dev/ttyUSB0 -p m88p -v -U flash:w:main.hex
13 13
 
14 14
 obj/%.o: %.c $(DEPS)
15 15
 	avr-gcc -c $< -o $@ $(CFLAGS)
@@ -17,7 +17,7 @@ obj/%.o: %.c $(DEPS)
17 17
 obj/%.o: BME280_driver/%.c $(DEPS)
18 18
 	avr-gcc -c $< -o $@ $(CFLAGS)
19 19
 
20
-main: obj/main.o obj/spi.o obj/nrf24l01.o obj/bme280_interface.o obj/bme280.o obj/pin_programming.o obj/crc.o obj/encryption.o
20
+main: obj/main.o obj/spi.o obj/nrf24l01.o obj/bme280_interface.o obj/bme280.o obj/pin_programming.o obj/crc.o obj/encryption.o obj/radio.o
21 21
 	avr-gcc $^ -o $@ $(CFLAGS)
22 22
 
23 23
 main.hex: main

+ 163
- 75
weather-sensor/firmware/nrf24l01.c ファイルの表示

@@ -17,9 +17,13 @@
17 17
 extern volatile bool nrfInterruptRaised;
18 18
 
19 19
 void Print_Register_Contents(uint8_t address);
20
+
21
+
20 22
 void Send_TX_Flush_Command(void);
23
+void Send_RX_Flush_Command(void);
21 24
 
22
-static void Write_Two_Bytes(uint8_t byte1, uint8_t byte2);
25
+static uint8_t Write_One_Byte(uint8_t byte1);
26
+static uint8_t Write_Two_Bytes(uint8_t byte1, uint8_t byte2);
23 27
 static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length);
24 28
 
25 29
 /* Startup and initial configuration of the NRF24L01 */
@@ -64,33 +68,15 @@ void Set_NRF24L01_Pins(void)
64 68
 
65 69
 void Configure_Transmission(uint8_t moduleId)
66 70
 {
71
+	SETUP_RETR_REGISTER setupRetrRegisterContents = {.byte = 0x0};
72
+	EN_RXADDR_REGISTER enableRxAddressesRegisterContents = {.byte = 0x0};
73
+	RX_PW_Pn_REGISTER rxPwPnRegisterContents = {.byte = 0x0};
74
+	EN_AA_REGISTER enAaRegister = {.byte = 0x0};
67 75
 	FEATURE_REGISTER featureRegisterContents = {.byte = 0x0};
68 76
 	DYNPD_REGISTER dyndpRegisterContents = {.byte = 0x0};
69
-	SETUP_RETR_REGISTER setupRetrRegisterContents = {.byte = 0x0};
70 77
 
71 78
 	uint8_t txAddress[5] = {0xB3, 0xB3, 0xB3, 0xB3, 0x00};
72
-	uint8_t rx0Address[5] = {0xB3, 0xB3, 0xB3, 0xB3, 0x20};
73
-	/* 
74
-	 * - Length of CRC (CRCO in CONFIG)
75
-	 * - Enable auto acknowledgment (EN_AA)
76
-	 *   -> Register already set correctly after reset
77
-	 * - Enable data pipes (EN_RXADDR)?
78
-	 *   -> Two pipes are already enabled on reset
79
-	 * - Set up address width (SETUP_AW)
80
-	 *   -> 3 bytes
81
-	 * - Automatic Retransmission (SETUP_RETR)
82
-	 *   -> ARD = 0b0000
83
-	 *   -> 3 retransmits -> ARC = 0b0011
84
-	 *   -> Register already set correctly after reset
85
-	 * - RF Channel (RF_CH)
86
-	 *   -> RF_CH = 0b1010000
87
-	 * - RF Setup (RF_SETUP)
88
-	 *   -> first use reset values, can be fine tuned later
89
-	 * - Enable dynamic payload length (DYNPD) -> command activate + 0x73, then set bits in FEATURE?
90
-	 */
91
-
92
-	/* Set the address width to 3 bytes */
93
-	//Write_NRF_Register(0x03, 0x1);
79
+	uint8_t rx1Address[5] = {0xB3, 0xB3, 0xB3, 0xB3, 0x00};
94 80
 
95 81
 	/* Set the frequency to 1450 MHz */
96 82
 	Write_NRF_Register(RF_CH_ADDRESS, 0x32);
@@ -100,12 +86,10 @@ void Configure_Transmission(uint8_t moduleId)
100 86
 	featureRegisterContents.bits.EN_DPL = 1; // enable dynamic payload length
101 87
 	Write_NRF_Register(FEATURE_ADDRESS, featureRegisterContents.byte);
102 88
 
103
-	/* */
104
-	setupRetrRegisterContents.bits.ARC = 0x3;
105
-	setupRetrRegisterContents.bits.ARD = 0xF;
106
-	Write_NRF_Register(SETUP_RETR_ADDRESS, setupRetrRegisterContents.byte);
107
-
108
-	/* set dynamic payload length for all data pipes */ // TODO: only pipe 0 is currently in use -> don't set the other values
89
+	/* set dynamic payload length for all data pipes
90
+	 * When the dynamic payload length is not set the module cannot receive packets from some
91
+	 * stations. This is probably due to counterfeit NRF24L01+ chips.
92
+	 */
109 93
 	dyndpRegisterContents.bits.DPL_P0 = 1;
110 94
 	dyndpRegisterContents.bits.DPL_P1 = 1;
111 95
 	dyndpRegisterContents.bits.DPL_P2 = 1;
@@ -114,23 +98,62 @@ void Configure_Transmission(uint8_t moduleId)
114 98
 	dyndpRegisterContents.bits.DPL_P5 = 1;
115 99
 	Write_NRF_Register(DYNPD_ADDRESS, dyndpRegisterContents.byte);
116 100
 
101
+	/* Set up the auto retries */
102
+	setupRetrRegisterContents.bits.ARC = 0x3;
103
+	setupRetrRegisterContents.bits.ARD = 0xF;
104
+	Write_NRF_Register(SETUP_RETR_ADDRESS, setupRetrRegisterContents.byte);
105
+
117 106
 	/* Set the TX address */
118 107
 	Set_TX_Address(txAddress, MAX_ADDRESS_LENGTH);
119 108
 
120
-	rx0Address[4] = moduleId; // The last byte of the address corresponds to the Id set by the pin programming
121
-	Set_RX_P0_Address(rx0Address, MAX_ADDRESS_LENGTH);
109
+	/* Set the address of the RX pipe 0 to the one of the base station to receive acks */
110
+	Set_RX_P0_Address(txAddress, MAX_ADDRESS_LENGTH);
111
+
112
+	/* Set the address of the RX pipe 1 to the own address to receive messages */
113
+	rx1Address[4] = moduleId; // The last byte of the address corresponds to the Id set by the pin programming
114
+	Set_RX_P1_Address(rx1Address, MAX_ADDRESS_LENGTH);
115
+
116
+	/* Enable the rx addresses for pipe 0 and pipe 1*/
117
+	enableRxAddressesRegisterContents.bits.ERX_P0 = 1;
118
+	enableRxAddressesRegisterContents.bits.ERX_P1 = 1;
119
+	Write_NRF_Register(EN_RXADDR_ADDRESS, enableRxAddressesRegisterContents.byte);
120
+
121
+	/* Set the payload witth for pipe 1 */
122
+	rxPwPnRegisterContents.bits.RX_PW_Pn = 32;
123
+	Write_NRF_Register(RX_PW_P1_ADDRESS, rxPwPnRegisterContents.byte);
124
+
125
+	rxPwPnRegisterContents.bits.RX_PW_Pn = 0;
126
+	Write_NRF_Register(RX_PW_P0_ADDRESS, rxPwPnRegisterContents.byte); // auto-ack pipe
127
+	Write_NRF_Register(RX_PW_P2_ADDRESS, rxPwPnRegisterContents.byte); // not used
128
+	Write_NRF_Register(RX_PW_P3_ADDRESS, rxPwPnRegisterContents.byte); // not used
129
+	Write_NRF_Register(RX_PW_P4_ADDRESS, rxPwPnRegisterContents.byte); // not used
130
+	Write_NRF_Register(RX_PW_P5_ADDRESS, rxPwPnRegisterContents.byte); // not used
131
+
132
+	/* Enable auto acknowledge for pipe 1 */
133
+	enAaRegister.bits.ENAA_P0 = 1;
134
+	enAaRegister.bits.ENAA_P1 = 1;
135
+	enAaRegister.bits.ENAA_P2 = 1;
136
+	enAaRegister.bits.ENAA_P3 = 1;
137
+	enAaRegister.bits.ENAA_P4 = 1;
138
+	enAaRegister.bits.ENAA_P5 = 1;
139
+	Write_NRF_Register(EN_AA_ADDRESS, enAaRegister.byte);
140
+
141
+	/* Flush FIFOs */
142
+	Send_TX_Flush_Command();
143
+	Send_RX_Flush_Command();
122 144
 
123 145
 
124 146
 	PCMSK2 |= (1<<PCINT21); // Set the external interrupt for PD5
125 147
 }
126 148
 
127
-void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
149
+bool NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
128 150
 {
151
+	bool success = false;
129 152
 	STATUS_REGISTER statusRegisterContents = {.byte = 0x0};
130 153
 	
131 154
 	if ((length > 32) || (length == 0))
132 155
 	{
133
-		return;
156
+		return success;
134 157
 	}
135 158
 
136 159
 	PCICR |= (1<<PCIE2); // Enable the interrupt for the IRQ signal
@@ -147,7 +170,6 @@ void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
147 170
 	 * induced by the SPI:
148 171
 	 * https://forum.mysensors.org/topic/10452/nrf24l01-communication-failure-root-cause-and-solution
149 172
 	 */
150
-	LED_PORT |= (1 << LED_PIN);
151 173
 
152 174
 	statusRegisterContents.byte = Read_NRF_Status_Register();
153 175
 
@@ -156,6 +178,10 @@ void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
156 178
 	{
157 179
 		Send_TX_Flush_Command(); /* Remove the packet from the TX FIFO as it is not done automatically */
158 180
 	}
181
+	else
182
+	{
183
+		success = true;
184
+	}
159 185
 	
160 186
 
161 187
 	/* Reset the interrupts */
@@ -168,57 +194,88 @@ void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
168 194
 	nrfInterruptRaised = false;
169 195
 
170 196
 
171
-	return;
197
+	return success;
172 198
 }
173 199
 
174
-uint8_t Read_NRF_Status_Register(void)
200
+bool NRF24L01_Receive_Message(uint8_t *buffer, uint8_t duration)
175 201
 {
176
-	uint8_t registerContents;
202
+	uint8_t messageReceived = false;
203
+	CONFIG_REGISTER configRegisterContents = {.byte = 0x0};
204
+	STATUS_REGISTER statusRegisterContents = {.byte = 0x0};
205
+	FIFO_STATUS_REGISTER fifoStatusRegisterContents = {.byte = 0x0};
177 206
 
178
-	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
179
-	registerContents = SPI_Transfer_Byte(0x00);
180
-	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
181
-	return registerContents;
182
-}
207
+	PCICR |= (1<<PCIE2); // Enable the interrupt for the IRQ signal
183 208
 
209
+	// Enable the receive mode
210
+	configRegisterContents.byte = Read_NRF_Register(CONFIG_ADDRESS);
211
+	configRegisterContents.bits.PRIM_RX = 0x1;
212
+	Write_NRF_Register(CONFIG_ADDRESS, configRegisterContents.byte);
184 213
 
185
-/* TODO: rewrite the read register function if it is needed (remove the read operations for the 5-byte registers)*/
186
-#if 0
187
-uint8_t Read_NRF_Register(uint8_t address, uint8_t * registerContents)
188
-{
189
-	/* TODO: simplify this function, as the registers with more than one byte are accessed with other functions */
190
-	uint8_t numberOfBytes = 0;
191 214
 
192
-	if ((address == 0x0A) ||
193
-	    (address == 0x0B) ||
194
-	    (address == 0x10))
215
+	NRF_CE_PORT |= (1 << NRF_CE_PIN);
216
+
217
+	_delay_ms(10);
218
+	while ((nrfInterruptRaised == false) && (duration > 0))
195 219
 	{
196
-		numberOfBytes = 5;
197
-	}
198
-	else
220
+		_delay_ms(1);
221
+		duration --;
222
+	};
223
+
224
+	if (nrfInterruptRaised == true) // check if a message was received
199 225
 	{
200
-		numberOfBytes = 1;
226
+		/* A message was received */
227
+
228
+		statusRegisterContents.byte = Read_NRF_Status_Register();
229
+
230
+		fifoStatusRegisterContents.byte = Read_NRF_Register(FIFO_STATUS_ADDRESS);
231
+		if (fifoStatusRegisterContents.bits.RX_EMPTY != 1)
232
+		{
233
+			messageReceived = true;
234
+		}
235
+
236
+		nrfInterruptRaised = false;
201 237
 	}
202 238
 
203
-	/* First write the address */
204
-	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
239
+	// Set the NRF to standby
240
+	NRF_CE_PORT &= ~(1 << NRF_CE_PIN);
205 241
 
242
+	configRegisterContents.byte = Read_NRF_Register(CONFIG_ADDRESS);
243
+	configRegisterContents.bits.PRIM_RX = 0x0;
244
+	Write_NRF_Register(CONFIG_ADDRESS, configRegisterContents.byte);
206 245
 
207
-	SPI_Transfer_Byte(address);
246
+	PCICR &= ~(1<<PCIE2); // Disable the interrupt for the IRQ signal
208 247
 
209
-	/* Read the register bytes */
210
-	for (uint8_t i = 0; i < numberOfBytes; i++)
248
+	if (messageReceived == true)
211 249
 	{
212
-		/* Write dummy data to shift in the register content */
213
-		registerContents[i] = SPI_Transfer_Byte(0x0);
250
+		Read_Message_From_RX_FIFO(PACKET_LENGTH, buffer); /* TODO: only possible after CE = 0? */
214 251
 	}
215 252
 
216
-	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
253
+	/* Reset the interrupts */
254
+	statusRegisterContents.bits.TX_DS = 1;
255
+	statusRegisterContents.bits.MAX_RT = 1;
256
+	statusRegisterContents.bits.RX_DR = 1;
257
+	Write_NRF_Register(STATUS_ADDRESS, statusRegisterContents.byte);
258
+
259
+	return messageReceived;
260
+}
261
+
262
+uint8_t Read_NRF_Status_Register(void)
263
+{
264
+	uint8_t registerContents;
217 265
 
218
-	return numberOfBytes;
266
+	registerContents = Write_One_Byte(0x0);
267
+	return registerContents;
219 268
 }
220 269
 
221
-#endif
270
+
271
+uint8_t Read_NRF_Register(uint8_t address)
272
+{
273
+	uint8_t registerContents;
274
+
275
+	registerContents = Write_Two_Bytes(address, 0x0);
276
+
277
+	return registerContents;
278
+}
222 279
 
223 280
 void Write_NRF_Register(uint8_t address, uint8_t registerContents)
224 281
 {
@@ -230,31 +287,59 @@ void Send_Activate_Command(void)
230 287
 	Write_Two_Bytes(0x50, 0x73);
231 288
 }
232 289
 
233
-static void Write_Two_Bytes(uint8_t byte1, uint8_t byte2)
290
+void Send_TX_Flush_Command(void)
291
+{
292
+	Write_One_Byte(FLUSH_TX_COMMAND);
293
+}
294
+
295
+void Send_RX_Flush_Command(void)
234 296
 {
297
+	Write_One_Byte(FLUSH_RX_COMMAND);
298
+}
299
+
300
+static uint8_t Write_One_Byte(uint8_t byte1)
301
+{
302
+	uint8_t registerContents = 0;
235 303
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
236 304
 
237
-	SPI_Transfer_Byte(byte1);
238
-	SPI_Transfer_Byte(byte2);
305
+	registerContents = SPI_Transfer_Byte(byte1);
239 306
 
240 307
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
308
+	return registerContents;
241 309
 }
242 310
 
243
-void Send_TX_Flush_Command(void)
311
+static uint8_t Write_Two_Bytes(uint8_t byte1, uint8_t byte2)
244 312
 {
245
-	/* First write the write command with the address */
313
+	uint8_t registerContents = 0;
246 314
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
247 315
 
248
-	SPI_Transfer_Byte(0xE1);
316
+	SPI_Transfer_Byte(byte1);
317
+	registerContents = SPI_Transfer_Byte(byte2);
249 318
 
250 319
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
320
+	return registerContents;
251 321
 }
252 322
 
253 323
 
254 324
 
255 325
 void Write_Message_To_TX_FIFO(uint8_t length, uint8_t * buffer)
256 326
 {
257
-	Write_Byte_And_Buffer(0xA0, buffer, length);
327
+	Write_Byte_And_Buffer(W_TX_PAYLOAD_COMMAND, buffer, length);
328
+}
329
+
330
+void Read_Message_From_RX_FIFO(uint8_t length, uint8_t * buffer)
331
+{
332
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
333
+
334
+	SPI_Transfer_Byte(R_RX_PAYLOAD_COMMAND);
335
+
336
+	/* Write the data byte */
337
+	for (uint8_t i = 0; i < length; i ++)
338
+	{
339
+		buffer[i] = SPI_Transfer_Byte(0x0);
340
+	}
341
+
342
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
258 343
 }
259 344
 
260 345
 void Set_TX_Address(uint8_t * txAddress, uint8_t length)
@@ -267,6 +352,11 @@ void Set_RX_P0_Address(uint8_t * rxAddress, uint8_t length)
267 352
 	Write_Byte_And_Buffer(RX_ADDR_P0_ADDRESS | 0x20, rxAddress, length);
268 353
 }
269 354
 
355
+void Set_RX_P1_Address(uint8_t * rxAddress, uint8_t length)
356
+{
357
+	Write_Byte_And_Buffer(RX_ADDR_P1_ADDRESS | 0x20, rxAddress, length);
358
+}
359
+
270 360
 static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length)
271 361
 {
272 362
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
@@ -281,5 +371,3 @@ static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length
281 371
 
282 372
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
283 373
 }
284
-
285
-//TODO: only write the used bytes into the address registers & add generic write functions

+ 27
- 10
weather-sensor/firmware/nrf24l01.h ファイルの表示

@@ -1,7 +1,9 @@
1 1
 #ifndef NRF24L01_H
2 2
 #define NRF24L01_H
3 3
 
4
-#define PACKET_BUFFER_LENGTH 22
4
+#define PACKET_LENGTH 32
5
+
6
+#define PACKET_PAYLOAD_BUFFER_LENGTH 22
5 7
 
6 8
 /* AVR I/O pin definionts */
7 9
 #define NRF_CE_DDR   DDRD
@@ -22,21 +24,24 @@ void Initialize_NRF24L01(void);
22 24
 void Set_NRF24L01_Pins(void);
23 25
 void Configure_Transmission(uint8_t moduleId);
24 26
 uint8_t Read_NRF_Status_Register(void);
25
-uint8_t Read_NRF_Register(uint8_t address, uint8_t * registerContents);
27
+uint8_t Read_NRF_Register(uint8_t address);
26 28
 void Write_NRF_Register(uint8_t address, uint8_t registerContents);
27 29
 void Send_Activate_Command(void);
28
-
29
-void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length);
30
+bool NRF24L01_Send_Message(uint8_t *buffer, uint8_t length);
31
+bool NRF24L01_Receive_Message(uint8_t *buffer, uint8_t duration);
30 32
 void Write_Message_To_TX_FIFO(uint8_t length, uint8_t * buffer);
33
+void Read_Message_From_RX_FIFO(uint8_t length, uint8_t * buffer);
31 34
 void Set_TX_Address(uint8_t * txAddress, uint8_t length);
32 35
 void Set_RX_P0_Address(uint8_t * rxAddress, uint8_t length);
36
+void Set_RX_P1_Address(uint8_t * rxAddress, uint8_t length);
33 37
 
34 38
 typedef enum
35 39
 {
36
-	PACKET_TYPE_SALT = 0,
37
-	PACKET_TYPE_REPORT = 1,
38
-	PACKET_TYPE_GET_VALUES = 2,
39
-	PACKET_TYPE_VALUES = 3,
40
+	PACKET_TYPE_GET_SALT = 0,
41
+	PACKET_TYPE_SALT = 1,
42
+	PACKET_TYPE_REPORT = 2,
43
+	PACKET_TYPE_GET_VALUES = 3,
44
+	PACKET_TYPE_VALUES = 4,
40 45
 } PACKET_TYPE;
41 46
 
42 47
 typedef enum
@@ -66,8 +71,20 @@ typedef struct __attribute__((packed)) PACKET
66 71
 			uint8_t valueTypeHumidity;
67 72
 			uint16_t humidity;
68 73
 			uint8_t unused[10];
69
-		} values;
70
-		uint8_t buffer[PACKET_BUFFER_LENGTH];
74
+		} reportData;
75
+
76
+		struct {
77
+			BITFIELD_PACKET_COUNT_ELEMENT packetIdentifier;
78
+			uint8_t salt[7];
79
+			uint8_t unused[14];
80
+		} saltData;
81
+
82
+		struct {
83
+			BITFIELD_PACKET_COUNT_ELEMENT packetIdentifier;
84
+			uint8_t unused[21];
85
+		} getSaltData;
86
+
87
+		uint8_t buffer[PACKET_PAYLOAD_BUFFER_LENGTH];
71 88
 	}payload;
72 89
 	uint16_t crc;
73 90
 } PACKET;

+ 6
- 0
weather-sensor/firmware/nrf24l01_definitions.h ファイルの表示

@@ -31,6 +31,12 @@
31 31
 #define DYNPD_ADDRESS 0x1C
32 32
 #define FEATURE_ADDRESS 0x1D
33 33
 
34
+/* Commands */
35
+#define FLUSH_TX_COMMAND 0xE1
36
+#define FLUSH_RX_COMMAND 0xE2
37
+#define W_TX_PAYLOAD_COMMAND 0xA0
38
+#define R_RX_PAYLOAD_COMMAND 0x61
39
+
34 40
 /* Register bits definitions */
35 41
 /* CONFIG*/
36 42
 typedef union

+ 4
- 1
weather-sensor/firmware/pin_programming.c ファイルの表示

@@ -1,5 +1,6 @@
1 1
 #include <avr/io.h>
2 2
 #include <stdint.h>
3
+#include <util/delay.h>
3 4
 
4 5
 #include "pin_programming.h"
5 6
 
@@ -30,10 +31,12 @@ void Configure_Pin_Programming_Pins(void)
30 31
 	PIN_PROG_2_DDR &= ~(1 << PIN_PROG_2_PIN);
31 32
 	PIN_PROG_3_DDR &= ~(1 << PIN_PROG_3_PIN);
32 33
 
33
-	/* Enable pull-ups */ // TODO: enable once the boards have been fixed!
34
+	/* Enable pull-ups */
34 35
 	PIN_PROG_1_PORT |= (1 << PIN_PROG_1_PIN);
35 36
 	PIN_PROG_2_PORT |= (1 << PIN_PROG_2_PIN);
36 37
 	PIN_PROG_3_PORT |= (1 << PIN_PROG_3_PIN);
38
+
39
+	_delay_us(20);
37 40
 }
38 41
 
39 42
 uint8_t Get_Own_Identifier(void)

+ 93
- 0
weather-sensor/firmware/radio.c ファイルの表示

@@ -0,0 +1,93 @@
1
+#include <string.h>
2
+#include "radio.h"
3
+#include "encryption.h"
4
+#include "crc.h"
5
+
6
+const uint8_t encryptionKey[16] = {0x9e, 0x37, 0x79, 0xb9, 0x9b, 0x97, 0x73, 0xe9, 0xb9, 0x79, 0x37, 0x9e, 0x6b, 0x69, 0x51, 0x56}; /* TODO: use exernal file with the keys */
7
+
8
+bool Send_Message(PACKET * packet, uint64_t * salt);
9
+
10
+bool Send_Get_Salt_Message(PACKET * packet, uint64_t * salt) //TODO: put into own file
11
+{
12
+	memset((uint8_t*)packet, 0, PACKET_LENGTH); //Reinitialize the buffer with zeros
13
+
14
+	packet->payload.reportData.packetIdentifier.elementCount = 0;
15
+	packet->payload.reportData.packetIdentifier.packetType = PACKET_TYPE_GET_SALT;
16
+
17
+	return Send_Message(packet, salt);
18
+}
19
+
20
+bool Send_Report_Message(PACKET * packet, uint64_t * salt, struct bme280_data * sensorData)
21
+{
22
+	packet->payload.reportData.packetIdentifier.elementCount = 3;
23
+	packet->payload.reportData.packetIdentifier.packetType = PACKET_TYPE_REPORT;
24
+
25
+	/* Fill in the payload */
26
+	packet->payload.reportData.valueTypeTemperature = VALUE_TYPE_TEMPERATURE;
27
+	packet->payload.reportData.temperature = sensorData->temperature/10;
28
+	packet->payload.reportData.valueTypePressure = VALUE_TYPE_PRESSURE;
29
+	packet->payload.reportData.pressure = sensorData->pressure;
30
+	packet->payload.reportData.valueTypeHumidity = VALUE_TYPE_HUMIDITY;
31
+	packet->payload.reportData.humidity = sensorData->humidity * 100/1024;
32
+
33
+	return Send_Message(packet, salt);
34
+}
35
+
36
+bool Send_Message(PACKET * packet, uint64_t * salt)
37
+{
38
+	bool success;
39
+
40
+	uint16_t crc;
41
+	(*salt) &= ~(1ull<<63); /* Set the most significant bit to 0 to indicate a packet from the device to the base station */
42
+
43
+	packet->salt = *salt;
44
+
45
+	/* Calculate the CRC */
46
+	crc = Calculate_Crc(packet->payload.buffer, PACKET_PAYLOAD_BUFFER_LENGTH);
47
+	packet->crc = crc;
48
+
49
+	Encrypt((uint32_t*) packet->payload.buffer,
50
+	        PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(crc),
51
+	        *salt,
52
+	        (uint32_t*) encryptionKey);
53
+
54
+	success = NRF24L01_Send_Message((uint8_t*)packet, PACKET_LENGTH);
55
+
56
+	/* Increment salt */
57
+	(*salt) += (1 << 8);
58
+
59
+	return success;
60
+}
61
+
62
+bool Read_Salt_Message(PACKET * packet, uint64_t * salt)
63
+{
64
+	uint16_t crcRemainder = 0xFFFF;
65
+	uint64_t baseStationSalt = 0x0;
66
+
67
+
68
+	/* TODO: check that the packet originated from the base station by checking the id */
69
+
70
+	baseStationSalt = packet->salt;
71
+	Decrypt((uint32_t*)packet->payload.buffer,
72
+	        PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(packet->crc),
73
+	        baseStationSalt,
74
+	        (uint32_t*) encryptionKey);
75
+
76
+	crcRemainder = Calculate_Crc(packet->payload.buffer,
77
+	                             PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(packet->crc));
78
+	if (crcRemainder != 0)
79
+	{
80
+		return false;
81
+	}
82
+
83
+	if ((packet->payload.saltData.packetIdentifier.packetType != PACKET_TYPE_SALT) ||
84
+	    (packet->payload.saltData.packetIdentifier.elementCount != 0))
85
+	{
86
+		return false;
87
+	}
88
+
89
+	memcpy((uint8_t*)salt, packet->payload.saltData.salt, 7);
90
+	*salt = (*salt) << 8;
91
+
92
+	return true;
93
+}

+ 13
- 0
weather-sensor/firmware/radio.h ファイルの表示

@@ -0,0 +1,13 @@
1
+#ifndef RADIO_H
2
+#define RADIO_H
3
+
4
+#include <stdint.h>
5
+#include <stdbool.h>
6
+#include "bme280_defs.h"
7
+#include "nrf24l01.h"
8
+
9
+bool Send_Get_Salt_Message(PACKET * packet, uint64_t * salt); //TODO: put into own file
10
+bool Read_Salt_Message(PACKET * packet, uint64_t * salt);
11
+bool Send_Report_Message(PACKET * packet, uint64_t * salt, struct bme280_data * sensorData);
12
+
13
+#endif

読み込み中…
キャンセル
保存