This code is from project: Adding touch screen to Siglent sds1022c oscilloscope
uart.h
#ifndef _H_UART_H #define _H_UART_H #include "main.h" #include <stdint.h> #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL ) )) -1 ) void uart_init(); uint8_t uart_read(); #endif
uart.c
#include "uart.h"
#include <avr/io.h>
void uart_init() {
UBRR0H = (unsigned char) (BAUD_PRESCALE >> 8);
UBRR0L = (unsigned char) BAUD_PRESCALE;
UCSR0B = (1 << RXEN0);
UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
}
uint8_t uart_read() {
uint8_t wait = 10;
while (!(UCSR0A & (1 << RXC0)) && wait) {
wait--;
}
if (wait > 0)
return UDR0;
return 0;
}
twi.h
#ifndef _H_TWI_H
#define _H_TWI_H
#include "main.h"
#include <compat/twi.h>
#ifndef SCL_CLOCK
#error No SCL clock defined
#endif
#define ACK 1
#define NOACK 0
#define Bcd2Dec(bcd) ((((bcd) >> 4) * 10) + (bcd) %16)
#define Dec2Bcd(dec) (((dec / 10) << 4) + (dec % 10))
void twi_init();
uint8_t twi_read_position(uint8_t *, uint16_t *, uint16_t *,
uint16_t *x2, uint16_t *y2);
#endif
twi.c
#include "twi.h"
static void twi_start(void) {
TWSR = 0;
TWBR = ((F_CPU / SCL_CLOCK - 16) / 2);
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
}
static void twi_stop(void) {
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
while (!(TWCR & (1<<TWSTO)));
}
static void twi_write(uint16_t data) {
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
}
static unsigned char twi_read(uint16_t ack) {
TWCR=ack ? ((1<<TWINT) | (1<<TWEN) | (1<<TWEA)) : ((1<<TWINT) | (1<<TWEN));
while (!(TWCR & (1<<TWINT)));
return TWDR;
}
void twi_init() {
L(DDRC, PC3);
L(PORTC, PC3);
L(DDRC, PC4);
L(PORTC, PC4);
L(DDRC, PC5);
L(PORTC, PC5);
}
uint8_t twi_read_position(uint8_t *fingers, uint16_t *x1, uint16_t *y1,
uint16_t *x2, uint16_t *y2) {
if (PINC & (1 << PC3))
return 0;
twi_start();
twi_write(0x82);
twi_write(0x10);
twi_stop();
twi_start();
twi_write(0x83);
*fingers = (uint8_t) twi_read(ACK);
*x1 = (uint16_t) twi_read(ACK) | (twi_read(ACK) << 8);
*y1 = (uint16_t) twi_read(ACK) | (twi_read(ACK) << 8);
*x2 = (uint16_t) twi_read(ACK) | (twi_read(ACK) << 8);
*y2 = (uint16_t) twi_read(ACK) | (twi_read(ACK) << 8);
twi_read(NOACK);
twi_stop();
return 1;
}
spi.h
#ifndef _H_SPI_H #define _H_SPI_H #include <stdint.h> void spi_soft_write(uint8_t a, uint8_t b); void spi_settings(); void spi_init(); #endif
spi.c
#include "main.h"
#include "spi.h"
#include "delay.h"
#include <avr/io.h>
void spi_soft_write(uint8_t address, uint8_t data) {
uint8_t i;
H(PORTB, PB1);
delay_us(5);
L(PORTB, PB0);
// 0 - write
L(PORTD, PD7);
delay_us(2);
H(PORTD, PD7);
delay_us(2);
// A4 - A0 address
for(i = 0; i < 5; i++) {
if (address & (1 << (4 - i))) {
H(PORTB, PB0);
} else {
L(PORTB, PB0);
}
L(PORTD, PD7);
delay_us(2);
H(PORTD, PD7);
delay_us(1);
}
// D7 - D0 data
for(i = 0; i < 8; i++) {
if (data & (1 << (7 - i))) {
H(PORTB, PB0);
} else {
L(PORTB, PB0);
}
L(PORTD, PD7);
delay_us(2);
H(PORTD, PD7);
delay_us(1);
}
L(PORTD, PD7);
delay_us(2);
H(PORTD, PD7);
delay_us(2);
delay_us(5);
L(PORTB, PB1);
delay_us(10);
}
void spi_settings() {
// choose imput port and resolution
spi_soft_write(0b00000000, 0b01100111);
// gamma
spi_soft_write(7, 0x1F);
spi_soft_write(8, 0x1F);
spi_soft_write(9, 0xFC);
spi_soft_write(0xA, 0xF3);
spi_soft_write(0xB, 0x02);
spi_soft_write(0xC, 0x01);
spi_soft_write(0xD, 0xFF);
spi_soft_write(0xE, 0xFF);
}
void spi_init() {
H(DDRB, PB0);
L(PORTB, PB0);
H(DDRB, PB1);
L(PORTB, PB1);
H(DDRD, PD7);
H(PORTD, PD7);
}
main.h
#ifndef _H_MAIN_H #define _H_MAIN_H #define __AVR_LIBC_DEPRECATED_ENABLE__ #define F_CPU 16000000L #define SCL_CLOCK 100000L #define USART_BAUDRATE 9600 #define H(a,b) a |=(1<<(b)) #define L(a,b) a &=~(1<<(b)) #endif #ifndef F_CPU #error CPU speed unknown #endif
main.c
#include "main.h"
#include "twi.h"
#include "kbd.h"
#include "delay.h"
#include "spi.h"
#include "uart.h"
#include <stdlib.h> // abs
#include <avr/io.h>
#include <avr/interrupt.h> // sei
#define BUTTON_ARRAY_LEN 7
struct {
uint16_t x1;
uint16_t y1;
uint16_t x2;
uint16_t y2;
uint8_t cmd;
} buttons[BUTTON_ARRAY_LEN] = {
{ .x1 = 700,
.y1 = 100,
.x2 = 800,
.y2 = 0,
.cmd = BTN_MENU_1 },
{ .x1 = 700,
.y1 = 200,
.x2 = 800,
.y2 = 100,
.cmd = BTN_MENU_2 },
{ .x1 = 700,
.y1 = 300,
.x2 = 800,
.y2 = 200,
.cmd = BTN_MENU_3 },
{ .x1 = 700,
.y1 = 400,
.x2 = 800,
.y2 = 300,
.cmd = BTN_MENU_4 },
{ .x1 = 700,
.y1 = 500,
.x2 = 800,
.y2 = 400,
.cmd = BTN_MENU_5 },
{ .x1 = 0,
.y1 = 100,
.x2 = 100,
.y2 = 0,
.cmd = BTN_MENU },
{ .x1 = 0,
.y1 = 200,
.x2 = 100,
.y2 = 100,
.cmd = BTN_TRIGGER }
};
/****************************************************************************/
/* Main */
/****************************************************************************/
int main() {
uint8_t fingers = 0;
uint16_t x1 = 0;
uint16_t old_x1 = 0;
uint16_t y1 = 0;
uint16_t old_y1 = 0;
uint16_t x2 = 0;
uint16_t y2 = 0;
uint16_t x_distance = 0;
uint16_t y_distance = 0;
uint16_t old_x_distance = 0;
uint16_t old_y_distance = 0;
uint8_t uart_cmd = 0;
uint8_t i = 0;
twi_init();
kbd_init();
spi_init();
uart_init();
sei();
spi_settings();
while(1) {
if( (uart_cmd = uart_read()) != 0) {
kbd_cmd(uart_cmd);
kbd_clear();
continue;
}
if (twi_read_position(&fingers, &x1, &y1, &x2, &y2)) {
if(fingers == 3) {
x_distance = abs(x1 - x2);
y_distance = abs(y1 - y2);
if (abs(x_distance - old_x_distance) > 25) {
old_x_distance = x_distance;
continue;
}
if (abs(y_distance - old_y_distance) > 25) {
old_y_distance = y_distance;
continue;
}
if (x_distance > y_distance) {
if (x_distance > old_x_distance + 15) {
kbd_cmd(ENC_HZ_ZOOM_UP);
old_x_distance = x_distance;
} else if(x_distance + 15 < old_x_distance) {
kbd_cmd(ENC_HZ_ZOOM_DW);
old_x_distance = x_distance;
}
} else if (y_distance > x_distance) {
if (y_distance > old_y_distance + 15) {
if (old_y1 < 240) {
kbd_cmd(ENC_CH1_V_DIV_UP);
} else {
kbd_cmd(ENC_CH2_V_DIV_UP);
}
old_y_distance = y_distance;
} else if(y_distance + 15 < old_y_distance) {
if (old_y1 < 240) {
kbd_cmd(ENC_CH1_V_DIV_DW);
} else {
kbd_cmd(ENC_CH2_V_DIV_DW);
}
old_y_distance = y_distance;
}
}
} else if (fingers == 1) {
for(i = 0; i < BUTTON_ARRAY_LEN; i++) {
if (x1 > buttons[i].x1 && x1 < buttons[i].x2 &&
y1 < buttons[i].y1 && y1 > buttons[i].y2) {
kbd_cmd(buttons[i].cmd);
kbd_clear();
delay_ms(100);
old_y1 = y1;
old_x1 = x1;
continue;
}
}
if (abs(y1 - old_y1) > 25) {
old_y1 = y1;
continue;
}
if (abs(x1 - old_x1) > 25) {
old_x1 = x1;
continue;
}
if (y1 > old_y1 + 3) {
if (x1 > 400 && x1 < 500) {
kbd_cmd(ENC_TRIG_LVL_DW);
old_y1 = y1;
old_x1 = x1;
continue;
}
if (old_y1 < 240) {
kbd_cmd(ENC_CH1_V_OFFT_DW);
} else {
kbd_cmd(ENC_CH2_V_OFFT_DW);
}
old_y1 = y1;
old_x1 = x1;
} else if(y1 + 3 < old_y1) {
if (x1 > 400 && x1 < 500) {
kbd_cmd(ENC_TRIG_LVL_UP);
old_y1 = y1;
old_x1 = x1;
continue;
}
if (old_y1 < 240) {
kbd_cmd(ENC_CH1_V_OFFT_UP);
} else {
kbd_cmd(ENC_CH2_V_OFFT_UP);
}
old_y1 = y1;
old_x1 = x1;
}
if (x1 > old_x1 + 3) {
kbd_cmd(ENC_HZ_POS_UP);
old_x1 = x1;
old_y1 = y1;
} else if(x1 + 3 < old_x1) {
kbd_cmd(ENC_HZ_POS_DW);
old_x1 = x1;
old_y1 = y1;
}
}
}
}
}
kbd.h
#ifndef _H_KBD_H #define _H_KBD_H #define ENC_HZ_POS_DW 1 #define ENC_HZ_POS_UP 2 #define ENC_HZ_ZOOM_DW 3 #define ENC_HZ_ZOOM_UP 4 #define ENC_CH1_V_OFFT_DW 5 #define ENC_CH1_V_OFFT_UP 6 #define ENC_CH1_V_DIV_DW 7 #define ENC_CH1_V_DIV_UP 8 #define ENC_CH2_V_OFFT_DW 9 #define ENC_CH2_V_OFFT_UP 10 #define ENC_CH2_V_DIV_DW 11 #define ENC_CH2_V_DIV_UP 12 #define ENC_MENU_DW 13 #define ENC_MENU_UP 14 #define ENC_TRIG_LVL_DW 15 #define ENC_TRIG_LVL_UP 16 #define BTN_SAVE_TO_FLASH 17 #define BTN_REF 18 #define BTN_HELP 19 #define BTN_TRIGGER 20 #define BTN_HZ_POS_RST 21 #define BTN_MENU_5 22 #define BTN_CH2 23 #define BTN_TRIGGER_FORCE 24 #define BTN_CH2_V_OFFT_RST 25 #define BTN_MENU_4 26 #define BTN_MATH 27 #define BTN_DEFAULTS 28 #define BTN_HZ_MASK 29 #define BTN_MENU_3 30 #define BTN_CH1 31 #define BTN_UTILITY 32 #define BTN_TRIGGER_50 33 #define BTN_CH2_V_RATIO 34 #define BTN_MENU_2 35 #define BTN_HZ_MENU 36 #define BTN_SAVE_RECALL 37 #define BTN_TRIGGER_SINGLE 38 #define BTN_CH1_V_RATIO 39 #define BTN_MENU_1 40 #define BTN_MEASURE 41 #define BTN_DISPLAY 42 #define BTN_TRIGGER_RUN_STOP 43 #define BTN_MENU_RST 44 #define BTN_MENU 45 #define BTN_CURSORS 46 #define BTN_ACQUIRE 47 #define BTN_TRIGGER_MENU 48 #define BTN_CH1_V_OFFT_RST 49 #define BIT_SIZE 64 void kbd_clear(); void kbd_cmd(uint8_t cmd); void kbd_init(); #endif
kbd.c
#include "main.h"
#include "delay.h"
#include "kbd.h"
#include <avr/io.h>
#include <avr/interrupt.h>
static uint8_t bits[BIT_SIZE];
static uint8_t cnt = 0;
static uint8_t outer = 0;
static uint8_t send = 0;
void kbd_clear() {
uint8_t i;
for(i = 0; i < BIT_SIZE; i++) {
bits[i] = 0;
}
}
static void kbd_commit() {
send = 1;
while(send) {
delay_us(1);
}
}
SIGNAL(INT0_vect) {
if (!(PIND & (1 << PD2))) {
if (bits[cnt])
L(PORTD, PD4);
else
H(PORTD, PD4);
++cnt;
if (cnt == 64) {
H(PORTD, PD4);
cnt = 0;
++outer;
if(outer > 1) {
outer = 0;
H(EIMSK, INT1);
L(EIMSK, INT0);
send = 0;
}
}
}
}
SIGNAL(INT1_vect) {
L(EIMSK, INT1);
H(EIMSK, INT0);
}
void kbd_cmd(uint8_t cmd) {
kbd_clear();
kbd_commit();
kbd_commit();
switch(cmd) {
case ENC_HZ_POS_UP:
bits[ 0] = 0; bits[ 1] = 1; kbd_commit();
bits[ 0] = 1; bits[ 1] = 1; kbd_commit();
bits[ 0] = 1; bits[ 1] = 0; break;
case ENC_HZ_POS_DW:
bits[ 0] = 1; bits[ 1] = 0; kbd_commit();
bits[ 0] = 1; bits[ 1] = 1; kbd_commit();
bits[ 0] = 0; bits[ 1] = 1; break;
case ENC_HZ_ZOOM_DW:
delay_ms(100);
bits[16] = 0; bits[17] = 1; kbd_commit();
bits[16] = 1; bits[17] = 1; kbd_commit();
bits[16] = 1; bits[17] = 0; break;
case ENC_HZ_ZOOM_UP:
delay_ms(100);
bits[16] = 1; bits[17] = 0; kbd_commit();
bits[16] = 1; bits[17] = 1; kbd_commit();
bits[16] = 0; bits[17] = 1; break;
case ENC_CH2_V_OFFT_DW:
bits[ 8] = 1; bits[ 9] = 0; kbd_commit();
bits[ 8] = 1; bits[ 9] = 1; kbd_commit();
bits[ 8] = 1; bits[ 8] = 0; break;
case ENC_CH2_V_OFFT_UP:
bits[ 8] = 0; bits[ 9] = 1; kbd_commit();
bits[ 8] = 1; bits[ 9] = 1; kbd_commit();
bits[ 8] = 1; bits[ 9] = 0; break;
case ENC_CH2_V_DIV_DW:
delay_ms(100);
bits[24] = 0; bits[25] = 1; kbd_commit();
bits[24] = 1; bits[25] = 1; kbd_commit();
bits[24] = 1; bits[25] = 0; break;
case ENC_CH2_V_DIV_UP:
delay_ms(100);
bits[24] = 1; bits[25] = 0; kbd_commit();
bits[24] = 1; bits[25] = 1; kbd_commit();
bits[24] = 0; bits[25] = 1; break;
case ENC_MENU_DW:
bits[40] = 1; bits[41] = 0; kbd_commit();
bits[40] = 1; bits[41] = 1; kbd_commit();
bits[40] = 0; bits[41] = 1; break;
case ENC_MENU_UP:
bits[40] = 0; bits[41] = 1; kbd_commit();
bits[40] = 1; bits[41] = 1; kbd_commit();
bits[40] = 1; bits[41] = 0; break;
case ENC_TRIG_LVL_DW:
bits[48] = 1; bits[49] = 0; kbd_commit();
bits[48] = 1; bits[49] = 1; kbd_commit();
bits[48] = 0; bits[49] = 1; break;
case ENC_TRIG_LVL_UP:
bits[48] = 0; bits[49] = 1; kbd_commit();
bits[48] = 1; bits[49] = 1; kbd_commit();
bits[48] = 1; bits[49] = 0; break;
case ENC_CH1_V_OFFT_DW:
bits[56] = 1; bits[57] = 0; kbd_commit();
bits[56] = 1; bits[57] = 1; kbd_commit();
bits[56] = 0; bits[57] = 1; break;
case ENC_CH1_V_OFFT_UP:
bits[56] = 0; bits[57] = 1; kbd_commit();
bits[56] = 1; bits[57] = 1; kbd_commit();
bits[56] = 1; bits[57] = 0; break;
case ENC_CH1_V_DIV_UP:
delay_ms(100);
bits[32] = 0; bits[33] = 1; kbd_commit();
bits[32] = 1; bits[33] = 1; kbd_commit();
bits[32] = 1; bits[33] = 0; break;
case ENC_CH1_V_DIV_DW:
delay_ms(100);
bits[32] = 1; bits[33] = 0; kbd_commit();
bits[32] = 1; bits[33] = 1; kbd_commit();
bits[32] = 0; bits[33] = 1; break;
case BTN_SAVE_TO_FLASH: bits[ 2] = 1; break;
case BTN_REF: bits[ 3] = 1; break;
case BTN_HELP: bits[ 4] = 1; break;
case BTN_TRIGGER: bits[ 5] = 1; break;
case BTN_HZ_POS_RST: bits[ 6] = 1; break;
case BTN_MENU_5: bits[10] = 1; break;
case BTN_CH2: bits[11] = 1; break;
case BTN_TRIGGER_FORCE: bits[13] = 1; break;
case BTN_CH2_V_OFFT_RST: bits[14] = 1; break;
case BTN_MENU_4: bits[18] = 1; break;
case BTN_MATH: bits[19] = 1; break;
case BTN_DEFAULTS: bits[21] = 1; break;
case BTN_HZ_MASK: bits[22] = 1; break;
case BTN_MENU_3: bits[26] = 1; break;
case BTN_CH1: bits[27] = 1; break;
case BTN_UTILITY: bits[28] = 1; break;
case BTN_TRIGGER_50: bits[29] = 1; break;
case BTN_CH2_V_RATIO: bits[30] = 1; break;
case BTN_MENU_2: bits[34] = 1; break;
case BTN_HZ_MENU: bits[35] = 1; break;
case BTN_SAVE_RECALL: bits[36] = 1; break;
case BTN_TRIGGER_SINGLE: bits[37] = 1; break;
case BTN_CH1_V_RATIO: bits[38] = 1; break;
case BTN_MENU_1: bits[42] = 1; break;
case BTN_MEASURE: bits[43] = 1; break;
case BTN_DISPLAY: bits[44] = 1; break;
case BTN_TRIGGER_RUN_STOP: bits[45] = 1; break;
case BTN_MENU_RST: bits[46] = 1; break;
case BTN_MENU: bits[50] = 1; break;
case BTN_CURSORS: bits[51] = 1; break;
case BTN_ACQUIRE: bits[52] = 1; break;
case BTN_TRIGGER_MENU: bits[53] = 1; break;
case BTN_CH1_V_OFFT_RST: bits[62] = 1; break;
};
kbd_commit();
}
void kbd_init() {
H(DDRD, PD4);
L(PORTD, PD4);
L(DDRD, PD2);
L(PORTD, PD2);
L(DDRD, PD3);
L(PORTD, PD3);
H(EICRA, ISC01);
L(EICRA, ISC00);
L(EICRA, ISC11);
H(EICRA, ISC10);
H(EIMSK, INT1);
}
delay.h
#ifndef _H_DELAY_H
#define _H_DELAY_H
#include "main.h"
#include <util/delay.h>
#define nop() __asm__ __volatile__("nop")
void delay_ms(unsigned short ms);
void delay_us(unsigned short us);
#endif
delay.c
#include "delay.h"
void delay_ms(unsigned short ms) {
while ( ms ) {
ms--;
_delay_ms(1);
}
}
void delay_us(unsigned short us) {
while ( us ) {
us--;
_delay_us(1);
}
}
Makefile
CPU=atmega328p
GCC=avr-gcc
CFLAGS= -Os -mmcu=$(CPU) -Wall -fpack-struct -fshort-enums -funsigned-bitfields -Wl,--relax -fno-move-loop-invariants -funsigned-char -fno-inline-small-functions -fdata-sections -fno-tree-loop-optimize -lprintf_min
INCLUDES=
LIBS=
OBJCPY=avr-objcopy
OBJECTS=main.o twi.o delay.o kbd.o spi.o uart.o
PROJECT_NAME=mega328p
HEX_FILE=$(PROJECT_NAME).hex
HEX_FILE_DUMP=$(PROJECT_NAME)_dump.hex
PROG=avrdude
PROG_FLAGS=-V -c usbasp -p $(CPU)
all:
$(MAKE) cls
$(MAKE) $(PROJECT_NAME)
$(MAKE) obj
$(MAKE) size #upload
$(PROJECT_NAME): $(OBJECTS)
$(GCC) -o $(PROJECT_NAME) $(OBJECTS) $(CFLAGS) $(LIBS) $(INCLUDES)
main.o: main.c main.h
$(GCC) $(CFLAGS) $(INCLUDES) -c main.c
twi.o: twi.c twi.h
$(GCC) $(CFLAGS) $(INCLUDES) -c twi.c
spi.o: spi.c spi.h
$(GCC) $(CFLAGS) $(INCLUDES) -c spi.c
kbd.o: kbd.c kbd.h
$(GCC) $(CFLAGS) $(INCLUDES) -c kbd.c
uart.o: uart.c uart.h
$(GCC) $(CFLAGS) $(INCLUDES) -c uart.c
delay.o: delay.c delay.h
$(GCC) $(CFLAGS) $(INCLUDES) -c delay.c
obj: $(OBJECTS)
$(OBJCPY) -O ihex $(PROJECT_NAME) $(HEX_FILE)
clean:
rm -f $(PROJECT_NAME) $(OBJECTS) $(HEX_FILE)
cls:
clear;true;
size:
du -b $(HEX_FILE)
upload:
$(MAKE) all
$(MAKE) $(HEX_FILE)
$(PROG) $(PROG_FLAGS) -e -U flash:w:$(HEX_FILE)
download:
$(PROG) $(PROG_FLAGS) -U flash:r:$(HEX_FILE_DUMP)
reset:
$(PROG) $(PROG_FLAGS)
No comments:
Post a Comment