Преглед изворни кода

untested BH1750 i2c lux sensor implementation

Thomas B пре 3 месеци
родитељ
комит
4577f98b5d
12 измењених фајлова са 566 додато и 96 уклоњено
  1. 3
    1
      README.md
  2. 0
    7
      client/fetch.py
  3. 4
    2
      sensor/Makefile
  4. 255
    0
      sensor/extern/USI_TWI_Master.c
  5. 162
    0
      sensor/extern/USI_TWI_Master.h
  6. 6
    7
      sensor/include/lux.h
  7. 28
    0
      sensor/include/twi.h
  8. 0
    66
      sensor/src/adc.c
  9. 45
    0
      sensor/src/lux.c
  10. 12
    4
      sensor/src/main.c
  11. 48
    0
      sensor/src/twi.c
  12. 3
    9
      sensor/src/usb.c

+ 3
- 1
README.md Прегледај датотеку

@@ -7,7 +7,9 @@
7 7
 The firmware of this project is licensed as GPLv3.
8 8
 A copy of the license can be found in `COPYING`.
9 9
 
10
-It uses [V-USB](https://github.com/obdev/v-usb), and is based on their example code.
10
+It uses [V-USB](https://github.com/obdev/v-usb) and is based on their example code.
11
+
12
+Also includes the I2C Master implementation from the Atmel AVR310 AppNote.
11 13
 
12 14
     This program is free software: you can redistribute it and/or modify
13 15
     it under the terms of the GNU General Public License as published by

+ 0
- 7
client/fetch.py Прегледај датотеку

@@ -7,7 +7,6 @@ import time
7 7
 CUSTOM_RQ_ECHO = 0 # send back wValue and wIndex, for testing comms reliability
8 8
 CUSTOM_RQ_RESET = 1 # reset to bootloader
9 9
 CUSTOM_RQ_GET = 2 # get ldr value
10
-CUSTOM_RQ_RAW = 3 # get ldr value
11 10
 
12 11
 max_comm_retries = 5;
13 12
 
@@ -43,10 +42,4 @@ if read_val(CUSTOM_RQ_ECHO, 4, 42, 23) != (42 | (23 << 16)):
43 42
 while True:
44 43
     v = read_val(CUSTOM_RQ_GET, 2)
45 44
     print(time.time(), ";", v, flush=True)
46
-
47
-    #r = read_val(CUSTOM_RQ_RAW, 2)
48
-    #print(time.time(), ";", r, flush=True)
49
-
50
-    #print(time.time(), ";", v, ";", r, flush=True)
51
-
52 45
     time.sleep(0.25)

+ 4
- 2
sensor/Makefile Прегледај датотеку

@@ -80,7 +80,8 @@ OBJDIR = build
80 80
 
81 81
 # List C source files here. (C dependencies are automatically generated.)
82 82
 SRC = v-usb/usbdrv/usbdrv.c v-usb/usbdrv/oddebug.c
83
-SRC += src/main.c src/adc.c src/usb.c
83
+SRC += extern/USI_TWI_Master.c
84
+SRC += src/main.c src/lux.c src/twi.c src/usb.c
84 85
 
85 86
 
86 87
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -114,7 +115,7 @@ DEBUG = dwarf-2
114 115
 #     Each directory must be seperated by a space.
115 116
 #     Use forward slashes for directory separators.
116 117
 #     For a directory that has spaces, enclose it in quotes.
117
-EXTRAINCDIRS = include v-usb/usbdrv v-usb/libs-device
118
+EXTRAINCDIRS = include extern v-usb/usbdrv v-usb/libs-device
118 119
 
119 120
 
120 121
 # Compiler flag to set the C Standard level.
@@ -613,6 +614,7 @@ clean_list :
613 614
 # Create object files directory
614 615
 $(shell mkdir -p $(OBJDIR) 2>/dev/null)
615 616
 $(shell mkdir -p $(OBJDIR)/src 2>/dev/null) # TODO not nice
617
+$(shell mkdir -p $(OBJDIR)/extern 2>/dev/null) # TODO not nice
616 618
 $(shell mkdir -p $(OBJDIR)/v-usb/usbdrv 2>/dev/null) # TODO not nice
617 619
 
618 620
 

+ 255
- 0
sensor/extern/USI_TWI_Master.c Прегледај датотеку

@@ -0,0 +1,255 @@
1
+/*****************************************************************************
2
+ *
3
+ * Atmel Corporation
4
+ *
5
+ * File              : USI_TWI_Master.c
6
+ * Date              : $Date: 2016-7-15 $
7
+ * Updated by        : $Author: Atmel $
8
+ *
9
+ * Support mail      : avr@atmel.com
10
+ *
11
+ * Supported devices : All device with USI module can be used.
12
+ *                     The example is written for the ATmega169, ATtiny26 and ATtiny2313
13
+ *
14
+ * AppNote           : AVR310 - Using the USI module as a TWI Master
15
+ *
16
+ * Description       : This is an implementation of an TWI master using
17
+ *                     the USI module as basis. The implementation assumes the AVR to
18
+ *                     be the only TWI master in the system and can therefore not be
19
+ *                     used in a multi-master system.
20
+ * Usage             : Initialize the USI module by calling the USI_TWI_Master_Initialise()
21
+ *                     function. Hence messages/data are transceived on the bus using
22
+ *                     the USI_TWI_Transceive() function. The transceive function
23
+ *                     returns a status byte, which can be used to evaluate the
24
+ *                     success of the transmission.
25
+ *
26
+ ****************************************************************************/
27
+#if __GNUC__
28
+#include <avr/io.h>
29
+#else
30
+#include <inavr.h>
31
+#include <ioavr.h>
32
+#endif
33
+#include "USI_TWI_Master.h"
34
+
35
+unsigned char USI_TWI_Master_Transfer(unsigned char);
36
+unsigned char USI_TWI_Master_Stop(void);
37
+
38
+union USI_TWI_state {
39
+	unsigned char errorState; // Can reuse the TWI_state for error states due to that it will not be need if there
40
+	                          // exists an error.
41
+	struct {
42
+		unsigned char addressMode : 1;
43
+		unsigned char masterWriteDataMode : 1;
44
+		unsigned char unused : 6;
45
+	};
46
+} USI_TWI_state;
47
+
48
+/*---------------------------------------------------------------
49
+ USI TWI single master initialization function
50
+---------------------------------------------------------------*/
51
+void USI_TWI_Master_Initialise(void)
52
+{
53
+	PORT_USI |= (1 << PIN_USI_SDA); // Enable pullup on SDA, to set high as released state.
54
+	PORT_USI |= (1 << PIN_USI_SCL); // Enable pullup on SCL, to set high as released state.
55
+
56
+	DDR_USI |= (1 << PIN_USI_SCL); // Enable SCL as output.
57
+	DDR_USI |= (1 << PIN_USI_SDA); // Enable SDA as output.
58
+
59
+	USIDR = 0xFF;                                           // Preload dataregister with "released level" data.
60
+	USICR = (0 << USISIE) | (0 << USIOIE) |                 // Disable Interrupts.
61
+	        (1 << USIWM1) | (0 << USIWM0) |                 // Set USI in Two-wire mode.
62
+	        (1 << USICS1) | (0 << USICS0) | (1 << USICLK) | // Software stobe as counter clock source
63
+	        (0 << USITC);
64
+	USISR = (1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) | // Clear flags,
65
+	        (0x0 << USICNT0);                                             // and reset counter.
66
+}
67
+
68
+/*---------------------------------------------------------------
69
+Use this function to get hold of the error message from the last transmission
70
+---------------------------------------------------------------*/
71
+unsigned char USI_TWI_Get_State_Info(void)
72
+{
73
+	return (USI_TWI_state.errorState); // Return error state.
74
+}
75
+
76
+/*---------------------------------------------------------------
77
+ USI Transmit and receive function. LSB of first byte in data
78
+ indicates if a read or write cycles is performed. If set a read
79
+ operation is performed.
80
+
81
+ Function generates (Repeated) Start Condition, sends address and
82
+ R/W, Reads/Writes Data, and verifies/sends ACK.
83
+
84
+ Success or error code is returned. Error codes are defined in
85
+ USI_TWI_Master.h
86
+---------------------------------------------------------------*/
87
+#ifndef __GNUC__
88
+__x // AVR compiler
89
+#endif
90
+    unsigned char
91
+    USI_TWI_Start_Transceiver_With_Data(unsigned char *msg, unsigned char msgSize)
92
+{
93
+	unsigned char tempUSISR_8bit = (1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC)
94
+	                               |                 // Prepare register value to: Clear flags, and
95
+	                               (0x0 << USICNT0); // set USI to shift 8 bits i.e. count 16 clock edges.
96
+	unsigned char tempUSISR_1bit = (1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC)
97
+	                               |                 // Prepare register value to: Clear flags, and
98
+	                               (0xE << USICNT0); // set USI to shift 1 bit i.e. count 2 clock edges.
99
+
100
+	USI_TWI_state.errorState  = 0;
101
+	USI_TWI_state.addressMode = TRUE;
102
+
103
+#ifdef PARAM_VERIFICATION
104
+	if (msg > (unsigned char *)RAMEND) // Test if address is outside SRAM space
105
+	{
106
+		USI_TWI_state.errorState = USI_TWI_DATA_OUT_OF_BOUND;
107
+		return (FALSE);
108
+	}
109
+	if (msgSize <= 1) // Test if the transmission buffer is empty
110
+	{
111
+		USI_TWI_state.errorState = USI_TWI_NO_DATA;
112
+		return (FALSE);
113
+	}
114
+#endif
115
+
116
+#ifdef NOISE_TESTING // Test if any unexpected conditions have arrived prior to this execution.
117
+	if (USISR & (1 << USISIF)) {
118
+		USI_TWI_state.errorState = USI_TWI_UE_START_CON;
119
+		return (FALSE);
120
+	}
121
+	if (USISR & (1 << USIPF)) {
122
+		USI_TWI_state.errorState = USI_TWI_UE_STOP_CON;
123
+		return (FALSE);
124
+	}
125
+	if (USISR & (1 << USIDC)) {
126
+		USI_TWI_state.errorState = USI_TWI_UE_DATA_COL;
127
+		return (FALSE);
128
+	}
129
+#endif
130
+
131
+	if (!(*msg
132
+	      & (1 << TWI_READ_BIT))) // The LSB in the address byte determines if is a masterRead or masterWrite operation.
133
+	{
134
+		USI_TWI_state.masterWriteDataMode = TRUE;
135
+	}
136
+
137
+	/* Release SCL to ensure that (repeated) Start can be performed */
138
+	PORT_USI |= (1 << PIN_USI_SCL); // Release SCL.
139
+	while (!(PIN_USI & (1 << PIN_USI_SCL)))
140
+		; // Verify that SCL becomes high.
141
+#ifdef TWI_FAST_MODE
142
+	DELAY_T4TWI; // Delay for T4TWI if TWI_FAST_MODE
143
+#else
144
+	DELAY_T2TWI; // Delay for T2TWI if TWI_STANDARD_MODE
145
+#endif
146
+
147
+	/* Generate Start Condition */
148
+	PORT_USI &= ~(1 << PIN_USI_SDA); // Force SDA LOW.
149
+	DELAY_T4TWI;
150
+	PORT_USI &= ~(1 << PIN_USI_SCL); // Pull SCL LOW.
151
+	PORT_USI |= (1 << PIN_USI_SDA);  // Release SDA.
152
+
153
+#ifdef SIGNAL_VERIFY
154
+	if (!(USISR & (1 << USISIF))) {
155
+		USI_TWI_state.errorState = USI_TWI_MISSING_START_CON;
156
+		return (FALSE);
157
+	}
158
+#endif
159
+
160
+	/*Write address and Read/Write data */
161
+	do {
162
+		/* If masterWrite cycle (or inital address tranmission)*/
163
+		if (USI_TWI_state.addressMode || USI_TWI_state.masterWriteDataMode) {
164
+			/* Write a byte */
165
+			PORT_USI &= ~(1 << PIN_USI_SCL);         // Pull SCL LOW.
166
+			USIDR = *(msg++);                        // Setup data.
167
+			USI_TWI_Master_Transfer(tempUSISR_8bit); // Send 8 bits on bus.
168
+
169
+			/* Clock and verify (N)ACK from slave */
170
+			DDR_USI &= ~(1 << PIN_USI_SDA); // Enable SDA as input.
171
+			if (USI_TWI_Master_Transfer(tempUSISR_1bit) & (1 << TWI_NACK_BIT)) {
172
+				if (USI_TWI_state.addressMode)
173
+					USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
174
+				else
175
+					USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
176
+				return (FALSE);
177
+			}
178
+			USI_TWI_state.addressMode = FALSE; // Only perform address transmission once.
179
+		}
180
+		/* Else masterRead cycle*/
181
+		else {
182
+			/* Read a data byte */
183
+			DDR_USI &= ~(1 << PIN_USI_SDA); // Enable SDA as input.
184
+			*(msg++) = USI_TWI_Master_Transfer(tempUSISR_8bit);
185
+
186
+			/* Prepare to generate ACK (or NACK in case of End Of Transmission) */
187
+			if (msgSize == 1) // If transmission of last byte was performed.
188
+			{
189
+				USIDR = 0xFF; // Load NACK to confirm End Of Transmission.
190
+			} else {
191
+				USIDR = 0x00; // Load ACK. Set data register bit 7 (output for SDA) low.
192
+			}
193
+			USI_TWI_Master_Transfer(tempUSISR_1bit); // Generate ACK/NACK.
194
+		}
195
+	} while (--msgSize); // Until all data sent/received.
196
+
197
+	USI_TWI_Master_Stop(); // Send a STOP condition on the TWI bus.
198
+
199
+	/* Transmission successfully completed*/
200
+	return (TRUE);
201
+}
202
+
203
+/*---------------------------------------------------------------
204
+ Core function for shifting data in and out from the USI.
205
+ Data to be sent has to be placed into the USIDR prior to calling
206
+ this function. Data read, will be return'ed from the function.
207
+---------------------------------------------------------------*/
208
+unsigned char USI_TWI_Master_Transfer(unsigned char temp)
209
+{
210
+	USISR = temp;                                          // Set USISR according to temp.
211
+	                                                       // Prepare clocking.
212
+	temp = (0 << USISIE) | (0 << USIOIE) |                 // Interrupts disabled
213
+	       (1 << USIWM1) | (0 << USIWM0) |                 // Set USI in Two-wire mode.
214
+	       (1 << USICS1) | (0 << USICS0) | (1 << USICLK) | // Software clock strobe as source.
215
+	       (1 << USITC);                                   // Toggle Clock Port.
216
+	do {
217
+		DELAY_T2TWI;
218
+		USICR = temp; // Generate positve SCL edge.
219
+		while (!(PIN_USI & (1 << PIN_USI_SCL)))
220
+			; // Wait for SCL to go high.
221
+		DELAY_T4TWI;
222
+		USICR = temp;                   // Generate negative SCL edge.
223
+	} while (!(USISR & (1 << USIOIF))); // Check for transfer complete.
224
+
225
+	DELAY_T2TWI;
226
+	temp  = USIDR;                 // Read out data.
227
+	USIDR = 0xFF;                  // Release SDA.
228
+	DDR_USI |= (1 << PIN_USI_SDA); // Enable SDA as output.
229
+
230
+	return temp; // Return the data from the USIDR
231
+}
232
+
233
+/*---------------------------------------------------------------
234
+ Function for generating a TWI Stop Condition. Used to release
235
+ the TWI bus.
236
+---------------------------------------------------------------*/
237
+unsigned char USI_TWI_Master_Stop(void)
238
+{
239
+	PORT_USI &= ~(1 << PIN_USI_SDA); // Pull SDA low.
240
+	PORT_USI |= (1 << PIN_USI_SCL);  // Release SCL.
241
+	while (!(PIN_USI & (1 << PIN_USI_SCL)))
242
+		; // Wait for SCL to go high.
243
+	DELAY_T4TWI;
244
+	PORT_USI |= (1 << PIN_USI_SDA); // Release SDA.
245
+	DELAY_T2TWI;
246
+
247
+#ifdef SIGNAL_VERIFY
248
+	if (!(USISR & (1 << USIPF))) {
249
+		USI_TWI_state.errorState = USI_TWI_MISSING_STOP_CON;
250
+		return (FALSE);
251
+	}
252
+#endif
253
+
254
+	return (TRUE);
255
+}

+ 162
- 0
sensor/extern/USI_TWI_Master.h Прегледај датотеку

@@ -0,0 +1,162 @@
1
+/*****************************************************************************
2
+ *
3
+ * Atmel Corporation
4
+ *
5
+ * File              : USI_TWI_Master.h
6
+ * Date              : $Date: 2016-7-15 $
7
+ * Updated by        : $Author: Atmel $
8
+ *
9
+ * Support mail      : avr@atmel.com
10
+ *
11
+ * Supported devices : All device with USI module can be used.
12
+ *                     The example is written for the ATmega169, ATtiny26 and ATtiny2313
13
+ *
14
+ * AppNote           : AVR310 - Using the USI module as a TWI Master
15
+ *
16
+ * Description       : This is an implementation of an TWI master using
17
+ *                     the USI module as basis. The implementation assumes the AVR to
18
+ *                     be the only TWI master in the system and can therefore not be
19
+ *                     used in a multi-master system.
20
+ * Usage             : Initialize the USI module by calling the USI_TWI_Master_Initialise()
21
+ *                     function. Hence messages/data are transceived on the bus using
22
+ *                     the USI_TWI_Start_Transceiver_With_Data() function. If the transceiver
23
+ *                     returns with a fail, then use USI_TWI_Get_Status_Info to evaluate the
24
+ *                     couse of the failure.
25
+ *
26
+ ****************************************************************************/
27
+#if __GNUC__
28
+#ifndef F_CPU
29
+#define F_CPU 16500000
30
+#endif
31
+#include <avr/io.h>
32
+#include <util/delay.h>
33
+#endif
34
+//********** Defines **********//
35
+// Defines controlling timing limits
36
+#define TWI_FAST_MODE
37
+
38
+#define SYS_CLK (F_CPU / 1000.0) // [kHz]
39
+
40
+#ifdef TWI_FAST_MODE                            // TWI FAST mode timing limits. SCL = 100-400kHz
41
+#define T2_TWI ((SYS_CLK * 1300) / 1000000) + 1 // >1,3us
42
+#define T4_TWI ((SYS_CLK * 600) / 1000000) + 1  // >0,6us
43
+
44
+#else                                           // TWI STANDARD mode timing limits. SCL <= 100kHz
45
+#define T2_TWI ((SYS_CLK * 4700) / 1000000) + 1 // >4,7us
46
+#define T4_TWI ((SYS_CLK * 4000) / 1000000) + 1 // >4,0us
47
+#endif
48
+
49
+// Defines controling code generating
50
+//#define PARAM_VERIFICATION
51
+//#define NOISE_TESTING
52
+//#define SIGNAL_VERIFY
53
+
54
+// USI_TWI messages and flags and bit masks
55
+//#define SUCCESS   7
56
+//#define MSG       0
57
+/****************************************************************************
58
+  Bit and byte definitions
59
+****************************************************************************/
60
+#define TWI_READ_BIT 0 // Bit position for R/W bit in "address byte".
61
+#define TWI_ADR_BITS 1 // Bit position for LSB of the slave address bits in the init byte.
62
+#define TWI_NACK_BIT 0 // Bit position for (N)ACK bit.
63
+
64
+#define USI_TWI_NO_DATA 0x00           // Transmission buffer is empty
65
+#define USI_TWI_DATA_OUT_OF_BOUND 0x01 // Transmission buffer is outside SRAM space
66
+#define USI_TWI_UE_START_CON 0x02      // Unexpected Start Condition
67
+#define USI_TWI_UE_STOP_CON 0x03       // Unexpected Stop Condition
68
+#define USI_TWI_UE_DATA_COL 0x04       // Unexpected Data Collision (arbitration)
69
+#define USI_TWI_NO_ACK_ON_DATA 0x05    // The slave did not acknowledge  all data
70
+#define USI_TWI_NO_ACK_ON_ADDRESS 0x06 // The slave did not acknowledge  the address
71
+#define USI_TWI_MISSING_START_CON 0x07 // Generated Start Condition not detected on bus
72
+#define USI_TWI_MISSING_STOP_CON 0x08  // Generated Stop Condition not detected on bus
73
+
74
+// Device dependant defines
75
+#if __GNUC__
76
+#if defined(__AVR_AT90Mega169__) || defined(__AVR_ATmega169PA__) || defined(__AVR_AT90Mega165__)                       \
77
+    || defined(__AVR_ATmega165__) || defined(__AVR_ATmega325__) || defined(__AVR_ATmega3250__)                         \
78
+    || defined(__AVR_ATmega645__) || defined(__AVR_ATmega6450__) || defined(__AVR_ATmega329__)                         \
79
+    || defined(__AVR_ATmega3290__) || defined(__AVR_ATmega649__) || defined(__AVR_ATmega6490__)
80
+#define DDR_USI DDRE
81
+#define PORT_USI PORTE
82
+#define PIN_USI PINE
83
+#define PORT_USI_SDA PORTE5
84
+#define PORT_USI_SCL PORTE4
85
+#define PIN_USI_SDA PINE5
86
+#define PIN_USI_SCL PINE4
87
+#endif
88
+#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_AT90Tiny26__) \
89
+    || defined(__AVR_ATtiny26__)
90
+#define DDR_USI DDRB
91
+#define PORT_USI PORTB
92
+#define PIN_USI PINB
93
+#define PORT_USI_SDA PORTB0
94
+#define PORT_USI_SCL PORTB2
95
+#define PIN_USI_SDA PINB0
96
+#define PIN_USI_SCL PINB2
97
+#endif
98
+#if defined(__AVR_AT90Tiny2313__) || defined(__AVR_ATtiny2313__)
99
+#define DDR_USI DDRB
100
+#define PORT_USI PORTB
101
+#define PIN_USI PINB
102
+#define PORT_USI_SDA PORTB5
103
+#define PORT_USI_SCL PORTB7
104
+#define PIN_USI_SDA PINB5
105
+#define PIN_USI_SCL PINB7
106
+#endif
107
+#else //__GNUC__
108
+#if defined(__AT90Mega169__) || defined(__ATmega169__) || defined(__AT90Mega165__) || defined(__ATmega165__)           \
109
+    || defined(__ATmega325__) || defined(__ATmega3250__) || defined(__ATmega645__) || defined(__ATmega6450__)          \
110
+    || defined(__ATmega329__) || defined(__ATmega3290__) || defined(__ATmega649__) || defined(__ATmega6490__)
111
+#define DDR_USI DDRE
112
+#define PORT_USI PORTE
113
+#define PIN_USI PINE
114
+#define PORT_USI_SDA PORTE5
115
+#define PORT_USI_SCL PORTE4
116
+#define PIN_USI_SDA PINE5
117
+#define PIN_USI_SCL PINE4
118
+#endif
119
+
120
+#if defined(__ATtiny25__) || defined(__ATtiny45__) || defined(__ATtiny85__) || defined(__AT90Tiny26__)                 \
121
+    || defined(__ATtiny26__)
122
+#define DDR_USI DDRB
123
+#define PORT_USI PORTB
124
+#define PIN_USI PINB
125
+#define PORT_USI_SDA PORTB0
126
+#define PORT_USI_SCL PORTB2
127
+#define PIN_USI_SDA PINB0
128
+#define PIN_USI_SCL PINB2
129
+#endif
130
+
131
+#if defined(__AT90Tiny2313__) || defined(__ATtiny2313__)
132
+#define DDR_USI DDRB
133
+#define PORT_USI PORTB
134
+#define PIN_USI PINB
135
+#define PORT_USI_SDA PORTB5
136
+#define PORT_USI_SCL PORTB7
137
+#define PIN_USI_SDA PINB5
138
+#define PIN_USI_SCL PINB7
139
+#endif
140
+#endif //__GNUC__
141
+
142
+// General defines
143
+#define TRUE 1
144
+#define FALSE 0
145
+
146
+#if __GNUC__
147
+#define DELAY_T2TWI (_delay_us(T2_TWI / 4))
148
+#define DELAY_T4TWI (_delay_us(T4_TWI / 4))
149
+#else
150
+#define DELAY_T2TWI (__delay_cycles(T2_TWI))
151
+#define DELAY_T4TWI (__delay_cycles(T4_TWI))
152
+#endif
153
+//********** Prototypes **********//
154
+
155
+void USI_TWI_Master_Initialise(void);
156
+#ifndef __GNUC__
157
+__x // AVR compiler
158
+#endif
159
+    unsigned char
160
+    USI_TWI_Start_Transceiver_With_Data(unsigned char *, unsigned char);
161
+
162
+unsigned char USI_TWI_Get_State_Info(void);

sensor/include/adc.h → sensor/include/lux.h Прегледај датотеку

@@ -1,5 +1,5 @@
1 1
 /*
2
- * adc.h
2
+ * lux.h
3 3
  *
4 4
  * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5 5
  *
@@ -16,13 +16,12 @@
16 16
  * See <http://www.gnu.org/licenses/>.
17 17
  */
18 18
 
19
-#ifndef __ADC_H__
20
-#define __ADC_H__
19
+#ifndef __LUX_H__
20
+#define __LUX_H__
21 21
 
22 22
 #include <stdint.h>
23 23
 
24
-void adcInit(void);
25
-uint16_t adcGet(void);
26
-uint16_t adcRaw(void);
24
+void luxInit(void);
25
+uint16_t luxGet(void);
27 26
 
28
-#endif // __ADC_H__
27
+#endif // __LUX_H__

+ 28
- 0
sensor/include/twi.h Прегледај датотеку

@@ -0,0 +1,28 @@
1
+/*
2
+ * twi.h
3
+ *
4
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef __TWI_H__
20
+#define __TWI_H__
21
+
22
+#include <stdint.h>
23
+
24
+void twiInit(void);
25
+void twiWrite(uint8_t addr, uint8_t op);
26
+uint16_t twiRead(uint8_t addr);
27
+
28
+#endif // __TWI_H__

+ 0
- 66
sensor/src/adc.c Прегледај датотеку

@@ -1,66 +0,0 @@
1
-/*
2
- * adc.c
3
- *
4
- * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
- *
6
- * This program is free software: you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation, either version 3 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * See <http://www.gnu.org/licenses/>.
17
- */
18
-
19
-#include <avr/io.h>
20
-#include <avr/interrupt.h>
21
-#include <util/atomic.h>
22
-
23
-#include "adc.h"
24
-
25
-static int32_t adc_filter = 0;
26
-static uint16_t adc_prev = 0;
27
-
28
-void adcInit(void) {
29
-    ADMUX = (1 << MUX0); // Vcc reference, ADC1 / PB2 in
30
-    ADCSRA = (1 << ADEN) | (1 << ADIE) // adc and interrupt enabled
31
-            | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) // prescaler 128
32
-            | (1 << ADSC); // start first conversion
33
-}
34
-
35
-static inline void adcFilter(uint16_t val) {
36
-    adc_prev = val;
37
-
38
-    int32_t input = val;
39
-    input <<= 16; // 10bit val --> 26bit input
40
-
41
-    adc_filter = adc_filter + ((input - adc_filter) >> 5);
42
-}
43
-
44
-ISR(ADC_vect) {
45
-    // add this value to our filtered average
46
-    adcFilter(ADC);
47
-
48
-    // start next conversion
49
-    ADCSRA |= (1 << ADSC);
50
-}
51
-
52
-uint16_t adcGet(void) {
53
-    uint16_t val;
54
-    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
55
-        val = (adc_filter >> 16) + ((adc_filter & 0x00008000) >> 15);
56
-    }
57
-    return val;
58
-}
59
-
60
-uint16_t adcRaw(void) {
61
-    uint16_t val;
62
-    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
63
-        val = adc_prev;
64
-    }
65
-    return val;
66
-}

+ 45
- 0
sensor/src/lux.c Прегледај датотеку

@@ -0,0 +1,45 @@
1
+/*
2
+ * lux.c
3
+ *
4
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include <avr/io.h>
20
+
21
+#include "twi.h"
22
+#include "lux.h"
23
+
24
+#define LUX_ADDR 0x5C
25
+
26
+#define OP_POWER_ON 0x01
27
+#define OP_RESET 0x07
28
+
29
+#define OP_CONT_1X 0x10
30
+#define OP_CONT_0_5X 0x11
31
+#define OP_CONT_4X 0x13
32
+
33
+#define OP_ONCE_1X 0x20
34
+#define OP_ONCE_0_5X 0x21
35
+#define OP_ONCE_4X 0x23
36
+
37
+void luxInit(void) {
38
+    twiWrite(LUX_ADDR, OP_POWER_ON);
39
+    twiWrite(LUX_ADDR, OP_CONT_1X);
40
+}
41
+
42
+uint16_t luxGet(void) {
43
+    uint16_t val = twiRead(LUX_ADDR);
44
+    return val;
45
+}

+ 12
- 4
sensor/src/main.c Прегледај датотеку

@@ -21,13 +21,15 @@
21 21
 #include <avr/wdt.h>
22 22
 #include <util/delay.h>
23 23
 
24
-#include "adc.h"
24
+#include "lux.h"
25
+#include "twi.h"
25 26
 #include "usbdrv.h"
26 27
 #include "main.h"
27 28
 
28 29
 bool keep_feeding = true;
29 30
 
30
-int __attribute__((noreturn)) main(void) {
31
+__attribute__((noreturn))
32
+int main(void) {
31 33
     wdt_enable(WDTO_1S);
32 34
     wdt_reset();
33 35
 
@@ -35,18 +37,24 @@ int __attribute__((noreturn)) main(void) {
35 37
     DDRB |= (1 << DDB1); // output
36 38
     PORTB |= (1 << PB1); // turn on
37 39
 
38
-    adcInit();
40
+    twiInit();
41
+    luxInit();
39 42
     usbInit();
40 43
 
41 44
     usbDeviceDisconnect(); // enforce re-enumeration, do this while interrupts are disabled!
45
+
42 46
     wdt_reset();
47
+    // TODO perform lux sensor init in this time
43 48
     _delay_ms(255); // fake USB disconnect for > 250 ms
49
+
44 50
     usbDeviceConnect();
45 51
 
46 52
     PORTB &= ~(1 << PB1); // turn status LED off
47 53
 
48
-    // enable interrupts and enter main loop for USB polling
54
+    // enable interrupts
49 55
     sei();
56
+
57
+    // enter main loop for USB polling
50 58
     while (1) {
51 59
         if (keep_feeding) {
52 60
             wdt_reset();

+ 48
- 0
sensor/src/twi.c Прегледај датотеку

@@ -0,0 +1,48 @@
1
+/*
2
+ * twi.c
3
+ *
4
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include <avr/io.h>
20
+
21
+#include "USI_TWI_Master.h"
22
+#include "twi.h"
23
+
24
+void twiInit(void) {
25
+    USI_TWI_Master_Initialise();
26
+}
27
+
28
+void twiWrite(uint8_t addr, uint8_t op) {
29
+    uint8_t msg[] = {
30
+        addr << TWI_ADR_BITS,
31
+        op
32
+    };
33
+
34
+    USI_TWI_Start_Transceiver_With_Data(msg, sizeof(msg));
35
+}
36
+
37
+uint16_t twiRead(uint8_t addr) {
38
+    uint8_t msg[] = {
39
+        (addr << TWI_ADR_BITS) | (1 << TWI_READ_BIT),
40
+        0, 0 // space for received data
41
+    };
42
+
43
+    do {
44
+        USI_TWI_Start_Transceiver_With_Data(msg, sizeof(msg));
45
+    } while (USI_TWI_Get_State_Info() == USI_TWI_NO_ACK_ON_ADDRESS);
46
+
47
+    return (msg[1] << 8) | msg[2];
48
+}

+ 3
- 9
sensor/src/usb.c Прегледај датотеку

@@ -21,13 +21,12 @@
21 21
 #include "usbdrv.h"
22 22
 #include "osccal.c" // missing usbdrv include, so include here
23 23
 
24
-#include "adc.h"
24
+#include "lux.h"
25 25
 #include "main.h"
26 26
 
27 27
 #define CUSTOM_RQ_ECHO 0 // send back wValue and wIndex, for testing comms reliability
28 28
 #define CUSTOM_RQ_RESET 1 // reset to bootloader
29 29
 #define CUSTOM_RQ_GET 2 // get ldr value, filtered
30
-#define CUSTOM_RQ_RAW 3 // get raw ldr value
31 30
 
32 31
 usbMsgLen_t usbFunctionSetup(uchar data[8]) {
33 32
     usbRequest_t *rq = (void *)data;
@@ -53,13 +52,8 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
53 52
             dataBuffer[0] = 0; // error code
54 53
         }
55 54
         return 1;
56
-    } else if ((rq->bRequest == CUSTOM_RQ_GET) || (rq->bRequest == CUSTOM_RQ_RAW)) {
57
-        uint16_t ldr_value;
58
-        if (rq->bRequest == CUSTOM_RQ_GET) {
59
-            ldr_value = adcGet();
60
-        } else {
61
-            ldr_value = adcRaw();
62
-        }
55
+    } else if (rq->bRequest == CUSTOM_RQ_GET) {
56
+        uint16_t ldr_value = luxGet();
63 57
         dataBuffer[0] = (ldr_value & 0x00FF) >> 0;
64 58
         dataBuffer[1] = (ldr_value & 0xFF00) >> 8;
65 59
 

Loading…
Откажи
Сачувај