21 Revīzijas

Autors SHA1 Ziņojums Datums
  Bernd Gottschlag f7bfdf101c Add definitions of the IRQ pin to the nrf24l01 5 gadus atpakaļ
  Bernd Gottschlag 1dd0f89149 Fix pin definitions of the interface to the nrf24l01 5 gadus atpakaļ
  Bernd Gottschlag 011303042b Remove a variable that caused a compiler warning 5 gadus atpakaļ
  Bernd Gottschlag f1b0ebf618 Move SPI initialization and pin definitions to spi.c 5 gadus atpakaļ
  Bernd Gottschlag 204ff8d220 Add power save mode and send messages every 7.5s 5 gadus atpakaļ
  Bernd Gottschlag 0c03c24fcd Change the MCU to the Atmega88 5 gadus atpakaļ
  Bernd Gottschlag ddb5b0426e Send the data from the BME280 with the NRF24L01 5 gadus atpakaļ
  Bernd Gottschlag 01dff7cfd3 Use spi functions 5 gadus atpakaļ
  Bernd Gottschlag 93fd7841a9 Use spi functions 5 gadus atpakaļ
  Bernd Gottschlag 9d1b611356 Use dedicated function to read the status register when transmitting 5 gadus atpakaļ
  Bernd Gottschlag fc26a37348 Set the transmission retries and time-out duration to each maximum 5 gadus atpakaļ
  Bernd Gottschlag b9cfc34e94 Flush TX FIFO after an unsuccessful transmission 5 gadus atpakaļ
  Bernd Gottschlag 45f19e8c43 Fix register struct definitions 5 gadus atpakaļ
  Bernd Gottschlag 5ee6bbbf1a Add SPI interface functions 5 gadus atpakaļ
  Bernd Gottschlag 7f1da0221c Update .gitignore 5 gadus atpakaļ
  Bernd Gottschlag e5ad15dbfa Add reading from the BME280 using the official API 5 gadus atpakaļ
  Bernd Gottschlag 780cedcbc4 Fix order of the bit fields of the register definitions 5 gadus atpakaļ
  Bernd Gottschlag 278f7f23fe WIP: use register definitions to access them 5 gadus atpakaļ
  Bernd Gottschlag b487ab67f6 Add nRF24L01 register definitions 5 gadus atpakaļ
  Bernd Gottschlag 33e1d5e700 WIP tidy up the NRF24L01 code 5 gadus atpakaļ
  Bernd Gottschlag 347211065c Add prototyping code for sending a dummy message with the nrf24l01 5 gadus atpakaļ

+ 3
- 0
.gitmodules Parādīt failu

@@ -0,0 +1,3 @@
1
+[submodule "weather-sensor/firmware/BME280_driver"]
2
+	path = weather-sensor/firmware/BME280_driver
3
+	url = https://github.com/BoschSensortec/BME280_driver.git

+ 5
- 0
weather-sensor/firmware/.gitignore Parādīt failu

@@ -0,0 +1,5 @@
1
+main
2
+*.hex
3
+
4
+
5
+*.swp

+ 1
- 0
weather-sensor/firmware/BME280_driver

@@ -0,0 +1 @@
1
+Subproject commit 3d686a326565b9cadb8507f73d7576ec0cc891f2

+ 112
- 0
weather-sensor/firmware/bme280_interface.c Parādīt failu

@@ -0,0 +1,112 @@
1
+#include <avr/io.h>
2
+#include <util/delay.h>
3
+
4
+#include "spi.h"
5
+#include "bme280.h"
6
+#include "bme280_interface.h"
7
+
8
+
9
+void user_delay_ms(uint32_t period);
10
+int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len);
11
+int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len);
12
+
13
+
14
+struct bme280_dev deviceStructure;
15
+uint32_t req_delay;
16
+
17
+
18
+int8_t Initialize_BME280(void)
19
+{
20
+	int8_t rslt = BME280_OK;
21
+	uint8_t settings_sel;
22
+
23
+
24
+	Set_BME280_Pins();
25
+
26
+	/* Sensor_0 interface over SPI with native chip select line */
27
+	deviceStructure.dev_id = 0;
28
+	deviceStructure.intf = BME280_SPI_INTF;
29
+	deviceStructure.read = user_spi_read;
30
+	deviceStructure.write = user_spi_write;
31
+	deviceStructure.delay_ms = user_delay_ms;
32
+
33
+	rslt = bme280_init(&deviceStructure);
34
+
35
+	/* Settings for mode of operation: weather monitorint */
36
+	deviceStructure.settings.osr_h = BME280_OVERSAMPLING_1X;
37
+	deviceStructure.settings.osr_p = BME280_OVERSAMPLING_1X;
38
+	deviceStructure.settings.osr_t = BME280_OVERSAMPLING_1X;
39
+	deviceStructure.settings.filter = BME280_FILTER_COEFF_OFF;
40
+
41
+	settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
42
+
43
+	rslt = bme280_set_sensor_settings(settings_sel, &deviceStructure);
44
+
45
+	/* calculate minimum delay required between consecutive measurments */
46
+	req_delay = bme280_cal_meas_delay(&deviceStructure.settings);
47
+
48
+	return rslt;
49
+}
50
+
51
+void Set_BME280_Pins(void)
52
+{
53
+	/* Setup the SPI interface */
54
+	BME_CSN_DDR |= (1 << BME_CSN_PIN);
55
+	BME_CSN_PORT |= (1 << BME_CSN_PIN);
56
+}
57
+
58
+/* Get one measurement in forced mode */
59
+void BME280_Get_Measurement(struct bme280_data * data)
60
+{
61
+	bme280_set_sensor_mode(BME280_FORCED_MODE, &deviceStructure);
62
+	deviceStructure.delay_ms(req_delay);
63
+	bme280_get_sensor_data(BME280_ALL, data, &deviceStructure);
64
+}
65
+
66
+/* Implementation of the interface function needed by the BME280 library */
67
+void user_delay_ms(uint32_t period)
68
+{
69
+	while (period--)
70
+	{
71
+		_delay_ms(1);
72
+	}
73
+}
74
+
75
+int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
76
+{
77
+	int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
78
+
79
+	/* unused parameters */
80
+	(void)dev_id;
81
+
82
+	SPI_Start_Transmission(&BME_CSN_PORT, BME_CSN_PIN);
83
+	SPI_Transfer_Byte(reg_addr);
84
+
85
+	for (uint16_t i = 0; i < len; i ++)
86
+	{
87
+		reg_data[i] = SPI_Transfer_Byte(0x0); /* Value to send doesn't matter */
88
+	}
89
+	SPI_Stop_Transmission(&BME_CSN_PORT, BME_CSN_PIN);
90
+
91
+	return rslt;
92
+}
93
+
94
+int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
95
+{
96
+	int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
97
+
98
+	/* unused parameters */
99
+	(void)dev_id;
100
+
101
+	/* SPI routine */
102
+	SPI_Start_Transmission(&BME_CSN_PORT, BME_CSN_PIN);
103
+	SPI_Transfer_Byte(reg_addr);
104
+
105
+	for (uint16_t i = 0; i < len; i ++)
106
+	{
107
+		SPI_Transfer_Byte(reg_data[i]);
108
+	}
109
+	SPI_Stop_Transmission(&BME_CSN_PORT, BME_CSN_PIN);
110
+
111
+	return rslt;
112
+}

+ 16
- 0
weather-sensor/firmware/bme280_interface.h Parādīt failu

@@ -0,0 +1,16 @@
1
+#ifndef BME280_H
2
+#define BME280_H
3
+
4
+#include <stdint.h>
5
+#include "bme280_defs.h"
6
+
7
+/* AVR I/O pin definionts */
8
+#define BME_CSN_DDR   DDRB
9
+#define BME_CSN_PORT  PORTB
10
+#define BME_CSN_PIN   PB2
11
+
12
+int8_t Initialize_BME280(void);
13
+void Set_BME280_Pins(void);
14
+void BME280_Get_Measurement(struct bme280_data * data);
15
+
16
+#endif

+ 2
- 0
weather-sensor/firmware/compile.sh Parādīt failu

@@ -0,0 +1,2 @@
1
+make main
2
+make main.hex

Binārs
weather-sensor/firmware/main Parādīt failu


+ 188
- 0
weather-sensor/firmware/main.c Parādīt failu

@@ -0,0 +1,188 @@
1
+#include <avr/io.h>
2
+#include <avr/interrupt.h>
3
+#include <avr/sleep.h>
4
+#include <util/delay.h>
5
+#include <stdint.h>
6
+#include <stdio.h>
7
+#include <stdlib.h>
8
+#include <string.h>
9
+
10
+#include "spi.h"
11
+#include "nrf24l01.h"
12
+#include "nrf24l01_definitions.h"
13
+#include "bme280_interface.h"
14
+#include "bme280_defs.h"
15
+
16
+
17
+
18
+/* Debug LED: */
19
+#define LED_DDR   DDRD
20
+#define LED_PORT  PORTD
21
+#define LED_PIN   PD3
22
+
23
+
24
+char bool_case = 0;
25
+int timer = 0;
26
+int timer_max = 0;
27
+
28
+volatile uint8_t cycle = 0;
29
+
30
+volatile uint8_t interruptCounter;
31
+volatile uint8_t executionFlag;
32
+
33
+
34
+void Enter_Power_Save_Mode(void);
35
+void Exit_Power_Save_Mode(void);
36
+
37
+
38
+/* TODO Notes for power saving:
39
+ * - Power-save-mode needed -> SM2...0 bits written to 011
40
+ * - Entering by issuing the SLEEP instruction -> What call in C?
41
+ *   - Before executing the SLEEP instruction, write bit SE of the SMCR to 1
42
+ * - Let Timer/Counter2 run with the necessary period and enable an interrupt.
43
+ *   -> The Global Interrupt Enable bit in SREG has to be set.
44
+ * - asynchronous/synchronous clock source?
45
+ * - When waking up
46
+ *   - Set PRR bits for needed peripherals
47
+ * - 
48
+ */
49
+void Set_Up_Power_Save_Mode(void);
50
+void Enter_Power_Save_Mode(void);
51
+
52
+
53
+ISR( TIMER2_COMPA_vect )
54
+{
55
+	/* Do nothing as the interrupt is only used to wake up the MCU. */
56
+}
57
+
58
+int main (void)
59
+{
60
+	struct bme280_data sensorData;
61
+//	uint8_t testRegisterContent = 0x0A;
62
+//	uint8_t registerContent[5];
63
+//	char registerContentString[30];
64
+//	uint8_t lengthRead;
65
+	uint8_t temp = 0;
66
+
67
+	/* Enable the debug LED */
68
+	LED_DDR |= (1 << LED_PIN);
69
+
70
+	/* Initialize the SPI */
71
+	Initialize_SPI();
72
+
73
+	/* Initialize the nrf24l01 */
74
+	Initialize_NRF24L01();
75
+	// The NRF24L01 is now in the mode Standby-I.
76
+
77
+	/* Configure the transmission parameters (Enhanced ShockBurst)*/
78
+	Configure_Transmission();
79
+
80
+	/* Initialize the BME280 */
81
+	Initialize_BME280();
82
+	Set_Up_Power_Save_Mode();
83
+
84
+
85
+	/* Delay the change of the operating frequency by the function Enter_Power_Save_Mode for the
86
+	 * first function pass. If it is changed before the ISP can flash the MCU the clocks of the ISP
87
+	 * and MCU are mismatched and the flashing will fail.
88
+	 */
89
+	_delay_ms(500);
90
+
91
+	while(1)
92
+	{
93
+		Enter_Power_Save_Mode(); // The MCU enters the Power Save Mode here.
94
+		Exit_Power_Save_Mode(); // The MCU exits the Power Save Mode here.
95
+
96
+		if (cycle == 0) // TODO cycle == 7 to execute this every 60 s
97
+		{
98
+			/* Re-Initialize the peripherals */
99
+			Set_BME280_Pins();
100
+			Set_NRF24L01_Pins();
101
+
102
+			/* Get measurement and send it */
103
+			BME280_Get_Measurement(&sensorData);
104
+			NRF24L01_Send_Message((uint8_t*)&sensorData, sizeof(sensorData));
105
+
106
+			if (temp == 0)
107
+			{
108
+				LED_PORT |= (1 << LED_PIN);
109
+				temp = 1;
110
+			}
111
+			else
112
+			{
113
+				temp = 0;
114
+				LED_PORT &= ~(1 << LED_PIN);
115
+			}
116
+
117
+			cycle = 0;
118
+		}
119
+		else
120
+		{
121
+			cycle ++;
122
+		}
123
+	}
124
+}
125
+
126
+void Set_Up_Power_Save_Mode(void)
127
+{
128
+	// Disable Brown-Out-Detection by setting the BODLEVEL 2:0 Fuses to 0b111 (should be default)
129
+	// Disable the on-chip debug system by setting the DWEN Fuse to 1 (should be default)
130
+
131
+	/* Disable some unused peripherals that are not used during operation of the weather station: */
132
+	// The ADC is turned off by default
133
+	ACSR &= ~(1<<ACD); // Analog comperator
134
+	ACSR &= ~(1<<ACIE); // The interrupt bit has to be cleared after switchin of the analog comperator
135
+	/*
136
+	 * The Internal voltager reference is automatically disabled if the BOD, ADC and Voltage
137
+	 * Reference are disabled
138
+	 */
139
+
140
+	/* Set up Timer/Counter2 */
141
+	PRR &= ~(1<<PRTIM2); // Enable the timer 2 in the Power Reduction Register
142
+
143
+	TCCR2A |= (1<<COM2A1)|(1<<COM2A0)|(1<<WGM21); // Set the timer to ClearTimer on Compare Match with output compare mode for channel A
144
+	/* There is a problem: The maximum time until the counter 2 overflows is 262ms at the nominal
145
+	 * core frquency of 1MHz and a timer prescaler of 1024.
146
+	 * This can be attenuated by lowering the system frequency to 31.25 kHz via the clock prescaler
147
+	 * (CLKPS3...0) of the register CLKPR. This gives a overflow time of 8.3s.
148
+	 * The cycle time of one minute can thus be accomplished by setting the output compare register
149
+	 * to 229. This spawns an interrupt every 7.5s which means the operation has to be executed
150
+	 * every 8 interrupt calls.
151
+	 */
152
+
153
+	TCCR2B |= (1<<CS22)|(1<<CS21)|(1<<CS20); // Set the timer prescaler to 1/1024
154
+	OCR2A = 229; // TODO: calculate this number from the wanted cycle time and the timer frequency.
155
+
156
+	TIMSK2 |= (1<<OCIE2A); // Enable the Output Compare Match A Interrupt.
157
+
158
+	/* Enable global interrupts: */
159
+	sei();
160
+}
161
+
162
+void Enter_Power_Save_Mode(void)
163
+{
164
+	PRR |= (1<<PRTWI) | (1<<PRTIM0) | (1<<PRTIM1) | (1<<PRSPI) | (1<<PRUSART0) | (1<<PRADC); /* Only timer 2 is needed for wake-up interrupt */
165
+
166
+	/* Set the clock prescaler for a frequency of 32.25 kHz*/
167
+	CLKPR = (1<<CLKPCE);
168
+	CLKPR = (1<<CLKPS3);
169
+
170
+	TCNT2 = 0;// Reset timer 2
171
+	TIMSK2 |= (1<<OCIE2A); // Enable the Output Compare Match A Interrupt.
172
+
173
+
174
+	set_sleep_mode(SLEEP_MODE_PWR_SAVE);
175
+	sleep_mode();
176
+}
177
+
178
+void Exit_Power_Save_Mode(void)
179
+{
180
+	TIMSK2 &= ~(1<<OCIE2A); // Disable the Output Compare Match A Interrupt.
181
+
182
+	/* Set the normal operating frequency of 1 MHz */
183
+	CLKPR = (1<<CLKPCE);
184
+	CLKPR = (1<<CLKPS1) | (1<<CLKPS0);
185
+
186
+	PRR &= ~(1<<PRSPI); // Enable SPI
187
+	Initialize_SPI(); // reinitalize SPI
188
+}

+ 0
- 200
weather-sensor/firmware/main.hex Parādīt failu

@@ -1,200 +0,0 @@
1
-:100000000C9456000C9473000C9473000C947300C1
2
-:100010000C9473000C9473000C9473000C94730094
3
-:100020000C9473000C9473000C9473000C94730084
4
-:100030000C9473000C9473000C9473000C94730074
5
-:100040000C9473000C9473000C9473000C94730064
6
-:100050000C9473000C9473000C9473000C94730054
7
-:100060000C9473000C9473000C9473000C94730044
8
-:100070000C9473000C9473000C9473000C94730034
9
-:100080000C9473000C9473000C9473000C94730024
10
-:100090000C9473000C9473000C9473000C94730014
11
-:1000A0000C9473000C9473000C94730011241FBE05
12
-:1000B000CFEFDAE0DEBFCDBF11E0A0E0B1E0E6E1D6
13
-:1000C000FCE002C005900D92AE34B107D9F721E0F3
14
-:1000D000AEE4B1E001C01D92A335B207E1F70E9482
15
-:1000E000C5020C9409060C94000086E084B980E5F2
16
-:1000F0008CBD08952D988FEF8EBD0DB407FEFDCFFA
17
-:100100002D9A8EB50895982F86EF890F823010F0C2
18
-:10011000903111F485E001C081E02D989EBD0DB4B1
19
-:1001200007FEFDCF262FFB011EBC0DB407FEFDCF41
20
-:100130009EB591939E2F921B9817B0F32D9A089518
21
-:100140009F92AF92BF92CF92DF92EF92FF920F9366
22
-:100150001F93CF93DF93CDB7DEB7C555D1090FB647
23
-:10016000F894DEBF0FBECDBF1A821982FE0133960E
24
-:1001700090E3DF011D929A95E9F77E01B1E5EB0E60
25
-:10018000F11CB7010E948300982E1BAA67018E0103
26
-:100190000D5C1F4F84E2A82E81E0B82E8C2D8E19A5
27
-:1001A000891598F4F60181916F011F928F931F9327
28
-:1001B0000F93BF92AF921F930F930E941F030FB62E
29
-:1001C000F894DEBF0FBECDBFE9CF1F930F9382E13E
30
-:1001D00091E09F938F938E010F5F1F4F1F930F939B
31
-:1001E0000E941F03C8010E94AB020F900F900F9056
32
-:1001F0000F900F900F90CB5ADF4F0FB6F894DEBFE1
33
-:100200000FBECDBFDF91CF911F910F91FF90EF9067
34
-:10021000DF90CF90BF90AF909F9008952D9880620F
35
-:100220008EBD0DB407FEFDCF6EBD0DB407FEFDCF34
36
-:100230002D9A0895249A259A2D9A2C988FEE95E55B
37
-:100240000197F1F700C000006AE080E00E940E0113
38
-:100250008FE99FE00197F1F700C0000008952D9805
39
-:1002600080E58EBD0DB407FEFDCF83E78EBD0DB4D6
40
-:1002700007FEFDCF2D9A08952D9890EA9EBD0DB4EE
41
-:1002800007FEFDCF262FFB019E2F921B981730F4FF
42
-:1002900091919EBD0DB407FEFDCFF6CF2D9A089526
43
-:1002A0004F925F926F927F928F929F92AF92BF9286
44
-:1002B000CF92DF92EF92FF920F931F93CF93DF9332
45
-:1002C000CDB7DEB7EB970FB6F894DEBF0FBECDBF4C
46
-:1002D0008091000190910101A0910201B091030170
47
-:1002E00088AF99AFAAAFBBAF1A821982FE013396CD
48
-:1002F00080E3DF011D928A95E9F7BE01685C7F4FBC
49
-:1003000084E00E943C012C9AB8E2BA95F1F72C984F
50
-:10031000412C512C32018CE2882E81E0982E02E192
51
-:1003200011E0CE0101967C0197E3C92E91E0D92E10
52
-:100330002EE3A22E21E0B22EAFECB7E01197F1F739
53
-:1003400000C00000BE016D5C7F4F87E00E9483000B
54
-:10035000823088F09F928F921F930F93FF92EF92BB
55
-:100360000E941F03C7010E94AB020F900F900F90D5
56
-:100370000F900F900F908BA985FF13C0DF92CF9243
57
-:100380001F930F93FF92EF920E941F03C7010E94D9
58
-:10039000AB020F900F900F900F900F900F9081E095
59
-:1003A00001C080E09BA994FF12C0BF92AF921F933F
60
-:1003B0000F93FF92EF920E941F03C7010E94AB02AE
61
-:1003C0000F900F900F900F900F900F9081E0BFEF64
62
-:1003D0004B1A5B0A6B0A7B0A811108C08FEF481623
63
-:1003E00051046104710409F0A7CF06C09FEF4916BC
64
-:1003F000510461047104C1F486E491E09F938F93EA
65
-:1004000082E191E09F938F938E010F5F1F4F1F93A7
66
-:100410000F930E941F03C8010E94AB020F900F9020
67
-:100420000F900F900F900F90BE016D5C7F4F87E093
68
-:100430000E9483006BA96F7087E00E940E01EB960B
69
-:100440000FB6F894DEBF0FBECDBFDF91CF911F91E5
70
-:100450000F91FF90EF90DF90CF90BF90AF909F9063
71
-:100460008F907F906F905F904F900895CF93DF9320
72
-:1004700000D000D0CDB7DEB769837A838B839C83AD
73
-:100480002D9880E38EBD0DB407FEFDCFFE013196A1
74
-:10049000CE01059621912EBD0DB407FEFDCFE817C4
75
-:1004A000F907C1F71EBC0DB407FEFDCF2D9A0F90C2
76
-:1004B0000F900F900F90DF91CF910895CF93DF931E
77
-:1004C00000D000D0CDB7DEB769837A838B839C835D
78
-:1004D0002D988AE28EBD0DB407FEFDCFFE01319648
79
-:1004E000CE01059621912EBD0DB407FEFDCFE81774
80
-:1004F000F907C1F71EBC0DB407FEFDCF2D9A0F9072
81
-:100500000F900F900F90DF91CF91089562E385E0F7
82
-:100510000E940E010E942F0164E08DE10E940E01F5
83
-:100520006FE38CE10E940E0166E574E382E190E0E6
84
-:100530000E94360266E574E382E190E00C945E026C
85
-:100540009093CD008093CC0088E18093C9008EE029
86
-:100550008093CA00089540E0242F30E0FC01019010
87
-:100560000020E9F73197E81BF90B2E173F0760F4DD
88
-:100570005091C80055FFFCCFFC01E20FF31F208112
89
-:100580002093CE004F5FE8CF0895CF93DF93CDB790
90
-:10059000DEB7E2970FB6F894DEBF0FBECDBF1A826A
91
-:1005A0001982FE01339680E3DF011D928A95E9F7F7
92
-:1005B00083E390E00E94A00284E091E09F938F93F8
93
-:1005C00082E191E09F938F938E010F5F1F4F1F93E6
94
-:1005D0000F930E941F03C8010E94AB020E94750086
95
-:1005E0000E941A010E9486020F900F900F900F90A8
96
-:1005F0000F900F9087E1C82E81E0D82E92E1E92E6E
97
-:1006000091E0F92E0E945001DF92CF92FF92EF927B
98
-:100610001F930F930E941F03C8010E94AB02BFEFFC
99
-:1006200029E688E1B15020408040E1F700C0000099
100
-:100630000F900F900F900F900F900F90E3CFAEE0C0
101
-:10064000B0E0E5E2F3E00C94E0050D891E8986E058
102
-:100650008C831A8309838FEF9FE79E838D83AE017E
103
-:10066000475E5F4F6F89788DCE0101960E944103EE
104
-:10067000EF81F885E00FF11F10822E96E4E00C94D4
105
-:10068000FC05ABE0B0E0E7E4F3E00C94D2056C01CC
106
-:100690007B018A01FC0117821682838181FFCCC114
107
-:1006A000CE0101963C01F6019381F70193FD8591FE
108
-:1006B00093FF81917F01882309F4BAC1853239F40F
109
-:1006C00093FD859193FF81917F01853229F4B601D5
110
-:1006D00090E00E943805E7CF912C212C312CFFE1CE
111
-:1006E000F315D8F08B3279F038F4803279F0833218
112
-:1006F000A1F4232D20611DC08D3261F0803369F497
113
-:10070000232D216016C0832D8260382EE32DE460F6
114
-:100710003E2E2AC0F32DF8601DC037FC2DC020ED01
115
-:10072000280F2A3040F08E32B9F436FC81C1232DD7
116
-:100730002064322E19C036FE06C08AE0989E200D35
117
-:100740001124922E11C0EAE02E9E200D1124222E9B
118
-:10075000F32DF0623F2E08C08C3621F4832D806883
119
-:10076000382E02C0883641F4F70193FD859193FF3E
120
-:1007700081917F018111B3CF982F9F7D9554933044
121
-:1007800028F40C5F1F4F9FE399830DC0833631F02F
122
-:10079000833771F0833509F059C021C0F801808199
123
-:1007A00089830E5F1F4F88248394912C530113C0BB
124
-:1007B0002801F2E04F0E511CF801A080B18036FEF6
125
-:1007C00003C0692D70E002C06FEF7FEFC5010E948A
126
-:1007D0002D054C018201F32DFF773F2E16C0280115
127
-:1007E00022E0420E511CF801A080B18036FE03C009
128
-:1007F000692D70E002C06FEF7FEFC5010E942205F6
129
-:100800004C01F32DF0683F2E820133FC1BC0822D7A
130
-:1008100090E088169906B0F4B60180E290E00E945C
131
-:1008200038052A94F4CFF50137FC859137FE819184
132
-:100830005F01B60190E00E94380521102A9421E062
133
-:10084000821A91088114910471F7E8C0843611F07E
134
-:10085000893641F5F80137FE07C0608171818281D8
135
-:1008600093810C5F1F4F08C060817181072E000CBF
136
-:10087000880B990B0E5F1F4FF32DFF763F2E97FFCE
137
-:1008800009C090958095709561957F4F8F4F9F4FD0
138
-:10089000F0683F2E2AE030E0A3010E947405882E04
139
-:1008A000861845C0853731F4232D2F7EB22E2AE0DD
140
-:1008B00030E025C0932D997FB92E8F36C1F018F402
141
-:1008C000883579F0B5C0803719F0883721F0B0C08D
142
-:1008D000E92FE061BE2EB4FE0DC0FB2DF460BF2EEB
143
-:1008E00009C034FE0AC0292F2660B22E06C028E0B7
144
-:1008F00030E005C020E130E002C020E132E0F80144
145
-:10090000B7FE07C060817181828193810C5F1F4FA8
146
-:1009100006C06081718180E090E00E5F1F4FA301EF
147
-:100920000E947405882E8618FB2DFF773F2E36FE19
148
-:100930000DC0232D2E7FA22E891458F434FE0BC037
149
-:1009400032FC09C0832D8E7EA82E05C0B82CA32CA6
150
-:1009500003C0B82C01C0B92CA4FE0FC0FE01E80DE5
151
-:10096000F11D8081803321F49A2D997EA92E09C032
152
-:10097000A2FE06C0B394B39404C08A2D867809F011
153
-:10098000B394A3FC11C0A0FE06C0B21488F4280CD6
154
-:10099000922C9B180EC0B21460F4B60180E290E075
155
-:1009A0000E943805B394F7CFB21418F42B1802C084
156
-:1009B000982C212CA4FE10C0B60180E390E00E9488
157
-:1009C0003805A2FE17C0A1FC03C088E790E002C072
158
-:1009D00088E590E0B6010CC08A2D867859F0A1FE1A
159
-:1009E00002C08BE201C080E2A7FC8DE2B60190E07C
160
-:1009F0000E943805891438F4B60180E390E00E9423
161
-:100A000038059A94F7CF8A94F301E80DF11D80819F
162
-:100A1000B60190E00E9438058110F5CF222009F43C
163
-:100A200042CEB60180E290E00E9438052A94F6CFCB
164
-:100A3000F6018681978102C08FEF9FEF2B96E2E14E
165
-:100A40000C94EE05FC010590615070400110D8F740
166
-:100A5000809590958E0F9F1F0895FC016150704006
167
-:100A600001900110D8F7809590958E0F9F1F0895E3
168
-:100A70000F931F93CF93DF93FB01238121FD03C0CD
169
-:100A80008FEF9FEF2CC022FF16C046815781248133
170
-:100A900035814217530744F4A081B1819D012F5F36
171
-:100AA0003F4F318320838C93268137812F5F3F4FC7
172
-:100AB0003783268314C08B01EC01FB010084F18590
173
-:100AC000E02D0995892BE1F6D80116968D919C9120
174
-:100AD0001797019617969C938E931697CE01DF91E8
175
-:100AE000CF911F910F910895FA01AA27283051F153
176
-:100AF000203181F1E8946F936E7F6E5F7F4F8F4F4F
177
-:100B00009F4FAF4FB1E03ED0B4E03CD0670F781FAD
178
-:100B1000891F9A1FA11D680F791F8A1F911DA11D92
179
-:100B20006A0F711D811D911DA11D20D009F46894CB
180
-:100B30003F912AE0269F11243019305D3193DEF673
181
-:100B4000CF010895462F4770405D4193B3E00FD029
182
-:100B5000C9F7F6CF462F4F70405D4A3318F0495D14
183
-:100B600031FD4052419302D0A9F7EACFB4E0A695F7
184
-:100B70009795879577956795BA95C9F70097610519
185
-:100B8000710508959B01AC010A2E0694579547956F
186
-:100B900037952795BA95C9F7620F731F841F951F64
187
-:100BA000A01D08952F923F924F925F926F927F9275
188
-:100BB0008F929F92AF92BF92CF92DF92EF92FF926D
189
-:100BC0000F931F93CF93DF93CDB7DEB7CA1BDB0B19
190
-:100BD0000FB6F894DEBF0FBECDBF09942A883988BE
191
-:100BE00048885F846E847D848C849B84AA84B984C5
192
-:100BF000C884DF80EE80FD800C811B81AA81B981D1
193
-:100C0000CE0FD11D0FB6F894DEBF0FBECDBFED01E4
194
-:060C10000895F894FFCFE7
195
-:100C1600DEADBEEF50726F6772616D2073746172E4
196
-:100C2600740025730D0A0074657374206D65737303
197
-:100C360061676500257330782578200072656164E8
198
-:100C4600206572726F720054582066696E006D617D
199
-:0E0C560078207265740074696D656F757400A6
200
-:00000001FF

+ 14
- 0
weather-sensor/firmware/makefile Parādīt failu

@@ -0,0 +1,14 @@
1
+all: main.hex
2
+
3
+clean:
4
+	rm -f main.hex
5
+	rm -f main
6
+
7
+flash: main.hex
8
+	sudo avrdude -c buspirate -b 115200 -P /dev/ttyUSB0 -p m88p -v -U flash:w:main.hex
9
+
10
+main: main.c spi.c spi.h nrf24l01.c nrf24l01.h nrf24l01_definitions.h bme280_interface.c bme280_interface.h BME280_driver/bme280.c BME280_driver/bme280.h
11
+	avr-gcc main.c spi.c nrf24l01.c bme280_interface.c BME280_driver/bme280.c -I BME280_driver -o main -mmcu=atmega88p -Os -Wall -Wextra -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -DF_CPU=1000000UL -D BME280_32BIT_ENABLE
12
+
13
+main.hex: main
14
+	avr-objcopy -O ihex -R .eeprom main main.hex

+ 342
- 0
weather-sensor/firmware/nrf24l01.c Parādīt failu

@@ -0,0 +1,342 @@
1
+#include <stdint.h>
2
+#include <avr/io.h>
3
+#include <util/delay.h>
4
+#include <stdio.h>
5
+#include <stdbool.h>
6
+
7
+#include "spi.h"
8
+#include "nrf24l01.h"
9
+#include "nrf24l01_definitions.h"
10
+
11
+/* TODO
12
+ * - Build a state machine that tracks the mode the NRF is set to
13
+ * - Configuration of NRF24L01 and startup
14
+ * - Send and Receive functions
15
+ * - Interrupt handling for Send and Receive
16
+ */
17
+
18
+void Print_Register_Contents(uint8_t address);
19
+void Send_TX_Flush_Command(void);
20
+
21
+/* Startup and initial configuration of the NRF24L01 */
22
+void Initialize_NRF24L01(void)
23
+{
24
+	CONFIG_REGISTER configRegisterContents = {.byte = 0x0};
25
+
26
+	/* Configure the AVR pins for the nrf24l01 */
27
+	Set_NRF24L01_Pins();
28
+
29
+	/* Wait more than 10.3 ms to make sure the nrf24l01 is running */
30
+	_delay_ms(11);
31
+
32
+	/* Write the PWR_UP bit of the CONFIG register (EN_CRC is also set) */
33
+	configRegisterContents.bits.EN_CRC = 0x1;
34
+	configRegisterContents.bits.PWR_UP = 0x1;
35
+	Write_NRF_Register(CONFIG_ADDRESS, configRegisterContents.byte);
36
+
37
+	/* Wait more than 1.5 ms for the change to take effect */
38
+	_delay_ms(2);
39
+
40
+	/* The NRF24L01 is now in the mode Standby-I */
41
+}
42
+
43
+void Set_NRF24L01_Pins(void)
44
+{
45
+	/* Set up the NRF24L01 */
46
+	NRF_CE_DDR |= (1 << NRF_CE_PIN);
47
+	NRF_CSN_DDR |= (1 << NRF_CSN_PIN);
48
+
49
+	/* Set the chip select pin to not selected */
50
+	NRF_CSN_PORT |= (1 << NRF_CSN_PIN);
51
+
52
+	/* Ensure that the CE pin is set to 0*/
53
+	NRF_CE_PORT &= ~(1 << NRF_CE_PIN);
54
+}
55
+
56
+void Configure_Transmission(void)
57
+{
58
+	FEATURE_REGISTER featureRegisterContents = {.byte = 0x0};
59
+	DYNPD_REGISTER dyndpRegisterContents = {.byte = 0x0};
60
+	SETUP_RETR_REGISTER setupRetrRegisterContents = {.byte = 0x0};
61
+	/* 
62
+	 * - Length of CRC (CRCO in CONFIG)
63
+	 * - Enable auto acknowledgment (EN_AA)
64
+	 *   -> Register already set correctly after reset
65
+	 * - Enable data pipes (EN_RXADDR)?
66
+	 *   -> Two pipes are already enabled on reset
67
+	 * - Set up address width (SETUP_AW)
68
+	 *   -> 3 bytes
69
+	 * - Automatic Retransmission (SETUP_RETR)
70
+	 *   -> ARD = 0b0000
71
+	 *   -> 3 retransmits -> ARC = 0b0011
72
+	 *   -> Register already set correctly after reset
73
+	 * - RF Channel (RF_CH)
74
+	 *   -> RF_CH = 0b1010000
75
+	 * - RF Setup (RF_SETUP)
76
+	 *   -> first use reset values, can be fine tuned later
77
+	 * - Enable dynamic payload length (DYNPD) -> command activate + 0x73, then set bits in FEATURE?
78
+	 */
79
+
80
+	/* Set the address width to 3 bytes */
81
+	//Write_NRF_Register(0x03, 0x1);
82
+
83
+	/* Set the frequency to 1450 MHz */
84
+	Write_NRF_Register(RF_CH_ADDRESS, 0x32);
85
+
86
+	/* Enable dynamic payload length */
87
+	Send_Activate_Command();
88
+	featureRegisterContents.bits.EN_DPL = 1; // enable dynamic payload length
89
+	Write_NRF_Register(FEATURE_ADDRESS, featureRegisterContents.byte);
90
+
91
+	/* */
92
+	setupRetrRegisterContents.bits.ARC = 0x3;
93
+	setupRetrRegisterContents.bits.ARD = 0xF;
94
+	Write_NRF_Register(SETUP_RETR_ADDRESS, setupRetrRegisterContents.byte);
95
+
96
+	/* set dynamic payload length for all data pipes */
97
+	dyndpRegisterContents.bits.DPL_P0 = 1;
98
+	dyndpRegisterContents.bits.DPL_P1 = 1;
99
+	dyndpRegisterContents.bits.DPL_P2 = 1;
100
+	dyndpRegisterContents.bits.DPL_P3 = 1;
101
+	dyndpRegisterContents.bits.DPL_P4 = 1;
102
+	dyndpRegisterContents.bits.DPL_P5 = 1;
103
+	Write_NRF_Register(DYNPD_ADDRESS, dyndpRegisterContents.byte);
104
+
105
+	/* Set the TX address */
106
+	Set_TX_Address(0x123456);
107
+
108
+	Set_RX_P0_Address(0x123456);
109
+	
110
+
111
+	// TODO: set addresses for all data pipes
112
+}
113
+
114
+void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length)
115
+{
116
+	bool transmissionFinished = false;
117
+
118
+	STATUS_REGISTER statusRegisterContents = {.byte = 0x0};
119
+	uint32_t timeout = 0;
120
+	/* TODO:
121
+	 * - if needed: PRIM_RX = 0
122
+	 * - Set CE = 1 for more than 10 us
123
+	 * - Wait until the transmission is finished
124
+	 * - Read number of retries for debug purposes
125
+	 * - Check if the FIFO is empty -> if not, flush it
126
+	 * - reset the interupts of the STATUS
127
+	 */
128
+	
129
+	/* TODO: messages with more than 32 byte length */
130
+	if ((length > 32) || (length == 0))
131
+	{
132
+		return;
133
+	}
134
+
135
+	Write_Message_To_TX_FIFO(length, buffer);
136
+
137
+	/* Set CE = 1 for more than 10 us */
138
+	NRF_CE_PORT |= (1 << NRF_CE_PIN);
139
+	_delay_us(15);
140
+	NRF_CE_PORT &= ~(1 << NRF_CE_PIN);
141
+
142
+
143
+	do
144
+	{
145
+		_delay_ms(1);
146
+		/* TODO: instead of polling the status register use the IRQ to spawn an interrupt as the
147
+		 * constant polling may induce transmission errors:
148
+		 * https://forum.mysensors.org/topic/10452/nrf24l01-communication-failure-root-cause-and-solution
149
+		 */
150
+		statusRegisterContents.byte = Read_NRF_Status_Register();
151
+
152
+		if (statusRegisterContents.bits.TX_DS == 1)
153
+		{
154
+			transmissionFinished = true;
155
+		}
156
+
157
+		if (statusRegisterContents.bits.MAX_RT == 1)
158
+		{
159
+			transmissionFinished = true; //TODO: indicate failure
160
+
161
+			Send_TX_Flush_Command(); /* Remove the packet from the TX FIFO as it is not done automatically */
162
+		}
163
+		
164
+		timeout ++; // TODO: this should work without the time out, as MAX_RT should be triggered if no ACK is received
165
+	} while ((transmissionFinished == false) && (timeout < 0xFF));
166
+
167
+	/* Reset the interrupts */
168
+	statusRegisterContents.byte = Read_NRF_Status_Register();
169
+	statusRegisterContents.bits.TX_DS = 1;
170
+	statusRegisterContents.bits.MAX_RT = 1;
171
+	Write_NRF_Register(STATUS_ADDRESS, statusRegisterContents.byte);
172
+}
173
+
174
+void Print_Register_Contents(uint8_t address)
175
+{
176
+	uint8_t registerContent[5];
177
+	uint8_t lengthRead;
178
+	char registerContentString[30];
179
+
180
+
181
+	lengthRead = Read_NRF_Register(address, registerContent);
182
+
183
+	registerContentString[0] = '\0';
184
+	for (uint8_t i = 0; i < lengthRead; i++)
185
+	{
186
+		sprintf(registerContentString, "%s0x%x ", registerContentString, registerContent[i]);
187
+	}
188
+}
189
+
190
+
191
+
192
+
193
+/* Send a message:
194
+ * - Set PRIM_RX = 0 and add one message to the TX-FIFO
195
+ * - Set CE=1 for more than 10 us
196
+ * - The NRF takes 130 us to enter the TX Mode
197
+ * - An Interrupt is generated once the 
198
+ * - 
199
+ */
200
+
201
+
202
+/* Set the NRF to RX Mode */
203
+
204
+/* Disable the RX Mode */
205
+
206
+
207
+
208
+
209
+uint8_t Read_NRF_Status_Register(void)
210
+{
211
+	uint8_t registerContents;
212
+
213
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
214
+	registerContents = SPI_Transfer_Byte(0x00);
215
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
216
+	return registerContents;
217
+}
218
+
219
+uint8_t Read_NRF_Register(uint8_t address, uint8_t * registerContents)
220
+{
221
+	/* TODO: simplify this function, as the registers with more than one byte are accessed with other functions */
222
+	uint8_t numberOfBytes = 0;
223
+
224
+	if ((address == 0x0A) ||
225
+	    (address == 0x0B) ||
226
+	    (address == 0x10))
227
+	{
228
+		numberOfBytes = 5;
229
+	}
230
+	else
231
+	{
232
+		numberOfBytes = 1;
233
+	}
234
+
235
+	/* First write the address */
236
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
237
+
238
+
239
+	SPI_Transfer_Byte(address);
240
+
241
+	/* Read the register bytes */
242
+	for (uint8_t i = 0; i < numberOfBytes; i++)
243
+	{
244
+		/* Write dummy data to shift in the register content */
245
+		registerContents[i] = SPI_Transfer_Byte(0x0);
246
+	}
247
+
248
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
249
+
250
+	return numberOfBytes;
251
+}
252
+
253
+void Write_NRF_Register(uint8_t address, uint8_t registerContents)
254
+{
255
+	/* First write the write command with the address */
256
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
257
+
258
+	SPI_Transfer_Byte(address | 0x20);
259
+
260
+	/* Write the data byte */
261
+	SPI_Transfer_Byte(registerContents);
262
+
263
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
264
+}
265
+
266
+// TODO: clean up functions
267
+void Send_Activate_Command(void)
268
+{
269
+	/* First write the write command with the address */
270
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
271
+	SPI_Transfer_Byte(0x50);
272
+
273
+	/* Write the data byte */
274
+	SPI_Transfer_Byte(0x73);
275
+
276
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
277
+}
278
+
279
+void Send_TX_Flush_Command(void)
280
+{
281
+	/* First write the write command with the address */
282
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
283
+
284
+	SPI_Transfer_Byte(0xE1);
285
+
286
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
287
+}
288
+
289
+
290
+
291
+void Write_Message_To_TX_FIFO(uint8_t length, uint8_t * buffer)
292
+{
293
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
294
+
295
+	/* Issue the write command: */
296
+	SPI_Transfer_Byte(0xA0);
297
+
298
+	/* Write the data bytes */
299
+	for (uint8_t i = 0; i < length; i++)
300
+	{
301
+		SPI_Transfer_Byte(buffer[i]);
302
+	}
303
+
304
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
305
+}
306
+
307
+void Set_TX_Address(uint32_t txAddress)
308
+{
309
+	uint8_t * buffer = (uint8_t*) &txAddress;
310
+
311
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
312
+
313
+	SPI_Transfer_Byte(TX_ADDR_ADDRESS | 0x20);
314
+	/* Write the data byte */
315
+	for (uint8_t i = 0; i < 4; i ++)
316
+	{
317
+		SPI_Transfer_Byte(buffer[i]);
318
+	}
319
+	SPI_Transfer_Byte(0x0);
320
+
321
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
322
+}
323
+
324
+void Set_RX_P0_Address(uint32_t rxAddress)
325
+{
326
+	uint8_t * buffer = (uint8_t*) &rxAddress;
327
+
328
+	SPI_Start_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
329
+
330
+	SPI_Transfer_Byte(RX_ADDR_P0_ADDRESS | 0x20);
331
+
332
+	/* Write the data byte */
333
+	for (uint8_t i = 0; i < 4; i ++)
334
+	{
335
+		SPI_Transfer_Byte(buffer[i]);
336
+	}
337
+	SPI_Transfer_Byte(0x0);
338
+
339
+	SPI_Stop_Transmission(&NRF_CSN_PORT, NRF_CSN_PIN);
340
+}
341
+
342
+//TODO: only write the used bytes into the address registers & add generic write functions

+ 32
- 0
weather-sensor/firmware/nrf24l01.h Parādīt failu

@@ -0,0 +1,32 @@
1
+#ifndef NRF24L01_H
2
+#define NRF24L01_H
3
+
4
+
5
+
6
+/* AVR I/O pin definionts */
7
+#define NRF_CE_DDR   DDRD
8
+#define NRF_CE_PORT  PORTD
9
+#define NRF_CE_PIN   PD7
10
+
11
+#define NRF_CSN_DDR   DDRD
12
+#define NRF_CSN_PORT  PORTD
13
+#define NRF_CSN_PIN   PD6
14
+
15
+#define NRF_IRQ_DDR   DDRD
16
+#define NRF_IRQ_PORT  PORTD
17
+#define NRF_IRQ_PIN   PD5
18
+
19
+void Initialize_NRF24L01(void);
20
+void Set_NRF24L01_Pins(void);
21
+void Configure_Transmission(void);
22
+uint8_t Read_NRF_Status_Register(void);
23
+uint8_t Read_NRF_Register(uint8_t address, uint8_t * registerContents);
24
+void Write_NRF_Register(uint8_t address, uint8_t registerContents);
25
+void Send_Activate_Command(void);
26
+
27
+void NRF24L01_Send_Message(uint8_t *buffer, uint8_t length);
28
+void Write_Message_To_TX_FIFO(uint8_t length, uint8_t * buffer);
29
+void Set_TX_Address(uint32_t txAddress);
30
+void Set_RX_P0_Address(uint32_t rxAddress);
31
+
32
+#endif

+ 220
- 61
weather-sensor/firmware/nrf24l01_definitions.h Parādīt failu

@@ -3,32 +3,32 @@
3 3
 
4 4
 
5 5
 /* NRF24L01 register mnemonic definitions */
6
-#define CONFIG 0x0
7
-#define EN_AA 0x1
8
-#define EN_RXADDR 0x2
9
-#define SETUP_AW 0x3
10
-#define SETUP_RETR 0x4
11
-#define RF_CH 0x5
12
-#define RF_SETUP 0x6
13
-#define STATUS 0x7
14
-#define OBSERVE_TX 0x8
15
-#define CD 0x9
16
-#define RX_ADDR_P0 0xA
17
-#define RX_ADDR_P1 0xB
18
-#define RX_ADDR_P2 0xC
19
-#define RX_ADDR_P3 0xD
20
-#define RX_ADDR_P4 0xE
21
-#define RX_ADDR_P5 0xF
22
-#define TX_ADDR 0x10
23
-#define RX_PW_P0 0x11
24
-#define RX_PW_P1 0x12
25
-#define RX_PW_P2 0x13
26
-#define RX_PW_P3 0x14
27
-#define RX_PW_P4 0x15
28
-#define RX_PW_P5 0x16
29
-#define FIFO_STATUS 0x17
30
-#define DYNPD 0x1C
31
-#define FEATURE 0x1D
6
+#define CONFIG_ADDRESS 0x0
7
+#define EN_AA_ADDRESS 0x1
8
+#define EN_RXADDR_ADDRESS 0x2
9
+#define SETUP_AW_ADDRESS 0x3
10
+#define SETUP_RETR_ADDRESS 0x4
11
+#define RF_CH_ADDRESS 0x5
12
+#define RF_SETUP_ADDRESS 0x6
13
+#define STATUS_ADDRESS 0x7
14
+#define OBSERVE_TX_ADDRESS 0x8
15
+#define CD_ADDRESS 0x9
16
+#define RX_ADDR_P0_ADDRESS 0xA
17
+#define RX_ADDR_P1_ADDRESS 0xB
18
+#define RX_ADDR_P2_ADDRESS 0xC
19
+#define RX_ADDR_P3_ADDRESS 0xD
20
+#define RX_ADDR_P4_ADDRESS 0xE
21
+#define RX_ADDR_P5_ADDRESS 0xF
22
+#define TX_ADDR_ADDRESS 0x10
23
+#define RX_PW_P0_ADDRESS 0x11
24
+#define RX_PW_P1_ADDRESS 0x12
25
+#define RX_PW_P2_ADDRESS 0x13
26
+#define RX_PW_P3_ADDRESS 0x14
27
+#define RX_PW_P4_ADDRESS 0x15
28
+#define RX_PW_P5_ADDRESS 0x16
29
+#define FIFO_STATUS_ADDRESS 0x17
30
+#define DYNPD_ADDRESS 0x1C
31
+#define FEATURE_ADDRESS 0x1D
32 32
 
33 33
 /* Register bits definitions */
34 34
 /* CONFIG*/
@@ -37,46 +37,205 @@ typedef union
37 37
 	uint8_t byte;
38 38
 	struct
39 39
 	{
40
-		 uint8_t bit012 : 3;
41
-		 uint8_t bit34 : 2;
42
-		 uint8_t bit5 : 1;
43
-		 uint8_t bit6 : 1;
44
-		 uint8_t bit7 : 1;
40
+		uint8_t PRIM_RX     : 1;
41
+		uint8_t PWR_UP      : 1;
42
+		uint8_t CRCO        : 1;
43
+		uint8_t EN_CRC      : 1;
44
+		uint8_t MASK_MAX_RT : 1;
45
+		uint8_t MASK_TX_DS  : 1;
46
+		uint8_t MASK_RX_DR  : 1;
47
+		uint8_t RESERVED    : 1;
45 48
 	}bits;
46 49
 }CONFIG_REGISTER;
47 50
 
48
-#define MASK_RX_DR (1<<6)
49
-#define MASK_TX_DS (1<<5)
50
-#define MASK_MAX_RT (1<<4)
51
-#define EN_CRC (1<<3)
52
-#define CRCO (1<<2)
53
-#define PWR_UP (1<<1)
54
-#define PRIM_RX (1<<0)
55
-
56 51
 /*EN_AA */
57
-#define ENAA_P5 (1<<5)
58
-#define ENAA_P4 (1<<4)
59
-#define ENAA_P3 (1<<3)
60
-#define ENAA_P2 (1<<2)
61
-#define ENAA_P1 (1<<1)
62
-#define ENAA_P0 (1<<0)
52
+typedef union
53
+{
54
+	uint8_t byte;
55
+	struct
56
+	{
57
+		uint8_t ENAA_P0  : 1;
58
+		uint8_t ENAA_P1  : 1;
59
+		uint8_t ENAA_P2  : 1;
60
+		uint8_t ENAA_P3  : 1;
61
+		uint8_t ENAA_P4  : 1;
62
+		uint8_t ENAA_P5  : 1;
63
+		uint8_t RESERVED : 2;
64
+	}bits;
65
+}EN_AA_REGISTER;
63 66
 
64 67
 /* EN_RXADDR */
65
-#define ERX_P5 (1<<5)
66
-#define ERX_P4 (1<<4)
67
-#define ERX_P3 (1<<3)
68
-#define ERX_P2 (1<<2)
69
-#define ERX_P1 (1<<1)
70
-#define ERX_P0 (1<<0)
71
-
72
-
73
-#define  (1<<)
74
-#define  (1<<)
75
-#define  (1<<)
76
-#define  (1<<)
77
-#define  (1<<)
78
-#define  (1<<)
79
-#define  (1<<)
80
-#define  (1<<)
68
+typedef union
69
+{
70
+	uint8_t byte;
71
+	struct
72
+	{
73
+		uint8_t ERX_P0   : 1;
74
+		uint8_t ERX_P1   : 1;
75
+		uint8_t ERX_P2   : 1;
76
+		uint8_t ERX_P3   : 1;
77
+		uint8_t ERX_P4   : 1;
78
+		uint8_t ERX_P5   : 1;
79
+		uint8_t RESERVED : 2;
80
+	}bits;
81
+}EN_RXADDR_REGISTER;
82
+
83
+/* SETUP_AW */
84
+typedef union
85
+{
86
+	uint8_t byte;
87
+	struct
88
+	{
89
+		 uint8_t AW : 2;
90
+		 uint8_t RESERVED : 6;
91
+	}bits;
92
+}SETUP_AW_REGISTER;
93
+
94
+#define ADDRESS_WIDTH_3_BYTES 0x1
95
+#define ADDRESS_WIDTH_4_BYTES 0x2
96
+#define ADDRESS_WIDTH_5_BYTES 0x3
97
+
98
+/* SETUP_RETR */
99
+typedef union
100
+{
101
+	uint8_t byte;
102
+	struct
103
+	{
104
+		 uint8_t ARC : 4;
105
+		 uint8_t ARD : 4;
106
+	}bits;
107
+}SETUP_RETR_REGISTER;
108
+
109
+/* RF_CH */
110
+typedef union
111
+{
112
+	uint8_t byte;
113
+	struct
114
+	{
115
+		 uint8_t RF_CH : 7;
116
+		 uint8_t RESERVED : 1;
117
+	}bits;
118
+}RF_CH_REGISTER;
119
+
120
+/* RF_SETUP */
121
+typedef union
122
+{
123
+	uint8_t byte;
124
+	struct
125
+	{
126
+		 uint8_t LNA_HCURR : 1;
127
+		 uint8_t RF_PWR    : 2;
128
+		 uint8_t RF_DR     : 1;
129
+		 uint8_t PLL_LOCK  : 1;
130
+		 uint8_t RESERVED  : 3;
131
+	}bits;
132
+}RF_SETUP_REGISTER;
133
+
134
+#define RF_DATA_RATE_1MBPS 0x0
135
+#define RF_DATA_RATE_2MBPS 0x1
136
+
137
+#define RF_OUTPUT_POWER_MINUS_18DBM
138
+#define RF_OUTPUT_POWER_MINUS_12DBM
139
+#define RF_OUTPUT_POWER_MINUS_16DBM
140
+#define RF_OUTPUT_POWER_0DBM
141
+
142
+// TODO: change order of all bit fields!!!
143
+
144
+/* STATUS */
145
+typedef union
146
+{
147
+	uint8_t byte;
148
+	struct
149
+	{
150
+		 uint8_t TX_FULL  : 1;
151
+		 uint8_t RX_P_NO  : 3;
152
+		 uint8_t MAX_RT   : 1;
153
+		 uint8_t TX_DS    : 1;
154
+		 uint8_t RX_DR    : 1;
155
+		 uint8_t RESERVED : 1;
156
+	}bits;
157
+}STATUS_REGISTER;
158
+
159
+#define RX_FIFO_EMPTY 0x7
160
+
161
+/* OBSERVE_TX */
162
+typedef union
163
+{
164
+	uint8_t byte;
165
+	struct
166
+	{
167
+		 uint8_t ARC_CNT  : 4;
168
+		 uint8_t PLOS_CNT : 4;
169
+	}bits;
170
+}OBSERVE_TX_REGISTER;
171
+
172
+/* CD */
173
+typedef union
174
+{
175
+	uint8_t byte;
176
+	struct
177
+	{
178
+		 uint8_t CD : 1;
179
+		 uint8_t RESERVED : 7;
180
+	}bits;
181
+}CD_REGISTER;
182
+
183
+/* RX_PW_Pn */
184
+typedef union
185
+{
186
+	uint8_t byte;
187
+	struct
188
+	{
189
+		 uint8_t RESERVED : 2;
190
+		 uint8_t RX_PW_Pn : 6;
191
+	}bits;
192
+}RX_PW_Pn_REGISTER;
193
+
194
+/* FIFO_STATUS */
195
+typedef union
196
+{
197
+	uint8_t byte;
198
+	struct
199
+	{
200
+		 uint8_t RX_EMPTY : 1;
201
+		 uint8_t RX_FULL  : 1;
202
+		 uint8_t RESERVED1 : 2;
203
+		 uint8_t TX_EMPTY : 1;
204
+		 uint8_t TX_FULL  : 1;
205
+		 uint8_t TX_REUSE : 1;
206
+		 uint8_t RESERVED0 : 1;
207
+	}bits;
208
+}FIFO_STATUS_REGISTER;
209
+
210
+/* DYNPD */
211
+typedef union
212
+{
213
+	uint8_t byte;
214
+	struct
215
+	{
216
+		 uint8_t DPL_P0   : 1;
217
+		 uint8_t DPL_P1   : 1;
218
+		 uint8_t DPL_P2   : 1;
219
+		 uint8_t DPL_P3   : 1;
220
+		 uint8_t DPL_P4   : 1;
221
+		 uint8_t DPL_P5   : 1;
222
+		 uint8_t RESERVED : 2;
223
+	}bits;
224
+}DYNPD_REGISTER;
225
+
226
+/* FEATURE */
227
+typedef union
228
+{
229
+	uint8_t byte;
230
+	struct
231
+	{
232
+		 uint8_t EN_DYN_ACK : 1;
233
+		 uint8_t EN_ACK_PAY : 1;
234
+		 uint8_t EN_DPL     : 1;
235
+		 uint8_t RESERVED   : 5;
236
+	}bits;
237
+}FEATURE_REGISTER;
81 238
 
82 239
 #endif
240
+
241
+

+ 33
- 0
weather-sensor/firmware/spi.c Parādīt failu

@@ -0,0 +1,33 @@
1
+#include <avr/io.h>
2
+
3
+/* Pin Definitions: */
4
+#define SPI_DDR       DDRB
5
+#define SPI_SCK_PIN   PB5
6
+#define SPI_MOSI_PIN  PB3
7
+#define SPI_MISO_PIN  PB4
8
+
9
+
10
+void Initialize_SPI(void)
11
+{
12
+	/* Set MOSI and SCK output, all others input */
13
+	SPI_DDR = (1<<SPI_MOSI_PIN)|(1<<SPI_SCK_PIN);
14
+	/* Enable SPI, Master, set clock rate fck/16 */
15
+	SPCR = (1<<SPE)|(1<<MSTR);
16
+}
17
+
18
+void SPI_Start_Transmission(volatile uint8_t *port, uint8_t pinNumber)
19
+{
20
+	*port &= ~(1<<pinNumber);
21
+}
22
+
23
+uint8_t SPI_Transfer_Byte(uint8_t byteToSend)
24
+{
25
+	SPDR = byteToSend;
26
+	while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
27
+	return SPDR;
28
+}
29
+
30
+void SPI_Stop_Transmission(volatile uint8_t *port, uint8_t pinNumber)
31
+{
32
+	*port |= (1<<pinNumber);
33
+}

+ 9
- 0
weather-sensor/firmware/spi.h Parādīt failu

@@ -0,0 +1,9 @@
1
+#ifndef SPI_H
2
+#define SPI_H
3
+
4
+void Initialize_SPI(void);
5
+void SPI_Start_Transmission(volatile uint8_t *port, uint8_t pinNumber);
6
+uint8_t SPI_Transfer_Byte(uint8_t byte);
7
+void SPI_Stop_Transmission(volatile uint8_t *port, uint8_t pinNumber);
8
+
9
+#endif

Notiek ielāde…
Atcelt
Saglabāt