Skip to content

Commit 8bba9f0

Browse files
author
Tim Essig
committed
First working prototype(one universe output)
1 parent fa181bc commit 8bba9f0

File tree

9 files changed

+987
-174
lines changed

9 files changed

+987
-174
lines changed

display.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include "display.h"
2+
3+
#include <avr/io.h>
4+
#include <avr/interrupt.h>
5+
#include <util/delay.h>
6+
7+
#define Takt_TWI 400000
8+
#define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
9+
#define TWI_BAUDRATE TWI_BAUD(F_CPU, Takt_TWI)
10+
11+
12+
uint8_t displayfunction = 0x00;
13+
uint8_t displaycontrol = 0x00;
14+
uint8_t displaymode = 0x00;
15+
uint8_t backlightVal = LCD_BACKLIGHT;
16+
17+
void setupTWI(void) {
18+
TWIC.MASTER.BAUD = TWI_BAUDRATE;
19+
20+
TWIC.MASTER.CTRLA = TWI_MASTER_WIF_bm | TWI_MASTER_ENABLE_bm | TWI_MASTER_INTLVL_gm; //Enable Write Interupt Flag, Enable Master, Interrupt Level 0
21+
22+
//RESET Bus State
23+
TWIC.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
24+
}
25+
26+
27+
void twiWrite(unsigned char byte) {
28+
TWIC.MASTER.ADDR = LCD_ADDR;
29+
while((TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm) == 0);
30+
31+
TWIC.MASTER.DATA = byte;
32+
while((TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm) == 0);
33+
}
34+
35+
36+
void writeStr(char value[]) {
37+
while(*value != 0) {
38+
send(*value++, Rs);
39+
}
40+
}
41+
42+
void writeInt(uint8_t value) {
43+
char str[4];
44+
45+
itoa(value, str, 10);
46+
writeStr(str);
47+
}
48+
49+
50+
void write(uint8_t value) {
51+
send(value, Rs);
52+
}
53+
54+
void writeDirect(uint8_t b) {
55+
twiWrite(b | backlightVal);
56+
}
57+
58+
void pulseEnable(uint8_t _data){
59+
writeDirect(_data | En); // En high
60+
_delay_ms(1); // enable pulse must be >450ns
61+
62+
writeDirect(_data & ~En); // En low
63+
_delay_ms(1); // commands need > 37us to settle
64+
}
65+
66+
void write4bits(uint8_t data) {
67+
writeDirect(data);
68+
pulseEnable(data);
69+
}
70+
71+
void send(uint8_t value, uint8_t mode) {
72+
uint8_t highnib=value&0xf0;
73+
uint8_t lownib=(value<<4)&0xf0;
74+
write4bits((highnib)|mode);
75+
write4bits((lownib)|mode);
76+
}
77+
78+
void command(uint8_t value) {
79+
send(value, 0);
80+
}
81+
82+
83+
84+
/**
85+
* Setup the Display
86+
*/
87+
void setupDisplay(void) {
88+
displayfunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS;
89+
90+
91+
//put the LCD into 4 bit mode
92+
// this is according to the hitachi HD44780 datasheet
93+
// figure 24, pg 46
94+
95+
//_delay_ms(1000);
96+
97+
// we start in 8bit mode, try to set 4 bit mode
98+
write4bits(0x03 << 4);
99+
_delay_ms(5); // wait min 4.1ms
100+
101+
// second try
102+
write4bits(0x03 << 4);
103+
_delay_ms(5); // wait min 4.1ms
104+
105+
// third go!
106+
write4bits(0x03 << 4);
107+
_delay_ms(1);
108+
109+
// finally, set to 4-bit interface
110+
write4bits(0x02 << 4);
111+
112+
// set # lines, font size, etc.
113+
command(LCD_FUNCTIONSET | displayfunction);
114+
115+
// turn the display on with no cursor or blinking default
116+
displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
117+
command(LCD_DISPLAYCONTROL | displaycontrol);
118+
119+
120+
command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
121+
_delay_ms(20); // this command takes a long time!
122+
123+
// Initialize to default text direction (for roman languages)
124+
displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
125+
126+
// set the entry mode
127+
command(LCD_ENTRYMODESET | displaymode);
128+
129+
command(LCD_RETURNHOME); // set cursor position to zero
130+
_delay_ms(20); // this command takes a long time!
131+
132+
backlightVal = LCD_BACKLIGHT;
133+
}
134+
135+
void setCursor(uint8_t col, uint8_t row) {
136+
int numlines = 2;
137+
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
138+
if ( row > numlines ) {
139+
row = numlines-1; // we count rows starting w/0
140+
}
141+
command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
142+
}
143+
144+
void clearDisplay(void) {
145+
command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
146+
_delay_ms(20); // this command takes a long time!
147+
}

display.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
#define DISPLAY_ADDR 0x3F
1+
#ifndef _DISPLAY_H
2+
#define _DISPLAY_H 1
3+
4+
5+
#include <avr/io.h>
6+
#include <avr/interrupt.h>
7+
#include <util/delay.h>
8+
9+
#define LCD_ADDR (0x3F << 1)
10+
211

312
// commands
413
#define LCD_CLEARDISPLAY 0x01
@@ -47,7 +56,15 @@
4756
#define Rs 1 << 0 // B00000001 // Register select bit
4857

4958

50-
uint8_t displayfunction = 0x00;
51-
uint8_t displaycontrol = 0x00;
52-
uint8_t displaymode = 0x00;
53-
uint8_t backlightVal = LCD_BACKLIGHT;
59+
extern void setupTWI(void);
60+
extern void twiWrite(unsigned char byte);
61+
extern void writeStr(char* value);
62+
extern void writeInt(uint8_t value);
63+
extern void write(uint8_t value);
64+
65+
extern void setupDisplay(void);
66+
extern void setCursor(uint8_t col, uint8_t row);
67+
68+
extern void clearDisplay(void);
69+
70+
#endif

dmx.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#include "dmx.h"
2+
3+
#include <avr/io.h>
4+
#include <avr/interrupt.h>
5+
#include <util/delay.h>
6+
7+
8+
9+
10+
uint8_t dmxBuffer[DMX_NUM_UNIVERSES][DMX_UNIVERSE_SIZE];
11+
12+
uint8_t* getUniverseBuffer(uint8_t universe) {
13+
return dmxBuffer[universe];
14+
}
15+
16+
17+
enum DMX_STATE {
18+
DMX_IDLE,
19+
DMX_BREAK,
20+
DMX_START,
21+
DMX_RUN
22+
};
23+
24+
25+
enum DMX_STATE dmx0state = DMX_IDLE;
26+
enum DMX_STATE dmx1state = DMX_IDLE;
27+
enum DMX_STATE dmx2state = DMX_IDLE;
28+
enum DMX_STATE dmx3state = DMX_IDLE;
29+
uint16_t dmx0ch = 0;
30+
uint16_t dmx1ch = 0;
31+
uint16_t dmx2ch = 0;
32+
uint16_t dmx3ch = 0;
33+
34+
35+
#define DMX_BAUD_BSCALE 0 // vorher 0b1001 -> -1
36+
#define DMX_BAUD_RESET_BSEL 15 // 125k BAUD @32Mhz, used for RESET
37+
#define DMX_BAUD_NORMAL_BSEL 7 // 250k BAUD @32Mhz
38+
39+
#define UART0 USARTD0
40+
41+
void setupDMXPort(USART_t* uart) {
42+
uart->BAUDCTRLB = DMX_BAUD_BSCALE << 4;
43+
uart->BAUDCTRLA = DMX_BAUD_RESET_BSEL;
44+
45+
uart->CTRLA = USART_TXCINTLVL_gm; // TX Highest INT Level
46+
uart->CTRLC = USART_SBMODE_bm | USART_CHSIZE_8BIT_gc; //2 StopBits, 8 DataBits
47+
48+
49+
uart->CTRLB = USART_TXEN_bm; //Enable TX
50+
}
51+
52+
void setupDMX(void) {
53+
54+
55+
//DMX 3
56+
PORTD.DIRSET = PIN3_bm; // Pin 3 -> UART 0 TX
57+
PORTD.PIN3CTRL = PORT_INVEN_bm;
58+
setupDMXPort(&USARTD0);
59+
60+
//DMX 4
61+
PORTE.DIRSET = PIN3_bm; // Pin 3 -> UART 0 TX
62+
PORTE.PIN3CTRL = PORT_INVEN_bm;
63+
setupDMXPort(&USARTE0);
64+
}
65+
66+
67+
void startDMX_TX(void) {
68+
69+
if(dmx0state == DMX_IDLE) {
70+
PORTA.OUTSET = 0x01;
71+
72+
//Set Baud
73+
UART0.BAUDCTRLA = DMX_BAUD_RESET_BSEL;
74+
UART0.BAUDCTRLB = DMX_BAUD_BSCALE << 4;
75+
76+
//Send Break Byte
77+
while (!( UART0.STATUS & USART_DREIF_bm));
78+
UART0.DATA = 0x00;
79+
80+
dmx0state = DMX_START;
81+
}
82+
83+
}
84+
85+
ISR(USARTD0_TXC_vect) //Transimission complete
86+
{
87+
88+
switch(dmx0state) {
89+
case DMX_START:
90+
//Change Baudrate
91+
UART0.BAUDCTRLA = DMX_BAUD_NORMAL_BSEL;
92+
UART0.BAUDCTRLB = DMX_BAUD_BSCALE << 4;
93+
94+
//SEND START Byte
95+
UART0.DATA = 0x00;
96+
97+
98+
dmx0ch = 0;
99+
dmx0state = DMX_RUN;
100+
101+
break;
102+
case DMX_RUN:
103+
PORTA.OUTSET = 0x02;
104+
105+
UART0.DATA = dmxBuffer[0][dmx0ch++];
106+
107+
if(dmx0ch >= 512) {
108+
dmx0state = DMX_IDLE;
109+
PORTA.OUTCLR = 0x03;
110+
//_delay_ms(500);
111+
}
112+
break;
113+
114+
}
115+
}

dmx.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef _DMX_H
2+
#define _DMX_H 1
3+
4+
#include <avr/io.h>
5+
6+
#define DMX_NUM_UNIVERSES 4
7+
#define DMX_UNIVERSE_SIZE 512
8+
9+
extern uint8_t dmxBuffer[DMX_NUM_UNIVERSES][DMX_UNIVERSE_SIZE];
10+
11+
12+
extern uint8_t* getUniverseBuffer(uint8_t universe);
13+
14+
15+
extern void setupDMX(void);
16+
extern void startDMX_TX(void);
17+
//extern void startDMX_TX(void);
18+
19+
20+
#endif

0 commit comments

Comments
 (0)