aboutsummaryrefslogtreecommitdiff
path: root/drivers/avr
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/avr')
-rw-r--r--drivers/avr/apa102.c96
-rw-r--r--drivers/avr/apa102.h45
-rw-r--r--drivers/avr/serial.c6
-rw-r--r--drivers/avr/spi_master.c2
-rw-r--r--drivers/avr/spi_master.h2
-rw-r--r--drivers/avr/uart.c170
-rw-r--r--drivers/avr/uart.h35
7 files changed, 210 insertions, 146 deletions
diff --git a/drivers/avr/apa102.c b/drivers/avr/apa102.c
deleted file mode 100644
index 740acb573..000000000
--- a/drivers/avr/apa102.c
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * APA102 lib V1.0a
3 *
4 * Controls APA102 RGB-LEDs
5 * Author: Mikkel (Duckle29 on GitHub)
6 *
7 * Dec 22th, 2017 v1.0a Initial Version
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include "apa102.h"
24#include <avr/interrupt.h>
25#include <avr/io.h>
26#include <util/delay.h>
27#include "debug.h"
28
29// Setleds for standard RGB
30void inline apa102_setleds(LED_TYPE *ledarray, uint16_t leds) { apa102_setleds_pin(ledarray, leds, _BV(RGB_DI_PIN & 0xF), _BV(RGB_CLK_PIN & 0xF)); }
31
32void static inline apa102_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask_DI, uint8_t pinmask_CLK) {
33 setPinOutput(RGB_DI_PIN);
34 setPinOutput(RGB_CLK_PIN);
35
36 apa102_send_array((uint8_t *)ledarray, leds)
37}
38
39void apa102_send_array(uint8_t *data, uint16_t leds) { // Data is struct of 3 bytes. RGB - leds is number of leds in data
40 apa102_start_frame();
41 while (leds--) {
42 apa102_send_frame(0xFF000000 | (data->b << 16) | (data->g << 8) | data->r);
43 data++;
44 }
45 apa102_end_frame(leds);
46}
47
48void apa102_send_frame(uint32_t frame) {
49 for (uint32_t i = 0xFF; i > 0;) {
50 apa102_send_byte(frame & i);
51 i = i << 8;
52 }
53}
54
55void apa102_start_frame() { apa102_send_frame(0); }
56
57void apa102_end_frame(uint16_t leds) {
58 // This function has been taken from: https://github.com/pololu/apa102-arduino/blob/master/APA102.h
59 // and adapted. The code is MIT licensed. I think thats compatible?
60
61 // We need to send some more bytes to ensure that all the LEDs in the
62 // chain see their new color and start displaying it.
63 //
64 // The data stream seen by the last LED in the chain will be delayed by
65 // (count - 1) clock edges, because each LED before it inverts the clock
66 // line and delays the data by one clock edge. Therefore, to make sure
67 // the last LED actually receives the data we wrote, the number of extra
68 // edges we send at the end of the frame must be at least (count - 1).
69 // For the APA102C, that is sufficient.
70 //
71 // The SK9822 only updates after it sees 32 zero bits followed by one more
72 // rising edge. To avoid having the update time depend on the color of
73 // the last LED, we send a dummy 0xFF byte. (Unfortunately, this means
74 // that partial updates of the beginning of an LED strip are not possible;
75 // the LED after the last one you are trying to update will be black.)
76 // After that, to ensure that the last LED in the chain sees 32 zero bits
77 // and a rising edge, we need to send at least 65 + (count - 1) edges. It
78 // is sufficent and simpler to just send (5 + count/16) bytes of zeros.
79 //
80 // We are ignoring the specification for the end frame in the APA102/SK9822
81 // datasheets because it does not actually ensure that all the LEDs will
82 // start displaying their new colors right away.
83
84 apa102_send_byte(0xFF);
85 for (uint16_t i = 0; i < 5 + leds / 16; i++) {
86 apa102_send_byte(0);
87 }
88}
89
90void apa102_send_byte(uint8_t byte) {
91 uint8_t i;
92 for (i = 0; i < 8; i++) {
93 writePin(RGB_DI_PIN, !!(byte & (1 << (7 - i))));
94 writePinHigh(RGB_CLK_PIN);
95 }
96}
diff --git a/drivers/avr/apa102.h b/drivers/avr/apa102.h
deleted file mode 100644
index d4c1e18ee..000000000
--- a/drivers/avr/apa102.h
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * light weight WS2812 lib include
3 *
4 * Version 2.3 - Nev 29th 2015
5 * Author: Tim (cpldcpu@gmail.com)
6 *
7 * Please do not change this file! All configuration is handled in "ws2812_config.h"
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#pragma once
24
25#include <avr/io.h>
26#include <avr/interrupt.h>
27
28#include "color.h"
29
30/* User Interface
31 *
32 * Input:
33 * ledarray: An array of GRB data describing the LED colors
34 * number_of_leds: The number of LEDs to write
35 * pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0)
36 *
37 * The functions will perform the following actions:
38 * - Set the data-out pin as output
39 * - Send out the LED data
40 * - Wait 50�s to reset the LEDs
41 */
42
43void apa102_setleds(LED_TYPE *ledarray, uint16_t number_of_leds);
44void apa102_setleds_pin(LED_TYPE *ledarray, uint16_t number_of_leds, uint8_t pinmask);
45void apa102_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
diff --git a/drivers/avr/serial.c b/drivers/avr/serial.c
index 526a0946b..3647bee0d 100644
--- a/drivers/avr/serial.c
+++ b/drivers/avr/serial.c
@@ -20,7 +20,7 @@
20 20
21#ifdef SOFT_SERIAL_PIN 21#ifdef SOFT_SERIAL_PIN
22 22
23# if !(defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) 23# if !(defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
24# error serial.c is not supported for the currently selected MCU 24# error serial.c is not supported for the currently selected MCU
25# endif 25# endif
26// if using ATmega32U4/2, AT90USBxxx I2C, can not use PD0 and PD1 in soft serial. 26// if using ATmega32U4/2, AT90USBxxx I2C, can not use PD0 and PD1 in soft serial.
@@ -52,8 +52,8 @@
52# define EICRx EICRA 52# define EICRx EICRA
53# endif 53# endif
54 54
55// ATmegaxxU2 specific config 55// ATmegaxxU2/AT90USB162 specific config
56# if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) 56# if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB162__)
57// PD4(INT5), PD6(INT6), PD7(INT7), PC7(INT4) 57// PD4(INT5), PD6(INT6), PD7(INT7), PC7(INT4)
58# if SOFT_SERIAL_PIN == D4 58# if SOFT_SERIAL_PIN == D4
59# define EIMSK_BIT _BV(INT5) 59# define EIMSK_BIT _BV(INT5)
diff --git a/drivers/avr/spi_master.c b/drivers/avr/spi_master.c
index cbec9f36e..19ca0ced4 100644
--- a/drivers/avr/spi_master.c
+++ b/drivers/avr/spi_master.c
@@ -20,7 +20,7 @@
20#include "quantum.h" 20#include "quantum.h"
21#include "timer.h" 21#include "timer.h"
22 22
23#if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) 23#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
24# define SPI_SCK_PIN B1 24# define SPI_SCK_PIN B1
25# define SPI_MOSI_PIN B2 25# define SPI_MOSI_PIN B2
26# define SPI_MISO_PIN B3 26# define SPI_MISO_PIN B3
diff --git a/drivers/avr/spi_master.h b/drivers/avr/spi_master.h
index e36a7c21c..9203698dd 100644
--- a/drivers/avr/spi_master.h
+++ b/drivers/avr/spi_master.h
@@ -21,7 +21,7 @@
21typedef int16_t spi_status_t; 21typedef int16_t spi_status_t;
22 22
23// Hardware SS pin is defined in the header so that user code can refer to it 23// Hardware SS pin is defined in the header so that user code can refer to it
24#if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) 24#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
25# define SPI_SS_PIN B0 25# define SPI_SS_PIN B0
26#elif defined(__AVR_ATmega32A__) 26#elif defined(__AVR_ATmega32A__)
27# define SPI_SS_PIN B4 27# define SPI_SS_PIN B4
diff --git a/drivers/avr/uart.c b/drivers/avr/uart.c
new file mode 100644
index 000000000..c6abcb6fe
--- /dev/null
+++ b/drivers/avr/uart.c
@@ -0,0 +1,170 @@
1/* UART Example for Teensy USB Development Board
2 * http://www.pjrc.com/teensy/
3 * Copyright (c) 2009 PJRC.COM, LLC
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24// Version 1.0: Initial Release
25// Version 1.1: Add support for Teensy 2.0, minor optimizations
26
27#include <avr/io.h>
28#include <avr/interrupt.h>
29
30#include "uart.h"
31
32#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
33# define UDRn UDR1
34# define UBRRnL UBRR1L
35# define UCSRnA UCSR1A
36# define UCSRnB UCSR1B
37# define UCSRnC UCSR1C
38# define U2Xn U2X1
39# define RXENn RXEN1
40# define TXENn TXEN1
41# define RXCIEn RXCIE1
42# define UCSZn1 UCSZ11
43# define UCSZn0 UCSZ10
44# define UDRIEn UDRIE1
45# define USARTn_UDRE_vect USART1_UDRE_vect
46# define USARTn_RX_vect USART1_RX_vect
47#elif defined(__AVR_ATmega32A__)
48# define UDRn UDR
49# define UBRRnL UBRRL
50# define UCSRnA UCSRA
51# define UCSRnB UCSRB
52# define UCSRnC UCSRC
53# define U2Xn U2X
54# define RXENn RXEN
55# define TXENn TXEN
56# define RXCIEn RXCIE
57# define UCSZn1 UCSZ1
58# define UCSZn0 UCSZ0
59# define UDRIEn UDRIE
60# define USARTn_UDRE_vect USART_UDRE_vect
61# define USARTn_RX_vect USART_RX_vect
62#elif defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
63# define UDRn UDR0
64# define UBRRnL UBRR0L
65# define UCSRnA UCSR0A
66# define UCSRnB UCSR0B
67# define UCSRnC UCSR0C
68# define U2Xn U2X0
69# define RXENn RXEN0
70# define TXENn TXEN0
71# define RXCIEn RXCIE0
72# define UCSZn1 UCSZ01
73# define UCSZn0 UCSZ00
74# define UDRIEn UDRIE0
75# define USARTn_UDRE_vect USART_UDRE_vect
76# define USARTn_RX_vect USART_RX_vect
77#endif
78
79// These buffers may be any size from 2 to 256 bytes.
80#define RX_BUFFER_SIZE 64
81#define TX_BUFFER_SIZE 256
82
83static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
84static volatile uint8_t tx_buffer_head;
85static volatile uint8_t tx_buffer_tail;
86static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
87static volatile uint8_t rx_buffer_head;
88static volatile uint8_t rx_buffer_tail;
89
90// Initialize the UART
91void uart_init(uint32_t baud) {
92 cli();
93 UBRRnL = (F_CPU / 4 / baud - 1) / 2;
94 UCSRnA = (1 << U2Xn);
95 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
96 UCSRnC = (1 << UCSZn1) | (1 << UCSZn0);
97 tx_buffer_head = tx_buffer_tail = 0;
98 rx_buffer_head = rx_buffer_tail = 0;
99 sei();
100}
101
102// Transmit a byte
103void uart_putchar(uint8_t c) {
104 uint8_t i;
105
106 i = tx_buffer_head + 1;
107 if (i >= TX_BUFFER_SIZE) i = 0;
108 // return immediately to avoid deadlock when interrupt is disabled(called from ISR)
109 if (tx_buffer_tail == i && (SREG & (1 << SREG_I)) == 0) return;
110 while (tx_buffer_tail == i)
111 ; // wait until space in buffer
112 // cli();
113 tx_buffer[i] = c;
114 tx_buffer_head = i;
115 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn);
116 // sei();
117}
118
119// Receive a byte
120uint8_t uart_getchar(void) {
121 uint8_t c, i;
122
123 while (rx_buffer_head == rx_buffer_tail)
124 ; // wait for character
125 i = rx_buffer_tail + 1;
126 if (i >= RX_BUFFER_SIZE) i = 0;
127 c = rx_buffer[i];
128 rx_buffer_tail = i;
129 return c;
130}
131
132// Return whether the number of bytes waiting in the receive buffer is nonzero.
133// Call this before uart_getchar() to check if it will need
134// to wait for a byte to arrive.
135bool uart_available(void) {
136 uint8_t head, tail;
137
138 head = rx_buffer_head;
139 tail = rx_buffer_tail;
140 if (head >= tail) return (head - tail) > 0;
141 return (RX_BUFFER_SIZE + head - tail) > 0;
142}
143
144// Transmit Interrupt
145ISR(USARTn_UDRE_vect) {
146 uint8_t i;
147
148 if (tx_buffer_head == tx_buffer_tail) {
149 // buffer is empty, disable transmit interrupt
150 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
151 } else {
152 i = tx_buffer_tail + 1;
153 if (i >= TX_BUFFER_SIZE) i = 0;
154 UDRn = tx_buffer[i];
155 tx_buffer_tail = i;
156 }
157}
158
159// Receive Interrupt
160ISR(USARTn_RX_vect) {
161 uint8_t c, i;
162
163 c = UDRn;
164 i = rx_buffer_head + 1;
165 if (i >= RX_BUFFER_SIZE) i = 0;
166 if (i != rx_buffer_tail) {
167 rx_buffer[i] = c;
168 rx_buffer_head = i;
169 }
170}
diff --git a/drivers/avr/uart.h b/drivers/avr/uart.h
new file mode 100644
index 000000000..602eb3d8b
--- /dev/null
+++ b/drivers/avr/uart.h
@@ -0,0 +1,35 @@
1/* UART Example for Teensy USB Development Board
2 * http://www.pjrc.com/teensy/
3 * Copyright (c) 2009 PJRC.COM, LLC
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#pragma once
25
26#include <stdint.h>
27#include <stdbool.h>
28
29void uart_init(uint32_t baud);
30
31void uart_putchar(uint8_t c);
32
33uint8_t uart_getchar(void);
34
35bool uart_available(void);