Sfoglia il codice sorgente

Add handling of the salt

On start-up the sensor sends a Get_Salt-message to the base station. The
base station responds and sends the salt, which the sensor uses from
there on.
Bernd Gottschlag 5 anni fa
parent
commit
4f83ec8bef

+ 120
- 29
weather-sensor/firmware/main.c Vedi File

@@ -36,25 +36,17 @@ volatile uint8_t interruptCounter;
36 36
 volatile uint8_t executionFlag;
37 37
 
38 38
 
39
-
40
-static PACKET reportPacket;
39
+static uint8_t messageBuffer[PACKET_LENGTH];
40
+static PACKET * packet = (PACKET*) messageBuffer;
41 41
 
42 42
 
43 43
 void Enter_Power_Save_Mode(void);
44 44
 void Exit_Power_Save_Mode(void);
45 45
 
46 46
 
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
- */
47
+bool Send_Get_Salt_Message(PACKET * packet, uint64_t salt); //TODO: put into own file
48
+bool Read_Salt_Message(PACKET * packet, uint64_t * salt);
49
+
58 50
 void Set_Up_Power_Save_Mode(void);
59 51
 void Enter_Power_Save_Mode(void);
60 52
 
@@ -73,6 +65,7 @@ int main (void)
73 65
 {
74 66
 	struct bme280_data sensorData;
75 67
 	uint16_t crc;
68
+	bool saltReceived = false;
76 69
 
77 70
 	/* Enable the debug LED */
78 71
 	LED_DDR |= (1 << LED_PIN);
@@ -96,9 +89,41 @@ int main (void)
96 89
 	Set_Up_Power_Save_Mode();
97 90
 
98 91
 	/* Initialize the salt */
99
-	salt = 0xFFFFFFFFFFFFFF00ull;
92
+	salt = 0x0ull;
100 93
 	salt |= ownId;
101 94
 
95
+
96
+	/* TODO: Request a salt from the base station:
97
+	 * - loop as long as no reply from the base station was received:
98
+	 *   - send the packet that requests the salt
99
+	 *   - if no ack is received for the packet go direclty to sleep for 100 ms
100
+	 *   - if no salt is received within 100 ms send the message again
101
+	 *   - keep the LED on for the duration to allow the user to see that the device is ready for operation.
102
+	 */
103
+	LED_PORT |= (1 << LED_PIN);
104
+	do
105
+	{
106
+		if (Send_Get_Salt_Message(packet, salt) == true)
107
+		{
108
+			memset(messageBuffer, 0x0F, 32);
109
+			if (NRF24L01_Receive_Message(messageBuffer, 100 /*ms*/) == true)
110
+			{
111
+				_delay_ms(10);
112
+				saltReceived = Read_Salt_Message(packet, &salt);
113
+			}
114
+		}
115
+		else
116
+		{
117
+			/* TODO: enter power save mode instead to make the battery life longer */
118
+			_delay_ms(100);
119
+		}
120
+	} while (saltReceived == false);
121
+	LED_PORT &= ~(1 << LED_PIN);
122
+
123
+	salt &= 0xFFFFFFFFFFFFFF00ull;
124
+	salt |= ownId;
125
+
126
+
102 127
 	/* Delay the change of the operating frequency by the function Enter_Power_Save_Mode for the
103 128
 	 * first function pass. If it is changed before the ISP can flash the MCU the clocks of the ISP
104 129
 	 * and MCU are mismatched and the flashing will fail.
@@ -120,36 +145,41 @@ int main (void)
120 145
 			BME280_Get_Measurement(&sensorData);
121 146
 
122 147
 
123
-			memset((uint8_t*)&reportPacket, 0, sizeof(reportPacket)); //Reinitialize the buffer with zeros
148
+			/* TODO: put the following into a Send_Report function */
149
+			memset((uint8_t*)packet, 0, PACKET_LENGTH); //Reinitialize the buffer with zeros
124 150
 
125 151
 			salt &= ~(1ull<<63);
126
-			reportPacket.salt = salt;
127
-			reportPacket.payload.values.packetIdentifier.elementCount = 3;
128
-			reportPacket.payload.values.packetIdentifier.packetType = PACKET_TYPE_REPORT;
152
+			packet->salt = salt;
153
+			packet->payload.reportData.packetIdentifier.elementCount = 3;
154
+			packet->payload.reportData.packetIdentifier.packetType = PACKET_TYPE_REPORT;
129 155
 
130 156
 			/* 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;
157
+			packet->payload.reportData.valueTypeTemperature = VALUE_TYPE_TEMPERATURE;
158
+			packet->payload.reportData.temperature = sensorData.temperature/10;
159
+			packet->payload.reportData.valueTypePressure = VALUE_TYPE_PRESSURE;
160
+			packet->payload.reportData.pressure = sensorData.pressure;
161
+			packet->payload.reportData.valueTypeHumidity = VALUE_TYPE_HUMIDITY;
162
+			packet->payload.reportData.humidity = sensorData.humidity * 100/1024;
137 163
 
138 164
 			/* Calculate the CRC */
139
-			crc = Calculate_Crc(reportPacket.payload.buffer, PACKET_BUFFER_LENGTH);
140
-			reportPacket.crc = crc;
165
+			crc = Calculate_Crc(packet->payload.buffer, PACKET_PAYLOAD_BUFFER_LENGTH);
166
+			packet->crc = crc;
141 167
 
142 168
 			/* Encrypt the packet */
143 169
 			/* TODO: 
144 170
 			 * - increment the salt for every packet
145 171
 			 * - Receive salt from the base station
146 172
 			 */
147
-			Encrypt((uint32_t*) &reportPacket.payload.buffer,
148
-			        PACKET_BUFFER_LENGTH + sizeof(crc),
173
+			Encrypt((uint32_t*) packet->payload.buffer,
174
+			        PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(crc),
149 175
 			        salt, (uint32_t*) encryptionKey);
150 176
 
151
-			NRF24L01_Send_Message((uint8_t*)&reportPacket, sizeof(reportPacket));
177
+			NRF24L01_Send_Message((uint8_t*)packet, PACKET_LENGTH);
152 178
 
179
+			/* Increment salt */
180
+			salt += (1 << 8);
181
+
182
+			LED_PORT |= (1 << LED_PIN);
153 183
 			_delay_ms(100); /* TODO: only for debugging, remove this later! */
154 184
 			LED_PORT &= ~(1 << LED_PIN);
155 185
 
@@ -225,3 +255,64 @@ void Exit_Power_Save_Mode(void)
225 255
 	PRR &= ~(1<<PRSPI); // Enable SPI
226 256
 	Initialize_SPI(); // reinitalize SPI
227 257
 }
258
+
259
+bool Send_Get_Salt_Message(PACKET * packet, uint64_t salt) //TODO: put into own file
260
+{
261
+	bool success = false;
262
+	uint16_t crc;
263
+
264
+	memset((uint8_t*)packet, 0, PACKET_LENGTH); //Reinitialize the buffer with zeros
265
+
266
+	salt &= ~(1ull<<63); /* Set the most significant bit to 0 to indicate a packet from the device to the base station */
267
+
268
+	packet->salt = salt;
269
+	packet->payload.reportData.packetIdentifier.elementCount = 0;
270
+	packet->payload.reportData.packetIdentifier.packetType = PACKET_TYPE_GET_SALT;
271
+
272
+	/* Calculate the CRC */
273
+	crc = Calculate_Crc(packet->payload.buffer, PACKET_PAYLOAD_BUFFER_LENGTH);
274
+	packet->crc = crc;
275
+
276
+	Encrypt((uint32_t*) packet->payload.buffer,
277
+	        PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(crc),
278
+	        salt,
279
+	        (uint32_t*) encryptionKey);
280
+
281
+	success = NRF24L01_Send_Message((uint8_t*)packet, PACKET_LENGTH);
282
+
283
+
284
+	return success;
285
+}
286
+
287
+bool Read_Salt_Message(PACKET * packet, uint64_t * salt)
288
+{
289
+	uint16_t crcRemainder = 0xFFFF;
290
+	uint64_t baseStationSalt = 0x0;
291
+
292
+
293
+	/* TODO: check that the packet originated from the base station by checking the id */
294
+
295
+	baseStationSalt = packet->salt;
296
+	Decrypt((uint32_t*)packet->payload.buffer,
297
+	        PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(packet->crc),
298
+	        baseStationSalt,
299
+	        (uint32_t*) encryptionKey);
300
+
301
+	crcRemainder = Calculate_Crc(packet->payload.buffer,
302
+	                             PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(packet->crc));
303
+	if (crcRemainder != 0)
304
+	{
305
+		return false;
306
+	}
307
+
308
+	if ((packet->payload.saltData.packetIdentifier.packetType != PACKET_TYPE_SALT) ||
309
+	    (packet->payload.saltData.packetIdentifier.elementCount != 0))
310
+	{
311
+		return false;
312
+	}
313
+
314
+	memcpy((uint8_t*)salt, packet->payload.saltData.salt, 7);
315
+	*salt = (*salt) << 8;
316
+
317
+	return true;
318
+}

+ 150
- 70
weather-sensor/firmware/nrf24l01.c Vedi File

@@ -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 */
@@ -72,28 +76,7 @@ void Configure_Transmission(uint8_t moduleId)
72 76
 	DYNPD_REGISTER dyndpRegisterContents = {.byte = 0x0};
73 77
 
74 78
 	uint8_t txAddress[5] = {0xB3, 0xB3, 0xB3, 0xB3, 0x00};
75
-	uint8_t rx0Address[5] = {0xB3, 0xB3, 0xB3, 0xB3, 0x00};
76
-	/* 
77
-	 * - Length of CRC (CRCO in CONFIG)
78
-	 * - Enable auto acknowledgment (EN_AA)
79
-	 *   -> Register already set correctly after reset
80
-	 * - Enable data pipes (EN_RXADDR)?
81
-	 *   -> Two pipes are already enabled on reset
82
-	 * - Set up address width (SETUP_AW)
83
-	 *   -> 3 bytes
84
-	 * - Automatic Retransmission (SETUP_RETR)
85
-	 *   -> ARD = 0b0000
86
-	 *   -> 3 retransmits -> ARC = 0b0011
87
-	 *   -> Register already set correctly after reset
88
-	 * - RF Channel (RF_CH)
89
-	 *   -> RF_CH = 0b1010000
90
-	 * - RF Setup (RF_SETUP)
91
-	 *   -> first use reset values, can be fine tuned later
92
-	 * - Enable dynamic payload length (DYNPD) -> command activate + 0x73, then set bits in FEATURE?
93
-	 */
94
-
95
-	/* Set the address width to 3 bytes */
96
-	//Write_NRF_Register(0x03, 0x1);
79
+	uint8_t rx1Address[5] = {0xB3, 0xB3, 0xB3, 0xB3, 0x00};
97 80
 
98 81
 	/* Set the frequency to 1450 MHz */
99 82
 	Write_NRF_Register(RF_CH_ADDRESS, 0x32);
@@ -116,8 +99,6 @@ void Configure_Transmission(uint8_t moduleId)
116 99
 	Write_NRF_Register(DYNPD_ADDRESS, dyndpRegisterContents.byte);
117 100
 
118 101
 	/* Set up the auto retries */
119
-
120
-	/* */
121 102
 	setupRetrRegisterContents.bits.ARC = 0x3;
122 103
 	setupRetrRegisterContents.bits.ARD = 0xF;
123 104
 	Write_NRF_Register(SETUP_RETR_ADDRESS, setupRetrRegisterContents.byte);
@@ -125,20 +106,54 @@ void Configure_Transmission(uint8_t moduleId)
125 106
 	/* Set the TX address */
126 107
 	Set_TX_Address(txAddress, MAX_ADDRESS_LENGTH);
127 108
 
128
-	/* Set the RX_P0 address to the one of the base station to receive acks */
129
-	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();
130 144
 
131 145
 
132 146
 	PCMSK2 |= (1<<PCINT21); // Set the external interrupt for PD5
133 147
 }
134 148
 
135
-void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
149
+bool NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
136 150
 {
151
+	bool success = false;
137 152
 	STATUS_REGISTER statusRegisterContents = {.byte = 0x0};
138 153
 	
139 154
 	if ((length > 32) || (length == 0))
140 155
 	{
141
-		return;
156
+		return success;
142 157
 	}
143 158
 
144 159
 	PCICR |= (1<<PCIE2); // Enable the interrupt for the IRQ signal
@@ -155,7 +170,6 @@ void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
155 170
 	 * induced by the SPI:
156 171
 	 * https://forum.mysensors.org/topic/10452/nrf24l01-communication-failure-root-cause-and-solution
157 172
 	 */
158
-	LED_PORT |= (1 << LED_PIN);
159 173
 
160 174
 	statusRegisterContents.byte = Read_NRF_Status_Register();
161 175
 
@@ -164,6 +178,10 @@ void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
164 178
 	{
165 179
 		Send_TX_Flush_Command(); /* Remove the packet from the TX FIFO as it is not done automatically */
166 180
 	}
181
+	else
182
+	{
183
+		success = true;
184
+	}
167 185
 	
168 186
 
169 187
 	/* Reset the interrupts */
@@ -176,57 +194,88 @@ void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
176 194
 	nrfInterruptRaised = false;
177 195
 
178 196
 
179
-	return;
197
+	return success;
180 198
 }
181 199
 
182
-uint8_t Read_NRF_Status_Register(void)
200
+bool NRF24L01_Receive_Message(uint8_t *buffer, uint8_t duration)
183 201
 {
184
-	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};
185 206
 
186
-	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
187
-	registerContents = SPI_Transfer_Byte(0x00);
188
-	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
189
-	return registerContents;
190
-}
207
+	PCICR |= (1<<PCIE2); // Enable the interrupt for the IRQ signal
191 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);
192 213
 
193
-/* TODO: rewrite the read register function if it is needed (remove the read operations for the 5-byte registers)*/
194
-#if 0
195
-uint8_t Read_NRF_Register(uint8_t address, uint8_t * registerContents)
196
-{
197
-	/* TODO: simplify this function, as the registers with more than one byte are accessed with other functions */
198
-	uint8_t numberOfBytes = 0;
199 214
 
200
-	if ((address == 0x0A) ||
201
-	    (address == 0x0B) ||
202
-	    (address == 0x10))
215
+	NRF_CE_PORT |= (1 << NRF_CE_PIN);
216
+
217
+	_delay_ms(10);
218
+	while ((nrfInterruptRaised == false) && (duration > 0))
203 219
 	{
204
-		numberOfBytes = 5;
205
-	}
206
-	else
220
+		_delay_ms(1);
221
+		duration --;
222
+	};
223
+
224
+	if (nrfInterruptRaised == true) // check if a message was received
207 225
 	{
208
-		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;
209 237
 	}
210 238
 
211
-	/* First write the address */
212
-	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
239
+	// Set the NRF to standby
240
+	NRF_CE_PORT &= ~(1 << NRF_CE_PIN);
213 241
 
242
+	configRegisterContents.byte = Read_NRF_Register(CONFIG_ADDRESS);
243
+	configRegisterContents.bits.PRIM_RX = 0x0;
244
+	Write_NRF_Register(CONFIG_ADDRESS, configRegisterContents.byte);
214 245
 
215
-	SPI_Transfer_Byte(address);
246
+	PCICR &= ~(1<<PCIE2); // Disable the interrupt for the IRQ signal
216 247
 
217
-	/* Read the register bytes */
218
-	for (uint8_t i = 0; i < numberOfBytes; i++)
248
+	if (messageReceived == true)
219 249
 	{
220
-		/* Write dummy data to shift in the register content */
221
-		registerContents[i] = SPI_Transfer_Byte(0x0);
250
+		Read_Message_From_RX_FIFO(PACKET_LENGTH, buffer); /* TODO: only possible after CE = 0? */
222 251
 	}
223 252
 
224
-	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);
225 258
 
226
-	return numberOfBytes;
259
+	return messageReceived;
227 260
 }
228 261
 
229
-#endif
262
+uint8_t Read_NRF_Status_Register(void)
263
+{
264
+	uint8_t registerContents;
265
+
266
+	registerContents = Write_One_Byte(0x0);
267
+	return registerContents;
268
+}
269
+
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
+}
230 279
 
231 280
 void Write_NRF_Register(uint8_t address, uint8_t registerContents)
232 281
 {
@@ -238,31 +287,59 @@ void Send_Activate_Command(void)
238 287
 	Write_Two_Bytes(0x50, 0x73);
239 288
 }
240 289
 
241
-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)
296
+{
297
+	Write_One_Byte(FLUSH_RX_COMMAND);
298
+}
299
+
300
+static uint8_t Write_One_Byte(uint8_t byte1)
242 301
 {
302
+	uint8_t registerContents = 0;
243 303
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
244 304
 
245
-	SPI_Transfer_Byte(byte1);
246
-	SPI_Transfer_Byte(byte2);
305
+	registerContents = SPI_Transfer_Byte(byte1);
247 306
 
248 307
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
308
+	return registerContents;
249 309
 }
250 310
 
251
-void Send_TX_Flush_Command(void)
311
+static uint8_t Write_Two_Bytes(uint8_t byte1, uint8_t byte2)
252 312
 {
253
-	/* First write the write command with the address */
313
+	uint8_t registerContents = 0;
254 314
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
255 315
 
256
-	SPI_Transfer_Byte(0xE1);
316
+	SPI_Transfer_Byte(byte1);
317
+	registerContents = SPI_Transfer_Byte(byte2);
257 318
 
258 319
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
320
+	return registerContents;
259 321
 }
260 322
 
261 323
 
262 324
 
263 325
 void Write_Message_To_TX_FIFO(uint8_t length, uint8_t * buffer)
264 326
 {
265
-	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);
266 343
 }
267 344
 
268 345
 void Set_TX_Address(uint8_t * txAddress, uint8_t length)
@@ -275,6 +352,11 @@ void Set_RX_P0_Address(uint8_t * rxAddress, uint8_t length)
275 352
 	Write_Byte_And_Buffer(RX_ADDR_P0_ADDRESS | 0x20, rxAddress, length);
276 353
 }
277 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
+
278 360
 static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length)
279 361
 {
280 362
 	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
@@ -289,5 +371,3 @@ static void Write_Byte_And_Buffer(uint8_t byte, uint8_t * buffer, uint8_t length
289 371
 
290 372
 	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
291 373
 }
292
-
293
-//TODO: only write the used bytes into the address registers & add generic write functions

+ 27
- 10
weather-sensor/firmware/nrf24l01.h Vedi File

@@ -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 Vedi File

@@ -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

Loading…
Annulla
Salva