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
 
65
 
66
 		/* Setup for next block */
66
 		/* Setup for next block */
67
 		currentCipherBlock = previousCipherBlock;
67
 		currentCipherBlock = previousCipherBlock;
68
-		if (previousCipherBlock != (uint8_t*) data + LENGTH_OF_BLOCK)
68
+		if (previousCipherBlock != (uint8_t*) data)
69
 		{
69
 		{
70
 			previousCipherBlock -= LENGTH_OF_BLOCK;
70
 			previousCipherBlock -= LENGTH_OF_BLOCK;
71
 		}
71
 		}

+ 37
- 49
weather-sensor/firmware/main.c 查看文件

15
 #include "bme280_interface.h"
15
 #include "bme280_interface.h"
16
 #include "bme280_defs.h"
16
 #include "bme280_defs.h"
17
 #include "pin_programming.h"
17
 #include "pin_programming.h"
18
-#include "crc.h"
19
-#include "encryption.h"
18
+#include "radio.h"
20
 
19
 
21
 
20
 
22
 
21
 
23
 uint8_t ownId;
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
 uint64_t salt;
23
 uint64_t salt;
26
 
24
 
27
 char bool_case = 0;
25
 char bool_case = 0;
36
 volatile uint8_t executionFlag;
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
 void Enter_Power_Save_Mode(void);
41
 void Enter_Power_Save_Mode(void);
44
 void Exit_Power_Save_Mode(void);
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
 void Set_Up_Power_Save_Mode(void);
46
 void Set_Up_Power_Save_Mode(void);
59
 void Enter_Power_Save_Mode(void);
47
 void Enter_Power_Save_Mode(void);
60
 
48
 
72
 int main (void)
60
 int main (void)
73
 {
61
 {
74
 	struct bme280_data sensorData;
62
 	struct bme280_data sensorData;
75
-	uint16_t crc;
63
+	bool saltReceived = false;
76
 
64
 
77
 	/* Enable the debug LED */
65
 	/* Enable the debug LED */
78
 	LED_DDR |= (1 << LED_PIN);
66
 	LED_DDR |= (1 << LED_PIN);
96
 	Set_Up_Power_Save_Mode();
84
 	Set_Up_Power_Save_Mode();
97
 
85
 
98
 	/* Initialize the salt */
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
 	/* Delay the change of the operating frequency by the function Enter_Power_Save_Mode for the
116
 	/* Delay the change of the operating frequency by the function Enter_Power_Save_Mode for the
103
 	 * first function pass. If it is changed before the ISP can flash the MCU the clocks of the ISP
117
 	 * first function pass. If it is changed before the ISP can flash the MCU the clocks of the ISP
119
 			/* Get measurement and send it */
133
 			/* Get measurement and send it */
120
 			BME280_Get_Measurement(&sensorData);
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
 			_delay_ms(100); /* TODO: only for debugging, remove this later! */
140
 			_delay_ms(100); /* TODO: only for debugging, remove this later! */
154
 			LED_PORT &= ~(1 << LED_PIN);
141
 			LED_PORT &= ~(1 << LED_PIN);
155
 
142
 
225
 	PRR &= ~(1<<PRSPI); // Enable SPI
212
 	PRR &= ~(1<<PRSPI); // Enable SPI
226
 	Initialize_SPI(); // reinitalize SPI
213
 	Initialize_SPI(); // reinitalize SPI
227
 }
214
 }
215
+

+ 3
- 3
weather-sensor/firmware/makefile 查看文件

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
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
 all: main.hex
4
 all: main.hex
5
 
5
 
9
 	rm -f obj/*.o
9
 	rm -f obj/*.o
10
 
10
 
11
 flash: main.hex
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
 obj/%.o: %.c $(DEPS)
14
 obj/%.o: %.c $(DEPS)
15
 	avr-gcc -c $< -o $@ $(CFLAGS)
15
 	avr-gcc -c $< -o $@ $(CFLAGS)
17
 obj/%.o: BME280_driver/%.c $(DEPS)
17
 obj/%.o: BME280_driver/%.c $(DEPS)
18
 	avr-gcc -c $< -o $@ $(CFLAGS)
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
 	avr-gcc $^ -o $@ $(CFLAGS)
21
 	avr-gcc $^ -o $@ $(CFLAGS)
22
 
22
 
23
 main.hex: main
23
 main.hex: main

+ 163
- 75
weather-sensor/firmware/nrf24l01.c 查看文件

17
 extern volatile bool nrfInterruptRaised;
17
 extern volatile bool nrfInterruptRaised;
18
 
18
 
19
 void Print_Register_Contents(uint8_t address);
19
 void Print_Register_Contents(uint8_t address);
20
+
21
+
20
 void Send_TX_Flush_Command(void);
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
 static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length);
27
 static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length);
24
 
28
 
25
 /* Startup and initial configuration of the NRF24L01 */
29
 /* Startup and initial configuration of the NRF24L01 */
64
 
68
 
65
 void Configure_Transmission(uint8_t moduleId)
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
 	FEATURE_REGISTER featureRegisterContents = {.byte = 0x0};
75
 	FEATURE_REGISTER featureRegisterContents = {.byte = 0x0};
68
 	DYNPD_REGISTER dyndpRegisterContents = {.byte = 0x0};
76
 	DYNPD_REGISTER dyndpRegisterContents = {.byte = 0x0};
69
-	SETUP_RETR_REGISTER setupRetrRegisterContents = {.byte = 0x0};
70
 
77
 
71
 	uint8_t txAddress[5] = {0xB3, 0xB3, 0xB3, 0xB3, 0x00};
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
 	/* Set the frequency to 1450 MHz */
81
 	/* Set the frequency to 1450 MHz */
96
 	Write_NRF_Register(RF_CH_ADDRESS, 0x32);
82
 	Write_NRF_Register(RF_CH_ADDRESS, 0x32);
100
 	featureRegisterContents.bits.EN_DPL = 1; // enable dynamic payload length
86
 	featureRegisterContents.bits.EN_DPL = 1; // enable dynamic payload length
101
 	Write_NRF_Register(FEATURE_ADDRESS, featureRegisterContents.byte);
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
 	dyndpRegisterContents.bits.DPL_P0 = 1;
93
 	dyndpRegisterContents.bits.DPL_P0 = 1;
110
 	dyndpRegisterContents.bits.DPL_P1 = 1;
94
 	dyndpRegisterContents.bits.DPL_P1 = 1;
111
 	dyndpRegisterContents.bits.DPL_P2 = 1;
95
 	dyndpRegisterContents.bits.DPL_P2 = 1;
114
 	dyndpRegisterContents.bits.DPL_P5 = 1;
98
 	dyndpRegisterContents.bits.DPL_P5 = 1;
115
 	Write_NRF_Register(DYNPD_ADDRESS, dyndpRegisterContents.byte);
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
 	/* Set the TX address */
106
 	/* Set the TX address */
118
 	Set_TX_Address(txAddress, MAX_ADDRESS_LENGTH);
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
 	PCMSK2 |= (1<<PCINT21); // Set the external interrupt for PD5
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
 	STATUS_REGISTER statusRegisterContents = {.byte = 0x0};
152
 	STATUS_REGISTER statusRegisterContents = {.byte = 0x0};
130
 	
153
 	
131
 	if ((length > 32) || (length == 0))
154
 	if ((length > 32) || (length == 0))
132
 	{
155
 	{
133
-		return;
156
+		return success;
134
 	}
157
 	}
135
 
158
 
136
 	PCICR |= (1<<PCIE2); // Enable the interrupt for the IRQ signal
159
 	PCICR |= (1<<PCIE2); // Enable the interrupt for the IRQ signal
147
 	 * induced by the SPI:
170
 	 * induced by the SPI:
148
 	 * https://forum.mysensors.org/topic/10452/nrf24l01-communication-failure-root-cause-and-solution
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
 	statusRegisterContents.byte = Read_NRF_Status_Register();
174
 	statusRegisterContents.byte = Read_NRF_Status_Register();
153
 
175
 
156
 	{
178
 	{
157
 		Send_TX_Flush_Command(); /* Remove the packet from the TX FIFO as it is not done automatically */
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
 	/* Reset the interrupts */
187
 	/* Reset the interrupts */
168
 	nrfInterruptRaised = false;
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
 void Write_NRF_Register(uint8_t address, uint8_t registerContents)
280
 void Write_NRF_Register(uint8_t address, uint8_t registerContents)
224
 {
281
 {
230
 	Write_Two_Bytes(0x50, 0x73);
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
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
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
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
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
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
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
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
319
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
320
+	return registerContents;
251
 }
321
 }
252
 
322
 
253
 
323
 
254
 
324
 
255
 void Write_Message_To_TX_FIFO(uint8_t length, uint8_t * buffer)
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
 void Set_TX_Address(uint8_t * txAddress, uint8_t length)
345
 void Set_TX_Address(uint8_t * txAddress, uint8_t length)
267
 	Write_Byte_And_Buffer(RX_ADDR_P0_ADDRESS | 0x20, rxAddress, length);
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
 static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length)
360
 static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length)
271
 {
361
 {
272
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
362
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
281
 
371
 
282
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
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
 #ifndef NRF24L01_H
1
 #ifndef NRF24L01_H
2
 #define NRF24L01_H
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
 /* AVR I/O pin definionts */
8
 /* AVR I/O pin definionts */
7
 #define NRF_CE_DDR   DDRD
9
 #define NRF_CE_DDR   DDRD
22
 void Set_NRF24L01_Pins(void);
24
 void Set_NRF24L01_Pins(void);
23
 void Configure_Transmission(uint8_t moduleId);
25
 void Configure_Transmission(uint8_t moduleId);
24
 uint8_t Read_NRF_Status_Register(void);
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
 void Write_NRF_Register(uint8_t address, uint8_t registerContents);
28
 void Write_NRF_Register(uint8_t address, uint8_t registerContents);
27
 void Send_Activate_Command(void);
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
 void Write_Message_To_TX_FIFO(uint8_t length, uint8_t * buffer);
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
 void Set_TX_Address(uint8_t * txAddress, uint8_t length);
34
 void Set_TX_Address(uint8_t * txAddress, uint8_t length);
32
 void Set_RX_P0_Address(uint8_t * rxAddress, uint8_t length);
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
 typedef enum
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
 } PACKET_TYPE;
45
 } PACKET_TYPE;
41
 
46
 
42
 typedef enum
47
 typedef enum
66
 			uint8_t valueTypeHumidity;
71
 			uint8_t valueTypeHumidity;
67
 			uint16_t humidity;
72
 			uint16_t humidity;
68
 			uint8_t unused[10];
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
 	}payload;
88
 	}payload;
72
 	uint16_t crc;
89
 	uint16_t crc;
73
 } PACKET;
90
 } PACKET;

+ 6
- 0
weather-sensor/firmware/nrf24l01_definitions.h 查看文件

31
 #define DYNPD_ADDRESS 0x1C
31
 #define DYNPD_ADDRESS 0x1C
32
 #define FEATURE_ADDRESS 0x1D
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
 /* Register bits definitions */
40
 /* Register bits definitions */
35
 /* CONFIG*/
41
 /* CONFIG*/
36
 typedef union
42
 typedef union

+ 4
- 1
weather-sensor/firmware/pin_programming.c 查看文件

1
 #include <avr/io.h>
1
 #include <avr/io.h>
2
 #include <stdint.h>
2
 #include <stdint.h>
3
+#include <util/delay.h>
3
 
4
 
4
 #include "pin_programming.h"
5
 #include "pin_programming.h"
5
 
6
 
30
 	PIN_PROG_2_DDR &= ~(1 << PIN_PROG_2_PIN);
31
 	PIN_PROG_2_DDR &= ~(1 << PIN_PROG_2_PIN);
31
 	PIN_PROG_3_DDR &= ~(1 << PIN_PROG_3_PIN);
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
 	PIN_PROG_1_PORT |= (1 << PIN_PROG_1_PIN);
35
 	PIN_PROG_1_PORT |= (1 << PIN_PROG_1_PIN);
35
 	PIN_PROG_2_PORT |= (1 << PIN_PROG_2_PIN);
36
 	PIN_PROG_2_PORT |= (1 << PIN_PROG_2_PIN);
36
 	PIN_PROG_3_PORT |= (1 << PIN_PROG_3_PIN);
37
 	PIN_PROG_3_PORT |= (1 << PIN_PROG_3_PIN);
38
+
39
+	_delay_us(20);
37
 }
40
 }
38
 
41
 
39
 uint8_t Get_Own_Identifier(void)
42
 uint8_t Get_Own_Identifier(void)

+ 93
- 0
weather-sensor/firmware/radio.c 查看文件

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 查看文件

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

Loading…
取消
儲存