21 コミット

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

+ 3
- 0
.gitmodules ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

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

バイナリ
weather-sensor/firmware/main ファイルの表示


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

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

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

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