Sfoglia il codice sorgente

Can now compile for Arduino with ATmega328 for debugging, added serial library for this purpose.

Thomas Buck 8 anni fa
parent
commit
3c26c57d91
11 ha cambiato i file con 917 aggiunte e 2 eliminazioni
  1. 11
    0
      include/cppm.h
  2. 125
    0
      include/serial.h
  3. 240
    0
      include/serial_device.h
  4. 26
    0
      include/spi.h
  5. 15
    1
      makefile
  6. 13
    0
      src/cppm.c
  7. 16
    0
      src/main.c
  8. 42
    1
      src/rx.c
  9. 410
    0
      src/serial.c
  10. 8
    0
      src/spi.c
  11. 11
    0
      src/timer.c

+ 11
- 0
include/cppm.h Vedi File

@@ -7,10 +7,21 @@
7 7
 
8 8
 #include <stdint.h>
9 9
 
10
+#ifdef DEBUG
11
+
12
+// Arduino D10
13
+#define CPPM_PORT PORTB
14
+#define CPPM_DDR DDRB
15
+#define CPPM_PIN PB2
16
+
17
+#else
18
+
10 19
 #define CPPM_PORT PORTB
11 20
 #define CPPM_DDR DDRB
12 21
 #define CPPM_PIN PB5
13 22
 
23
+#endif
24
+
14 25
 extern volatile uint16_t cppmData[8];
15 26
 
16 27
 void cppmInit(void);

+ 125
- 0
include/serial.h Vedi File

@@ -0,0 +1,125 @@
1
+/*
2
+ * serial.h
3
+ *
4
+ * Copyright (c) 2012, 2013, Thomas Buck <xythobuz@me.com>
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions
9
+ * are met:
10
+ *
11
+ * - Redistributions of source code must retain the above copyright notice,
12
+ *   this list of conditions and the following disclaimer.
13
+ *
14
+ * - Redistributions in binary form must reproduce the above copyright
15
+ *   notice, this list of conditions and the following disclaimer in the
16
+ *   documentation and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+#ifndef _serial_h
31
+#define _serial_h
32
+
33
+/** \addtogroup uart UART Library
34
+ *  UART Library enabling you to control all available
35
+ *  UART Modules. With XON/XOFF Flow Control and buffered
36
+ *  Receiving and Transmitting.
37
+ *  @{
38
+ */
39
+
40
+/** \file serial.h
41
+ *  UART Library Header File
42
+ */
43
+
44
+/** Calculate Baudrate Register Value */
45
+#define BAUD(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)
46
+
47
+/** Get number of available UART modules.
48
+ *  \returns number of modules
49
+ */
50
+uint8_t serialAvailable(void);
51
+
52
+/** Initialize the UART Hardware.
53
+ *  \param uart UART Module to initialize
54
+ *  \param baud Baudrate. Use the BAUD() macro!
55
+ */
56
+void serialInit(uint8_t uart, uint16_t baud);
57
+
58
+/** Stop the UART Hardware.
59
+ *  \param uart UART Module to stop
60
+ */
61
+void serialClose(uint8_t uart);
62
+
63
+/** Manually change the flow control.
64
+ *  Flow Control has to be compiled into the library!
65
+ *  \param uart UART Module to operate on
66
+ *  \param on 1 of on, 0 if off
67
+ */
68
+void setFlow(uint8_t uart, uint8_t on);
69
+
70
+/** Check if a byte was received.
71
+ *  \param uart UART Module to check
72
+ *  \returns 1 if a byte was received, 0 if not
73
+ */
74
+uint8_t serialHasChar(uint8_t uart);
75
+
76
+/** Read a single byte.
77
+ *  \param uart UART Module to read from
78
+ *  \returns Received byte or 0
79
+ */
80
+uint8_t serialGet(uint8_t uart);
81
+
82
+/** Wait until a character is received.
83
+ *  \param uart UART Module to read from
84
+ *  \returns Received byte
85
+ */
86
+uint8_t serialGetBlocking(uint8_t uart);
87
+
88
+/** Check if the receive buffer is full.
89
+ *  \param uart UART Module to check
90
+ *  \returns 1 if buffer is full, 0 if not
91
+ */
92
+uint8_t serialRxBufferFull(uint8_t uart);
93
+
94
+/** Check if the receive buffer is empty.
95
+ *  \param uart UART Module to check
96
+ *  \returns 1 if buffer is empty, 0 if not.
97
+ */
98
+uint8_t serialRxBufferEmpty(uint8_t uart);
99
+
100
+/** Send a byte.
101
+ *  \param uart UART Module to write to
102
+ *  \param data Byte to send
103
+ */
104
+void serialWrite(uint8_t uart, uint8_t data);
105
+
106
+/** Send a string.
107
+ *  \param uart UART Module to write to
108
+ *  \param data Null-Terminated String
109
+ */
110
+void serialWriteString(uint8_t uart, const char *data);
111
+
112
+/** Check if the transmit buffer is full.
113
+ *  \param uart UART Module to check
114
+ *  \returns 1 if buffer is full, 0 if not
115
+ */
116
+uint8_t serialTxBufferFull(uint8_t uart);
117
+
118
+/** Check if the transmit buffer is empty.
119
+ *  \param uart UART Module to check
120
+ *  \returns 1 if buffer is empty, 0 if not.
121
+ */
122
+uint8_t serialTxBufferEmpty(uint8_t uart);
123
+
124
+#endif // _serial_h
125
+/** @} */

+ 240
- 0
include/serial_device.h Vedi File

@@ -0,0 +1,240 @@
1
+/*
2
+ * serial_device.h
3
+ *
4
+ * Copyright (c) 2012, 2013, Thomas Buck <xythobuz@me.com>
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions
9
+ * are met:
10
+ *
11
+ * - Redistributions of source code must retain the above copyright notice,
12
+ *   this list of conditions and the following disclaimer.
13
+ *
14
+ * - Redistributions in binary form must reproduce the above copyright
15
+ *   notice, this list of conditions and the following disclaimer in the
16
+ *   documentation and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+#ifndef _serial_device_h
31
+#define _serial_device_h
32
+
33
+/** \addtogroup uart UART Library
34
+ *  UART Library enabling you to control all available
35
+ *  UART Modules. With XON/XOFF Flow Control and buffered
36
+ *  Receiving and Transmitting.
37
+ *  @{
38
+ */
39
+
40
+/** \file serial_device.h
41
+ *  UART Library device-specific configuration.
42
+ *  Contains Register and Bit Positions for different AVR devices.
43
+ */
44
+
45
+#if  defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
46
+    || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
47
+|| defined(__AVR_ATmega323__)
48
+
49
+#define UART_COUNT 1
50
+#define UART_REGISTERS 6
51
+#define UART_BITS 7
52
+volatile uint8_t *serialRegisters[UART_COUNT][UART_REGISTERS] = {{
53
+    &UDR,
54
+    &UCSRB,
55
+    &UCSRC,
56
+    &UCSRA,
57
+    &UBRRH,
58
+    &UBRRL
59
+}};
60
+#define SERIALBAUDBIT 8
61
+uint8_t serialBits[UART_COUNT][UART_BITS] = {{
62
+    UCSZ0,
63
+    UCSZ1,
64
+    RXCIE,
65
+    RXEN,
66
+    TXEN,
67
+    UDRIE,
68
+    UDRE
69
+}};
70
+#define SERIALRECIEVEINTERRUPT USART_RXC_vect
71
+#define SERIALTRANSMITINTERRUPT USART_UDRE_vect
72
+ 
73
+#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) \
74
+    || defined(__AVR_ATmega48__) || defined(__AVR_ATmega88__) \
75
+    || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) \
76
+    || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88P__) 
77
+
78
+#define UART_COUNT 1
79
+#define UART_REGISTERS 5
80
+#define UART_BITS 7
81
+volatile uint8_t *serialRegisters[UART_COUNT][UART_REGISTERS] = {{
82
+    &UDR0,
83
+    &UCSR0B,
84
+    &UCSR0C,
85
+    &UCSR0A
86
+}};
87
+#define SERIALBAUDBIT 16
88
+volatile uint16_t *serialBaudRegisters[UART_COUNT] = {
89
+    &UBRR0
90
+};
91
+uint8_t serialBits[UART_COUNT][UART_BITS] = {{
92
+    UCSZ00,
93
+    UCSZ01,
94
+    RXCIE0,
95
+    RXEN0,
96
+    TXEN0,
97
+    UDRIE0,
98
+    UDRE0
99
+}};
100
+#define SERIALRECIEVEINTERRUPT USART_RX_vect
101
+#define SERIALTRANSMITINTERRUPT USART_UDRE_vect
102
+
103
+#elif defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__)
104
+
105
+#define UART_COUNT 2
106
+#define UART_REGISTERS 4
107
+#define UART_BITS 7
108
+volatile uint8_t *serialRegisters[UART_COUNT][UART_REGISTERS] = {
109
+    {
110
+        &UDR0,
111
+        &UCSR0B,
112
+        &UCSR0C,
113
+        &UCSR0A
114
+    },
115
+    {
116
+        &UDR1,
117
+        &UCSR1B,
118
+        &UCSR1C,
119
+        &UCSR1A
120
+    }
121
+};
122
+#define SERIALBAUDBIT 16
123
+volatile uint16_t *serialBaudRegisters[UART_COUNT] = {
124
+    &UBRR0, &UBRR1
125
+};
126
+uint8_t serialBits[UART_COUNT][UART_BITS] = {
127
+    {
128
+        UCSZ00,
129
+        UCSZ01,
130
+        RXCIE0,
131
+        RXEN0,
132
+        TXEN0,
133
+        UDRIE0,
134
+        UDRE0
135
+    },
136
+    {
137
+        UCSZ10,
138
+        UCSZ11,
139
+        RXCIE1,
140
+        RXEN1,
141
+        TXEN1,
142
+        UDRIE1,
143
+        UDRE1
144
+    }
145
+};
146
+#define SERIALRECIEVEINTERRUPT   USART0_RX_vect
147
+#define SERIALTRANSMITINTERRUPT  USART0_UDRE_vect
148
+#define SERIALRECIEVEINTERRUPT1  USART1_RX_vect
149
+#define SERIALTRANSMITINTERRUPT1 USART1_UDRE_vect
150
+
151
+
152
+#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) \
153
+    || defined(__AVR_ATmega640__)
154
+
155
+#define UART_COUNT 4
156
+#define UART_REGISTERS 4
157
+#define UART_BITS 7
158
+volatile uint8_t *serialRegisters[UART_COUNT][UART_REGISTERS] = {
159
+    {
160
+        &UDR0,
161
+        &UCSR0B,
162
+        &UCSR0C,
163
+        &UCSR0A
164
+    },
165
+    {
166
+        &UDR1,
167
+        &UCSR1B,
168
+        &UCSR1C,
169
+        &UCSR1A
170
+    },
171
+    {
172
+        &UDR2,
173
+        &UCSR2B,
174
+        &UCSR2C,
175
+        &UCSR2A
176
+    },
177
+    {
178
+        &UDR3,
179
+        &UCSR3B,
180
+        &UCSR3C,
181
+        &UCSR3A
182
+    }
183
+};
184
+#define SERIALBAUDBIT 16
185
+volatile uint16_t *serialBaudRegisters[UART_COUNT] = {
186
+    &UBRR0, &UBRR1, &UBRR2, &UBRR3
187
+};
188
+uint8_t serialBits[UART_COUNT][UART_BITS] = {
189
+    {
190
+        UCSZ00,
191
+        UCSZ01,
192
+        RXCIE0,
193
+        RXEN0,
194
+        TXEN0,
195
+        UDRIE0,
196
+        UDRE0
197
+    },
198
+    {
199
+        UCSZ10,
200
+        UCSZ11,
201
+        RXCIE1,
202
+        RXEN1,
203
+        TXEN1,
204
+        UDRIE1,
205
+        UDRE1
206
+    },
207
+    {
208
+        UCSZ20,
209
+        UCSZ21,
210
+        RXCIE2,
211
+        RXEN2,
212
+        TXEN2,
213
+        UDRIE2,
214
+        UDRE2
215
+    },
216
+    {
217
+        UCSZ30,
218
+        UCSZ31,
219
+        RXCIE3,
220
+        RXEN3,
221
+        TXEN3,
222
+        UDRIE3,
223
+        UDRE3
224
+    }
225
+};
226
+#define SERIALRECIEVEINTERRUPT   USART0_RX_vect
227
+#define SERIALTRANSMITINTERRUPT  USART0_UDRE_vect
228
+#define SERIALRECIEVEINTERRUPT1  USART1_RX_vect
229
+#define SERIALTRANSMITINTERRUPT1 USART1_UDRE_vect
230
+#define SERIALRECIEVEINTERRUPT2  USART2_RX_vect
231
+#define SERIALTRANSMITINTERRUPT2 USART2_UDRE_vect
232
+#define SERIALRECIEVEINTERRUPT3  USART3_RX_vect
233
+#define SERIALTRANSMITINTERRUPT3 USART3_UDRE_vect
234
+
235
+#else
236
+#error "AvrSerialLibrary not compatible with your MCU!"
237
+#endif
238
+
239
+#endif // _serial_device_h
240
+/** @} */

+ 26
- 0
include/spi.h Vedi File

@@ -8,6 +8,30 @@
8 8
 #include <stdint.h>
9 9
 #include <avr/io.h>
10 10
 
11
+#ifdef DEBUG
12
+
13
+// Arduino D2
14
+#define SCK_on PORTD |= PD2
15
+#define SCK_off PORTD &= ~(PD2)
16
+
17
+// Arduino D4
18
+#define MO_on PORTD |= PD4
19
+#define MO_off PORTD &= ~(PD4)
20
+
21
+// Arduino D7
22
+#define CS_on PORTD |= PD7
23
+#define CS_off PORTD &= ~(PD7)
24
+
25
+// Arduino D8
26
+#define MI_1 (PINB & PB0) == PB0
27
+#define MI_0 (PINB & PB0) != PB0
28
+
29
+// Arduino D12
30
+#define GDO_1 (PINB & PB4) == PB4
31
+#define GDO_0 (PINB & PB4) != PB4
32
+
33
+#else
34
+
11 35
 #define SCK_on PORTB |= PB4
12 36
 #define SCK_off PORTB &= ~(PB4)
13 37
 
@@ -23,6 +47,8 @@
23 47
 #define GDO_1 (PINB & PB0) == PB0
24 48
 #define GDO_0 (PINB & PB0) != PB0
25 49
 
50
+#endif
51
+
26 52
 #define NOP() __asm__ __volatile__("nop")
27 53
 
28 54
 void spiInit(void);

+ 15
- 1
makefile Vedi File

@@ -19,6 +19,10 @@ SRC += src/cc2500.c
19 19
 SRC += src/rx.c
20 20
 SRC += src/cppm.c
21 21
 
22
+ifeq ($(DEBUG),1)
23
+	SRC += src/serial.c
24
+endif
25
+
22 26
 OBJ = $(addprefix $(BUILDDIR)/, $(SRC:.c=.o))
23 27
 
24 28
 CARGS = -mmcu=$(MCU)
@@ -35,6 +39,10 @@ CARGS += -std=$(CSTANDARD)
35 39
 CARGS += -DF_CPU=$(F_CPU)
36 40
 CARGS += -ffunction-sections
37 41
 
42
+ifeq ($(DEBUG),1)
43
+	CARGS += -DDEBUG
44
+endif
45
+
38 46
 LINKER = -Wl,--relax
39 47
 
40 48
 PROGRAMMER = avrisp2
@@ -44,6 +52,9 @@ TARGET = rx
44 52
 
45 53
 all: $(BUILDDIR)/$(TARGET).hex
46 54
 
55
+debug:
56
+	$(MAKE) BUILDDIR=build/debug TARGET=debug MCU=atmega328 DEBUG=1 all
57
+
47 58
 $(BUILDDIR)/%.o: %.c
48 59
 	@$(MKDIR) $(BUILDDIR)/$(dir $<)
49 60
 	$(GCC) -c $< -o $@ $(CARGS)
@@ -57,7 +68,10 @@ $(BUILDDIR)/$(TARGET).hex: $(BUILDDIR)/$(TARGET).elf
57 68
 	$(OBJDUMP) -h -S $< > $(@:.hex=.lss)
58 69
 
59 70
 program: $(BUILDDIR)/$(TARGET).hex
60
-	$(AVRDUDE) -p $(MCU) -c $(PROGRAMMER) -P $(ISPPORT) -e -U $(TARGET).hex
71
+	$(AVRDUDE) -p $(MCU) -c $(PROGRAMMER) -P $(ISPPORT) -e -U $(BUILDDIR)/$(TARGET).hex
72
+
73
+debugProgram:
74
+	$(MAKE) BUILDDIR=build/debug TARGET=debug MCU=atmega328 DEBUG=1 PROGRAMMER=stk500v1 ISPPORT=/dev/tty.usbserial-A100OZQ1 program
61 75
 
62 76
 clean:
63 77
 	$(RM) $(BUILDDIR)

+ 13
- 0
src/cppm.c Vedi File

@@ -60,7 +60,12 @@ void cppmInit(void) {
60 60
     CPPM_PORT &= ~(1 << CPPM_PIN);
61 61
 
62 62
     TCCR0B |= (1 << CS01); // Prescaler: 8
63
+
64
+#ifdef DEBUG
65
+    TIMSK0 |= (1 << TOIE0) | (1 << OCIE0A); // Enable Overflow and Compare Match Interrupt
66
+#else
63 67
     TIMSK |= (1 << TOIE0) | (1 << OCIE0A); // Enable Overflow and Compare Match Interrupt
68
+#endif
64 69
     OCR0A = 0;
65 70
 
66 71
     state = 0;
@@ -111,7 +116,11 @@ static void nextState(void) {
111 116
     }
112 117
 }
113 118
 
119
+#ifdef DEBUG
120
+ISR(TIMER0_OVF_vect) {
121
+#else
114 122
 ISR(TIM0_OVF_vect) {
123
+#endif
115 124
     if (triggerState == OVERFLOW) {
116 125
         if (triggerTimeRemaining == 0) {
117 126
             triggerState = NONE;
@@ -122,7 +131,11 @@ ISR(TIM0_OVF_vect) {
122 131
     }
123 132
 }
124 133
 
134
+#ifdef DEBUG
135
+ISR(TIMER0_COMPA_vect) {
136
+#else
125 137
 ISR(TIM0_COMPA_vect) {
138
+#endif
126 139
     if (triggerState == COMPARE_MATCH) {
127 140
         triggerState = NONE;
128 141
         nextState();

+ 16
- 0
src/main.c Vedi File

@@ -10,6 +10,10 @@
10 10
 #include "cppm.h"
11 11
 #include "rx.h"
12 12
 
13
+#ifdef DEBUG
14
+#include "serial.h"
15
+#endif
16
+
13 17
 void watchdogBoot(void) __attribute__((naked)) __attribute__((section(".init3")));
14 18
 void watchdogBoot(void) {
15 19
     MCUSR = 0;
@@ -20,12 +24,24 @@ void main(void) {
20 24
     cppmInit();
21 25
     timerInit();
22 26
 
27
+#ifdef DEBUG
28
+    serialInit(0, BAUD(19200, F_CPU));
29
+#endif
30
+
23 31
     sei(); // Enable interrupts (required for timer)
24 32
     wdt_enable(WDTO_250MS); // Trigger Watchdog after 250ms
25 33
 
34
+#ifdef DEBUG
35
+    serialWriteString(0, "RX reset.\n");
36
+#endif
37
+
26 38
     spiInit();
27 39
     rxInit();
28 40
 
41
+#ifdef DEBUG
42
+    serialWriteString(0, "RX ready!\n");
43
+#endif
44
+
29 45
     for(;;) {
30 46
         wdt_reset();
31 47
         rxReceivePacket();

+ 42
- 1
src/rx.c Vedi File

@@ -14,6 +14,10 @@
14 14
 #include "timer.h"
15 15
 #include "rx.h"
16 16
 
17
+#ifdef DEBUG
18
+#include "serial.h"
19
+#endif
20
+
17 21
 #define CHANNELS 8
18 22
 #define PPM_MIN 1000
19 23
 #define PPM_MAX 2000
@@ -57,9 +61,17 @@ static void readBindingData(void);
57 61
 static void writeBindingData(void);
58 62
 
59 63
 void rxInit(void) {
64
+#ifdef DEBUG
65
+    serialWriteString(0, "RX: binding\n");
66
+#endif
67
+
60 68
     initialize(1); // binding
61 69
     binding();
62 70
 
71
+#ifdef DEBUG
72
+    serialWriteString(0, "RX: receiving\n");
73
+#endif
74
+
63 75
     initialize(0); // data
64 76
     cc2500WriteReg(CC2500_0A_CHANNR, hopData[channr]);//0A-hop
65 77
     cc2500WriteReg(CC2500_23_FSCAL3, 0x89); //23-89
@@ -119,9 +131,16 @@ static void binding(void) {
119 131
     readBindingData();
120 132
     if ((txid[0] != 0xff) || (txid[1] != 0xff)) {
121 133
         // valid binding data found
134
+#ifdef DEBUG
135
+        serialWriteString(0, "RX: found data in EEPROM!\n");
136
+#endif
122 137
         return;
123 138
     }
124 139
 
140
+#ifdef DEBUG
141
+    serialWriteString(0, "RX: no stored data, tuning...\n");
142
+#endif
143
+
125 144
     // No valid txid, forcing bind
126 145
     tuning();
127 146
 
@@ -129,6 +148,10 @@ static void binding(void) {
129 148
     cc2500WriteReg(CC2500_0C_FSCTRL0, frequencyOffsetHack);
130 149
     eeprom_write_byte(EEPROM_BASE_ADDRESS + 101, frequencyOffsetHack);
131 150
 
151
+#ifdef DEBUG
152
+    serialWriteString(0, "RX: tuned, binding...\n");
153
+#endif
154
+
132 155
     performBind();
133 156
 }
134 157
 
@@ -188,6 +211,10 @@ static void performBind(void) {
188 211
         wdt_reset();
189 212
     }
190 213
 
214
+#ifdef DEBUG
215
+    serialWriteString(0, "RX: got hop data, reading list...\n");
216
+#endif
217
+
191 218
     listLength = 0;
192 219
     uint8_t eol = 0;
193 220
     for (uint8_t bindIdx = 0x05; bindIdx <= 120; bindIdx += 5) {
@@ -223,6 +250,10 @@ static void performBind(void) {
223 250
         }
224 251
     }
225 252
 
253
+#ifdef DEBUG
254
+    serialWriteString(0, "RX: binding finished!\n");
255
+#endif
256
+
226 257
     writeBindingData();
227 258
     cc2500Strobe(CC2500_SIDLE); // Back to idle
228 259
 }
@@ -277,7 +308,13 @@ void rxReceivePacket() {
277 308
             if (missingPackets > MAX_MISSING_PACKET) {
278 309
                 nextChannel(SEEK_CHANNEL_SKIP);
279 310
                 counter++;
280
-                //if (counter > (MAX_MISSING_PACKET << 1)) LED_ON;
311
+
312
+#ifdef DEBUG
313
+                if (counter > (MAX_MISSING_PACKET << 1)) {
314
+                    serialWriteString(0, "RX: missing packet notification!\n");
315
+                }
316
+#endif
317
+
281 318
                 if (counter == (MAX_MISSING_PACKET << 2)) counter = 0;
282 319
                 break;
283 320
             } else
@@ -343,6 +380,10 @@ void rxReceivePacket() {
343 380
         ppmBuffer[RSSI_OVER_PPM] = map(rssi, RSSI_MIN, RSSI_MAX, PPM_MIN, PPM_MAX);
344 381
 #endif
345 382
 
383
+#ifdef DEBUG
384
+        serialWriteString(0, "RX: packet received, sending CPPM!\n");
385
+#endif
386
+
346 387
         cppmCopy(ppmBuffer);
347 388
     }
348 389
 

+ 410
- 0
src/serial.c Vedi File

@@ -0,0 +1,410 @@
1
+/*
2
+ * serial.c
3
+ *
4
+ * Copyright (c) 2012, 2013, Thomas Buck <xythobuz@me.com>
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions
9
+ * are met:
10
+ *
11
+ * - Redistributions of source code must retain the above copyright notice,
12
+ *   this list of conditions and the following disclaimer.
13
+ *
14
+ * - Redistributions in binary form must reproduce the above copyright
15
+ *   notice, this list of conditions and the following disclaimer in the
16
+ *   documentation and/or other materials provided with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+#include <avr/io.h>
31
+#include <avr/interrupt.h>
32
+#include <stdint.h>
33
+
34
+#include "serial.h"
35
+#include "serial_device.h"
36
+
37
+/** \addtogroup uart UART Library
38
+ *  UART Library enabling you to control all available
39
+ *  UART Modules. With XON/XOFF Flow Control and buffered
40
+ *  Receiving and Transmitting.
41
+ *  @{
42
+ */
43
+
44
+/** \file serial.c
45
+ *  UART Library Implementation
46
+ */
47
+
48
+/** If you define this, a '\\r' (CR) will be put in front of a '\\n' (LF) when sending a byte.
49
+ *  Binary Communication will then be impossible!
50
+ */
51
+// #define SERIALINJECTCR
52
+
53
+#ifndef RX_BUFFER_SIZE
54
+#define RX_BUFFER_SIZE 32 /**< RX Buffer Size in Bytes (Power of 2) */
55
+#endif
56
+
57
+#ifndef TX_BUFFER_SIZE
58
+#define TX_BUFFER_SIZE 32 /**< TX Buffer Size in Bytes (Power of 2) */
59
+#endif
60
+
61
+/** Defining this enables incoming XON XOFF (sends XOFF if rx buff is full) */
62
+#define FLOWCONTROL
63
+
64
+#define FLOWMARK 5 /**< Space remaining to trigger xoff/xon */
65
+#define XON 0x11 /**< XON Value */
66
+#define XOFF 0x13 /**< XOFF Value */
67
+
68
+#if (RX_BUFFER_SIZE < 2) || (TX_BUFFER_SIZE < 2)
69
+#error SERIAL BUFFER TOO SMALL!
70
+#endif
71
+
72
+#ifdef FLOWCONTROL
73
+#if (RX_BUFFER_SIZE < 8) || (TX_BUFFER_SIZE < 8)
74
+#error SERIAL BUFFER TOO SMALL!
75
+#endif
76
+#endif
77
+
78
+#if ((RX_BUFFER_SIZE + TX_BUFFER_SIZE) * UART_COUNT) >= (RAMEND - 0x60)
79
+#error SERIAL BUFFER TOO LARGE!
80
+#endif
81
+
82
+// serialRegisters
83
+#define SERIALDATA  0
84
+#define SERIALB     1
85
+#define SERIALC     2
86
+#define SERIALA     3
87
+#define SERIALUBRRH 4
88
+#define SERIALUBRRL 5
89
+
90
+// serialBits
91
+#define SERIALUCSZ0 0
92
+#define SERIALUCSZ1 1
93
+#define SERIALRXCIE 2
94
+#define SERIALRXEN  3
95
+#define SERIALTXEN  4
96
+#define SERIALUDRIE 5
97
+#define SERIALUDRE  6
98
+
99
+uint8_t volatile rxBuffer[UART_COUNT][RX_BUFFER_SIZE];
100
+uint8_t volatile txBuffer[UART_COUNT][TX_BUFFER_SIZE];
101
+uint16_t volatile rxRead[UART_COUNT];
102
+uint16_t volatile rxWrite[UART_COUNT];
103
+uint16_t volatile txRead[UART_COUNT];
104
+uint16_t volatile txWrite[UART_COUNT];
105
+uint8_t volatile shouldStartTransmission[UART_COUNT];
106
+
107
+#ifdef FLOWCONTROL
108
+uint8_t volatile sendThisNext[UART_COUNT];
109
+uint8_t volatile flow[UART_COUNT];
110
+uint8_t volatile rxBufferElements[UART_COUNT];
111
+#endif
112
+
113
+uint8_t serialAvailable(void) {
114
+    return UART_COUNT;
115
+}
116
+
117
+void serialInit(uint8_t uart, uint16_t baud) {
118
+    if (uart >= UART_COUNT)
119
+        return;
120
+
121
+    // Initialize state variables
122
+    rxRead[uart] = 0;
123
+    rxWrite[uart] = 0;
124
+    txRead[uart] = 0;
125
+    txWrite[uart] = 0;
126
+    shouldStartTransmission[uart] = 1;
127
+#ifdef FLOWCONTROL
128
+    sendThisNext[uart] = 0;
129
+    flow[uart] = 1;
130
+    rxBufferElements[uart] = 0;
131
+#endif
132
+
133
+    // Default Configuration: 8N1
134
+    *serialRegisters[uart][SERIALC] = (1 << serialBits[uart][SERIALUCSZ0]) | (1 << serialBits[uart][SERIALUCSZ1]);
135
+
136
+    // Set baudrate
137
+#if SERIALBAUDBIT == 8
138
+    *serialRegisters[uart][SERIALUBRRH] = (baud >> 8);
139
+    *serialRegisters[uart][SERIALUBRRL] = baud;
140
+#else
141
+    *serialBaudRegisters[uart] = baud;
142
+#endif
143
+
144
+    *serialRegisters[uart][SERIALB] = (1 << serialBits[uart][SERIALRXCIE]); // Enable Interrupts
145
+    *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALRXEN]) | (1 << serialBits[uart][SERIALTXEN]); // Enable Receiver/Transmitter
146
+}
147
+
148
+void serialClose(uint8_t uart) {
149
+    if (uart >= UART_COUNT)
150
+        return;
151
+
152
+    uint8_t sreg = SREG;
153
+    sei();
154
+    while (!serialTxBufferEmpty(uart));
155
+    while (*serialRegisters[uart][SERIALB] & (1 << serialBits[uart][SERIALUDRIE])); // Wait while Transmit Interrupt is on
156
+    cli();
157
+    *serialRegisters[uart][SERIALB] = 0;
158
+    *serialRegisters[uart][SERIALC] = 0;
159
+    SREG = sreg;
160
+}
161
+
162
+#ifdef FLOWCONTROL
163
+void setFlow(uint8_t uart, uint8_t on) {
164
+    if (uart >= UART_COUNT)
165
+        return;
166
+
167
+    if (flow[uart] != on) {
168
+        if (on == 1) {
169
+            // Send XON
170
+            while (sendThisNext[uart] != 0);
171
+            sendThisNext[uart] = XON;
172
+            flow[uart] = 1;
173
+            if (shouldStartTransmission[uart]) {
174
+                shouldStartTransmission[uart] = 0;
175
+                *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]);
176
+                *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
177
+            }
178
+        } else {
179
+            // Send XOFF
180
+            sendThisNext[uart] = XOFF;
181
+            flow[uart] = 0;
182
+            if (shouldStartTransmission[uart]) {
183
+                shouldStartTransmission[uart] = 0;
184
+                *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]);
185
+                *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
186
+            }
187
+        }
188
+        // Wait till it's transmitted
189
+        while (*serialRegisters[uart][SERIALB] & (1 << serialBits[uart][SERIALUDRIE]));
190
+    }
191
+}
192
+#endif
193
+
194
+// ---------------------
195
+// |     Reception     |
196
+// ---------------------
197
+
198
+uint8_t serialHasChar(uint8_t uart) {
199
+    if (uart >= UART_COUNT)
200
+        return 0;
201
+
202
+    if (rxRead[uart] != rxWrite[uart]) { // True if char available
203
+        return 1;
204
+    } else {
205
+        return 0;
206
+    }
207
+}
208
+
209
+uint8_t serialGetBlocking(uint8_t uart) {
210
+    if (uart >= UART_COUNT)
211
+        return 0;
212
+
213
+    while(!serialHasChar(uart));
214
+    return serialGet(uart);
215
+}
216
+
217
+uint8_t serialGet(uint8_t uart) {
218
+    if (uart >= UART_COUNT)
219
+        return 0;
220
+
221
+    uint8_t c;
222
+
223
+#ifdef FLOWCONTROL
224
+    rxBufferElements[uart]--;
225
+    if ((flow[uart] == 0) && (rxBufferElements[uart] <= FLOWMARK)) {
226
+        while (sendThisNext[uart] != 0);
227
+        sendThisNext[uart] = XON;
228
+        flow[uart] = 1;
229
+        if (shouldStartTransmission[uart]) {
230
+            shouldStartTransmission[uart] = 0;
231
+            *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]); // Enable Interrupt
232
+            *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
233
+        }
234
+    }
235
+#endif
236
+
237
+    if (rxRead[uart] != rxWrite[uart]) {
238
+        c = rxBuffer[uart][rxRead[uart]];
239
+        rxBuffer[uart][rxRead[uart]] = 0;
240
+        if (rxRead[uart] < (RX_BUFFER_SIZE - 1)) {
241
+            rxRead[uart]++;
242
+        } else {
243
+            rxRead[uart] = 0;
244
+        }
245
+        return c;
246
+    } else {
247
+        return 0;
248
+    }
249
+}
250
+
251
+uint8_t serialRxBufferFull(uint8_t uart) {
252
+    if (uart >= UART_COUNT)
253
+        return 0;
254
+
255
+    return (((rxWrite[uart] + 1) == rxRead[uart]) || ((rxRead[uart] == 0) && ((rxWrite[uart] + 1) == RX_BUFFER_SIZE)));
256
+}
257
+
258
+uint8_t serialRxBufferEmpty(uint8_t uart) {
259
+    if (uart >= UART_COUNT)
260
+        return 0;
261
+
262
+    if (rxRead[uart] != rxWrite[uart]) {
263
+        return 0;
264
+    } else {
265
+        return 1;
266
+    }
267
+}
268
+
269
+// ----------------------
270
+// |    Transmission    |
271
+// ----------------------
272
+
273
+void serialWrite(uint8_t uart, uint8_t data) {
274
+    if (uart >= UART_COUNT)
275
+        return;
276
+
277
+#ifdef SERIALINJECTCR
278
+    if (data == '\n') {
279
+        serialWrite(uart, '\r');
280
+    }
281
+#endif
282
+    while (serialTxBufferFull(uart));
283
+
284
+    txBuffer[uart][txWrite[uart]] = data;
285
+    if (txWrite[uart] < (TX_BUFFER_SIZE - 1)) {
286
+        txWrite[uart]++;
287
+    } else {
288
+        txWrite[uart] = 0;
289
+    }
290
+    if (shouldStartTransmission[uart]) {
291
+        shouldStartTransmission[uart] = 0;
292
+        *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]); // Enable Interrupt
293
+        *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
294
+    }
295
+}
296
+
297
+void serialWriteString(uint8_t uart, const char *data) {
298
+    if (uart >= UART_COUNT)
299
+        return;
300
+
301
+    if (data == 0) {
302
+        serialWriteString(uart, "NULL");
303
+    } else {
304
+        while (*data != '\0') {
305
+            serialWrite(uart, *data++);
306
+        }
307
+    }
308
+}
309
+
310
+uint8_t serialTxBufferFull(uint8_t uart) {
311
+    if (uart >= UART_COUNT)
312
+        return 0;
313
+
314
+    return (((txWrite[uart] + 1) == txRead[uart]) || ((txRead[uart] == 0) && ((txWrite[uart] + 1) == TX_BUFFER_SIZE)));
315
+}
316
+
317
+uint8_t serialTxBufferEmpty(uint8_t uart) {
318
+    if (uart >= UART_COUNT)
319
+        return 0;
320
+
321
+    if (txRead[uart] != txWrite[uart]) {
322
+        return 0;
323
+    } else {
324
+        return 1;
325
+    }
326
+}
327
+
328
+void serialReceiveInterrupt(uint8_t uart) {
329
+    rxBuffer[uart][rxWrite[uart]] = *serialRegisters[uart][SERIALDATA];
330
+    if (rxWrite[uart] < (RX_BUFFER_SIZE - 1)) {
331
+        rxWrite[uart]++;
332
+    } else {
333
+        rxWrite[uart] = 0;
334
+    }
335
+
336
+#ifdef FLOWCONTROL
337
+    rxBufferElements[uart]++;
338
+    if ((flow[uart] == 1) && (rxBufferElements[uart] >= (RX_BUFFER_SIZE - FLOWMARK))) {
339
+        sendThisNext[uart] = XOFF;
340
+        flow[uart] = 0;
341
+        if (shouldStartTransmission[uart]) {
342
+            shouldStartTransmission[uart] = 0;
343
+            *serialRegisters[uart][SERIALB] |= (1 << serialBits[uart][SERIALUDRIE]); // Enable Interrupt
344
+            *serialRegisters[uart][SERIALA] |= (1 << serialBits[uart][SERIALUDRE]); // Trigger Interrupt
345
+        }
346
+    }
347
+#endif
348
+}
349
+
350
+void serialTransmitInterrupt(uint8_t uart) {
351
+#ifdef FLOWCONTROL
352
+    if (sendThisNext[uart]) {
353
+        *serialRegisters[uart][SERIALDATA] = sendThisNext[uart];
354
+        sendThisNext[uart] = 0;
355
+    } else {
356
+#endif
357
+        if (txRead[uart] != txWrite[uart]) {
358
+            *serialRegisters[uart][SERIALDATA] = txBuffer[uart][txRead[uart]];
359
+            if (txRead[uart] < (TX_BUFFER_SIZE -1)) {
360
+                txRead[uart]++;
361
+            } else {
362
+                txRead[uart] = 0;
363
+            }
364
+        } else {
365
+            shouldStartTransmission[uart] = 1;
366
+            *serialRegisters[uart][SERIALB] &= ~(1 << serialBits[uart][SERIALUDRIE]); // Disable Interrupt
367
+        }
368
+#ifdef FLOWCONTROL
369
+    }
370
+#endif
371
+}
372
+
373
+ISR(SERIALRECIEVEINTERRUPT) { // Receive complete
374
+    serialReceiveInterrupt(0);
375
+}
376
+
377
+ISR(SERIALTRANSMITINTERRUPT) { // Data register empty
378
+    serialTransmitInterrupt(0);
379
+}
380
+
381
+#if UART_COUNT > 1
382
+ISR(SERIALRECIEVEINTERRUPT1) { // Receive complete
383
+    serialReceiveInterrupt(1);
384
+}
385
+
386
+ISR(SERIALTRANSMITINTERRUPT1) { // Data register empty
387
+    serialTransmitInterrupt(1);
388
+}
389
+#endif
390
+
391
+#if UART_COUNT > 2
392
+ISR(SERIALRECIEVEINTERRUPT2) { // Receive complete
393
+    serialReceiveInterrupt(2);
394
+}
395
+
396
+ISR(SERIALTRANSMITINTERRUPT2) { // Data register empty
397
+    serialTransmitInterrupt(2);
398
+}
399
+#endif
400
+
401
+#if UART_COUNT > 3
402
+ISR(SERIALRECIEVEINTERRUPT3) { // Receive complete
403
+    serialReceiveInterrupt(3);
404
+}
405
+
406
+ISR(SERIALTRANSMITINTERRUPT3) { // Data register empty
407
+    serialTransmitInterrupt(3);
408
+}
409
+#endif
410
+/** @} */

+ 8
- 0
src/spi.c Vedi File

@@ -5,11 +5,19 @@
5 5
 #include "spi.h"
6 6
 
7 7
 void spiInit(void) {
8
+#ifdef DEBUG
9
+    DDRB |= (1 << PB0);  // SI output
10
+    DDRD &= ~(1 << PD4); // SO input
11
+    DDRD |= (1 << PD2);  // SCLK output
12
+    DDRD |= (1 << PD7);  // CS output
13
+    DDRB &= ~(1 << PB4); // GDO0 input
14
+#else
8 15
     DDRB |= (1 << PB2);  // SI output
9 16
     DDRB &= ~(1 << PB3); // SO input
10 17
     DDRB |= (1 << PB4);  // SCLK output
11 18
     DDRB |= (1 << PB1);  // CS output
12 19
     DDRB &= ~(1 << PB0); // GDO0 input
20
+#endif
13 21
 
14 22
     SCK_off;
15 23
     MO_off;

+ 11
- 0
src/timer.c Vedi File

@@ -10,14 +10,25 @@
10 10
 volatile time_t systemTime = 0;
11 11
 
12 12
 void timerInit(void) {
13
+#ifdef DEBUG
14
+    TCCR2A |= (1 << WGM21); // CTC Mode
15
+    TCCR2B |= (1 << CS22); // Prescaler: 64
16
+    OCR2A = 250; // Count to 250
17
+    TIMSK2 |= (1 << OCIE2A); // Enable compare match interrupt
18
+#else
13 19
     // Using 8bit Timer1
14 20
     TCCR1 |= (1 << CTC1); // CTC Mode
15 21
     TCCR1 |= (1 << CS12) | (1 << CS11) | (1 << CS10); // Prescaler: 64
16 22
     OCR1A = 250; // Count to 250
17 23
     TIMSK |= (1 << OCIE1A); // Enable compare match interrupt
24
+#endif
18 25
 }
19 26
 
27
+#ifdef DEBUG
28
+ISR(TIMER2_COMPA_vect) {
29
+#else
20 30
 ISR(TIMER1_COMPA_vect) {
31
+#endif
21 32
     systemTime++; // one millisecond has passed
22 33
 }
23 34
 

Loading…
Annulla
Salva