1 | // usart.h
|
2 | #ifndef USART_H
|
3 | #define USART_H 1
|
4 |
|
5 | #define USART_BAUD_MIDI (((F_CPU/16)/31250)-1)
|
6 | #define USART0_SIZE_RX 16
|
7 | #define USART0_SIZE_TX 16
|
8 | void usart0_rxpuff_null(void); // RX puffer => 0
|
9 | void usart0_txpuff_null(void); // TX puffer => 0
|
10 | unsigned char usart0_rxsymbol_count(); // Zustand von RX Puffer
|
11 | unsigned char usart0_txsymbol_count(); // Zustand von TX Puffer
|
12 | void usart0_rxpuffein(unsigned char data); // byte aus RX0 in puffer lesen
|
13 | unsigned char usart0_rxpuffaus(void); // byte aus Puffer lesen
|
14 | void usart0_txpuff_null(void); // TX puffer = 0
|
15 | void usart0_txpuffein(unsigned char data); // byte in TX puffer lesen
|
16 | void usart0_txpuffaus(void);// byte aus TX Puffer senden, in interrupt tx
|
17 |
|
18 | static inline void usart0_init(void){
|
19 | UBRR0H = (uint8_t)(USART_BAUD_MIDI>>8);
|
20 | UBRR0L = (uint8_t)USART_BAUD_MIDI;
|
21 | UCSR0A = 0;
|
22 | UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
|
23 | UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
|
24 | usart0_rxpuff_null();
|
25 | usart0_txpuff_null();
|
26 | }
|
27 |
|
28 | #endif /* USART_H */
|
29 |
|
30 | // usart.c
|
31 | #include <avr/io.h> // Muss immer sein
|
32 | #include <inttypes.h> // Fuer Datentyp
|
33 | #include <avr/pgmspace.h> // Fuer Flash
|
34 |
|
35 | #include "main.h" // Allgemeine Programmablauf
|
36 | #include "usart.h" // USART
|
37 | #include "lcd.h" // LCD
|
38 |
|
39 | static unsigned char rx_kopf;
|
40 | static unsigned char rx_schwanz;
|
41 | static unsigned char rx_symbol_count;
|
42 | static unsigned char rx_puffer[USART0_SIZE_RX];
|
43 |
|
44 | static unsigned char tx_kopf;
|
45 | static unsigned char tx_schwanz;
|
46 | static unsigned char tx_symbol_count;
|
47 | static unsigned char tx_puffer[USART0_SIZE_TX];
|
48 |
|
49 | void usart0_rxpuff_null(void){ // puffer = 0
|
50 |
|
51 | rx_schwanz = 0;
|
52 | rx_kopf = 0;
|
53 | rx_symbol_count = 0;
|
54 | }
|
55 |
|
56 | void usart0_txpuff_null(void){ // puffer = 0
|
57 |
|
58 | tx_schwanz = 0;
|
59 | tx_kopf = 0;
|
60 | tx_symbol_count = 0;
|
61 | }
|
62 |
|
63 | unsigned char usart0_rxsymbol_count(){
|
64 |
|
65 | return rx_symbol_count;
|
66 | }
|
67 |
|
68 | unsigned char usart0_txsymbol_count(){
|
69 |
|
70 | return tx_symbol_count;
|
71 | }
|
72 |
|
73 | static void count_inc(unsigned char *count, unsigned char wert){
|
74 | (*count)++;
|
75 | if(*count >= wert){
|
76 | *count = 0;
|
77 | }
|
78 | }
|
79 |
|
80 | void usart0_rxpuffein(unsigned char data){ // byte aus RX0 in puffer lesen
|
81 |
|
82 | if(rx_symbol_count < USART0_SIZE_RX){
|
83 | // Wenn puffer noch Platz hat
|
84 |
|
85 | rx_puffer[rx_schwanz] = data;
|
86 | rx_symbol_count++;
|
87 |
|
88 | count_inc(&rx_schwanz, USART0_SIZE_RX);
|
89 | }
|
90 | FLAGG &= ~(1<<F_RX0); // Flag fuer Empfang auf Null
|
91 | }
|
92 |
|
93 | void usart0_txpuffein(unsigned char data){ // byte in TX puffer legen
|
94 |
|
95 | if(tx_symbol_count < USART0_SIZE_TX){
|
96 | // Wenn puffer noch Platz hat
|
97 |
|
98 | tx_puffer[tx_schwanz] = data;
|
99 | tx_symbol_count++;
|
100 |
|
101 | count_inc(&tx_schwanz, USART0_SIZE_TX);
|
102 | }
|
103 | }
|
104 |
|
105 | unsigned char usart0_rxpuffaus(void){ // byte aus RX Puffer lesen
|
106 |
|
107 | unsigned char data = 0;
|
108 | data = rx_puffer[rx_kopf];
|
109 | rx_symbol_count--;
|
110 | count_inc(&rx_kopf, USART0_SIZE_RX);
|
111 |
|
112 | return data;;
|
113 | }
|
114 |
|
115 | void usart0_txpuffaus(void){ // byte aus TX Puffer senden
|
116 |
|
117 | UDR0 = tx_puffer[tx_kopf];
|
118 | tx_symbol_count--;
|
119 | count_inc(&tx_kopf, USART0_SIZE_TX);
|
120 | }
|
121 |
|
122 | // midi.h
|
123 | #ifndef MIDI_H
|
124 | #define MIDI_H 1
|
125 |
|
126 | #define ACTIVE_SENSING 0xfe
|
127 |
|
128 | void midi_lcd(unsigned char midi_byte);
|
129 | // Gibt auf Indikator Leerzeichen und Ziffer
|
130 |
|
131 | void midi_puff_schieb(unsigned int data );
|
132 | // schieben fuer MIDI: int=2x char und Leerzeichen
|
133 | #endif /* MIDI_H */
|
134 |
|
135 | // midi.c
|
136 | #include <avr/io.h> // Muss immer sein
|
137 | #include <inttypes.h> // Fuer Datentyp
|
138 | #include <avr/pgmspace.h> // Fuer Flash
|
139 |
|
140 | #include "main.h" // Allgemeine Programmablauf
|
141 | #include "lcd.h" // LCD
|
142 | #include "midi.h" // MIDI
|
143 | #include "led.h" // LED, fuer LED_F_NUM
|
144 |
|
145 | void midi_lcd(unsigned char midi_byte){ // Gibt auf Indikator Leerzeichen und Ziffer
|
146 | if(midi_byte != ACTIVE_SENSING){ // Synchro-Byte ausschliessen
|
147 | unsigned int midizif;
|
148 | midizif = lcd_ziffer(midi_byte);
|
149 | midi_puff_schieb(midizif);
|
150 | } else { // Led F kurz einschalten, wenn ACTIVE_SENSING
|
151 | led_ein_time((1<<LED_F_NUM),50);
|
152 | }
|
153 | }
|
154 |
|
155 | void midi_puff_schieb(unsigned int data ){ // schieben fuer MIDI: int=2x char und Leerzeichen
|
156 | unsigned int a;
|
157 | unsigned char b;
|
158 | a = (data >> 8);
|
159 | b = (unsigned char)a;
|
160 | lcd_puff_schieb_links(b); // Dec
|
161 | b = (unsigned char)data;
|
162 | lcd_puff_schieb_links(b); // Eins
|
163 | lcd_puff_schieb_links(' '); // Leerzeichen
|
164 | }
|
165 |
|
166 | // main.h
|
167 | #ifndef MAIN_H
|
168 | #define MAIN_H 1
|
169 |
|
170 | #ifndef F_CPU // Quarz 16 MHz.
|
171 | #define F_CPU 16000000UL // CPU_F fuer Verzoegerungen
|
172 | #endif
|
173 |
|
174 | #ifndef FLAGG
|
175 | #define FLAGG GPIOR0 /* fuer Ereignisse */
|
176 | #define F_PULS 0 /* Puls 1000 Hz, timer 3 interrupt */
|
177 | #define F_RX0 1 /* MIDI-Nachricht gekommen */
|
178 | #define F_TX0 2 /* MIDI-Nachricht versandt */
|
179 | #endif
|
180 |
|
181 | /**********************************************************/
|
182 |
|
183 |
|
184 | #endif /* MAIN_H */
|
185 |
|
186 | // main.c
|
187 | #include <avr/io.h> // Muss immer sein
|
188 | #include <stdio.h> // Die Ein- und Ausgabefunktionen,
|
189 | // Typen und Makros
|
190 | #include <stdlib.h> // Funktionen zur Umwandlung von Zahlen,
|
191 | // fuer Speicherverwaltung und aehnliche Aufgaben.
|
192 | #include <string.h> // Funktionen fuer Zeichenketten
|
193 | #include <inttypes.h> // Fuer Datentyp
|
194 | #include <avr/interrupt.h> // Fuer Interrupts
|
195 | #include <avr/eeprom.h> // Fuer EEPROM
|
196 | #include <avr/pgmspace.h> // Fuer Flash
|
197 | #include <util/delay.h> // Fuer Verzoegerungen
|
198 |
|
199 | #include "main.h" // Allgemeine Programmablauf
|
200 | #include "led.h" // LED
|
201 | #include "knopf.h" // Knopf
|
202 | #include "drehgeber.h" // Drehgeber
|
203 | #include "timer.h" // Systempuls
|
204 | #include "spi.h" // SPI
|
205 | #include "lcv1024.h" // NVRAM
|
206 | #include "lcd.h" // LCD
|
207 | #include "usart.h" // USART
|
208 | #include "midi.h" // MIDI
|
209 | #include "logik.h" // Logik
|
210 |
|
211 | ISR(USART0_RX_vect){ // USART0, Rx Complete
|
212 |
|
213 | FLAGG |= (1<<F_RX0); // Flag fuer Empfang einsetzen
|
214 | usart0_rxpuffein(UDR0); // In Puffer
|
215 | }
|
216 |
|
217 | int main(void){
|
218 |
|
219 | /******* init *******/
|
220 |
|
221 | system_init();
|
222 |
|
223 | sei(); // Interrupts erlauben
|
224 |
|
225 | /* * * */
|
226 |
|
227 | while(1){
|
228 |
|
229 | // Bedienung von Puls 1 ms
|
230 | if( FLAGG & (1<<F_PULS) ){
|
231 |
|
232 | FLAGG &= ~(1<<F_PULS); // Flag fuer Puls = 0
|
233 |
|
234 | /* * etwas, was jede 1 ms gemacht sein sollte * */
|
235 | }
|
236 |
|
237 | // Pruefen, ob TX-Puffer etwas hat.
|
238 | // Wenn TX-Puffer nicht leer und fruehere Sendung zu Ende
|
239 | if((usart0_txsymbol_count()) && (UCSR0A & (1<<UDRE0))){
|
240 | usart0_txpuffaus();
|
241 | }
|
242 |
|
243 |
|
244 |
|
245 | /* RX bedienen */
|
246 | if(usart0_rxsymbol_count()){ // wenn rx-Puffer nicht leer
|
247 | unsigned char data;
|
248 | data = usart0_rxpuffaus();
|
249 | if(data != ACTIVE_SENSING){
|
250 | midi_puff_schieb(lcd_ziffer(data));
|
251 | } else {
|
252 | led_ein_time((1<<LED_F_NUM),70);
|
253 | }
|
254 | }
|
255 |
|
256 | }
|
257 | return 0;
|
258 | }
|