This commit is contained in:
Олег Бородин
2025-01-18 13:25:14 +02:00
parent 4b289d1c46
commit 9ae1e7bc07
10 changed files with 137 additions and 27115 deletions

View File

@@ -9,7 +9,7 @@ MCU = atmega328p
CFLAGS += -DF_CPU=$(F_CPU) -mmcu=$(MCU)
CFLAGS += -I. -Os --std=c11
CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -save-temps
#CFLAGS += -save-temps
CFLAGS += -Wall
LDFLAGS += -s -mmcu=$(MCU)
@@ -25,6 +25,7 @@ MAIN_OBJS += eeprom.o
MAIN_OBJS += i2c.o
MAIN_OBJS += timer.o
MAIN_OBJS += tool.o
MAIN_OBJS += radio.o
MAIN_ELF = main.elf
MAIN_HEX = main.hex

View File

@@ -25,7 +25,7 @@ void button_setup(button_t *button) {
}
static bool button_is_pressed(button_t *button) {
if (REG_BIT_VALUE(_MMIO_BYTE(button->pinaddr), button->outnum)) {
if (!REG_BIT_VALUE(_MMIO_BYTE(button->pinaddr), button->outnum)) {
return true;
}
return false;

50
contr.c
View File

@@ -21,7 +21,16 @@
#include <contr.h>
button_t volume_button;
#include <button.h>
#include <i2c.h>
#include <adc.h>
#include <disp.h>
#include <timer.h>
#include <radio.h>
button_t volplus_button;
button_t volminus_button;
typedef struct {
uint8_t volume;
@@ -36,10 +45,31 @@ void contr_init(void) {
}
void contr_setup(void) {
i2c_init();
disp_init();
button_init(&volplus_button, BTVOLPLUS_DDRADDR,
BTVOLPLUS_PORTADDR, BTVOLPLUS_PINDADDR, BTVOLPLUS_OUTNUM);
button_setup(&volplus_button);
button_reset(&volplus_button);
button_init(&volminus_button, BTVOLMINUS_DDRADDR,
BTVOLMINUS_PORTADDR, BTVOLMINUS_PINDADDR, BTVOLMINUS_OUTNUM);
button_setup(&volminus_button);
button_reset(&volminus_button);
adc_init();
radio_init();
radio_unmute();
radio_volume();
timer0_init();
sei();
}
ISR(TIMER0_OVF_vect) {
button_handle(&volume_button);
button_handle(&volplus_button);
button_handle(&volminus_button);
}
@@ -55,19 +85,25 @@ void contr_show_logo(void) {
void contr_show_volume(void) {
char dispstr[CONTR_DISPSTR_SIZE];
sprintf(dispstr, "%4d", contr.volume);
disp_string(1, 1, dispstr);
sprintf(dispstr, "%2d 0x%02X %02X", contr.volume, radio_get_status(), i2c_error);
disp_string(7, 0, dispstr);
}
#define MAX_VOLUME 64
void contr_calc_volume(void) {
if (button_was_pressed(&volume_button) == true) {
if (button_was_pressed(&volplus_button)) {
if (contr.volume == MAX_VOLUME) {
return;
}
contr.volume++;
contr.volume_updated = true;
}
if (contr.volume > MAX_VOLUME) {
contr.volume = 0;
if (button_was_pressed(&volminus_button)) {
if (contr.volume == 0) {
return;
}
contr.volume--;
contr.volume_updated = true;
}
}

40
contr.h
View File

@@ -3,7 +3,45 @@
#include <stdint.h>
button_t volume_button;
#define PINBADDR ((0x03) + 0x20)
#define DDRBADDR ((0x04) + 0x20)
#define PORTBADDR ((0x05) + 0x20)
#define PINCADDR ((0x06) + 0x20)
#define DDRCADDR ((0x07) + 0x20)
#define PORTCADDR ((0x08) + 0x20)
#define PINDADDR ((0x09) + 0x20)
#define DDRDADDR ((0x0A) + 0x20)
#define PORTDADDR ((0x0B) + 0x20)
// PD2 - ENC--
// PD3 - ENC++
// PD4 - Mode
// PD5 - BW
// PD6 - Vol+
// PD7 - Vol-
// PB0 - Band+
// PB1 - Band-
// PB2 - Step
// PB3 - AGC
// PB4 - xx
// PC0 - ENC
#define BTVOLPLUS_DDRADDR DDRDADDR
#define BTVOLPLUS_PORTADDR PORTDADDR
#define BTVOLPLUS_PINDADDR PINDADDR
#define BTVOLPLUS_OUTNUM PD6
#define BTVOLMINUS_DDRADDR DDRDADDR
#define BTVOLMINUS_PORTADDR PORTDADDR
#define BTVOLMINUS_PINDADDR PINDADDR
#define BTVOLMINUS_OUTNUM PD7
void contr_init(void);
void contr_setup(void);

45
disp.c
View File

@@ -6,8 +6,8 @@
#include <i2c.h>
#include <disp.h>
#define DISP_FONT basefont
#define DISP_I2CADDR (0x78 >> 1)
#define DISP_FONT basefont
#define DISP_I2CADDR 0x78
#define DISP_WIDTH 128
#define DISP_HEIGHT 64
@@ -23,15 +23,6 @@
#define DISP_SEND_CMD 0x00
#define DISP_SEND_DATA 0x40
const uint8_t basefont[DISP_MAX_CHARCODE - DISP_MIN_CHARCODE][DISP_CHAR_ARRLEN] PROGMEM;
typedef struct {
uint8_t max_posx;
uint8_t max_posy;
} disp_t;
disp_t disp;
#define SSD1306_SETLOWCOLUMN 0x00 /* Set Lower Column Start Address for Page Addressing Mode. */
#define SSD1306_SETHIGHCOLUMN 0x10 /* Set Higher Column Start Address for Page Addressing Mode. */
#define SSD1306_MEMORYMODE 0x20 /* Set Memory Addressing Mode. */
@@ -60,6 +51,19 @@ disp_t disp;
#define SSD1306_DEACTIVATE_SCROLL 0x2E /* Deactivate scroll */
#define SSD1306_NOP 0XE3 /* No Operation Command. */
const uint8_t basefont[DISP_MAX_CHARCODE - DISP_MIN_CHARCODE][DISP_CHAR_ARRLEN] PROGMEM;
static void disp_send_cmd(uint8_t cmd[], uint8_t size);
static void disp_send_data(uint8_t data[], uint16_t size);
typedef struct {
uint8_t max_posx;
uint8_t max_posy;
} disp_t;
disp_t disp;
const uint8_t init_sequence[] PROGMEM = {
SSD1306_DISPLAYOFF,
SSD1306_MEMORYMODE, 0x00,
@@ -83,20 +87,22 @@ const uint8_t init_sequence[] PROGMEM = {
};
void disp_send_cmd(uint8_t cmd[], uint8_t size) {
i2c_send_addr((DISP_I2CADDR << 1) | 0);
i2c_send_data(DISP_SEND_CMD);
static void disp_send_cmd(uint8_t cmd[], uint8_t size) {
i2c_start();
i2c_write(DISP_I2CADDR);
i2c_write(DISP_SEND_CMD);
for (uint8_t i = 0; i < size; i++) {
i2c_send_data(cmd[i]);
i2c_write(cmd[i]);
}
i2c_stop();
}
void disp_send_data(uint8_t data[], uint16_t size) {
i2c_send_addr((DISP_I2CADDR << 1) | 0);
i2c_send_data(DISP_SEND_DATA);
static void disp_send_data(uint8_t data[], uint16_t size) {
i2c_start();
i2c_write(DISP_I2CADDR);
i2c_write(DISP_SEND_DATA);
for (uint16_t i = 0; i < size; i++) {
i2c_send_data(data[i]);
i2c_write(data[i]);
}
i2c_stop();
}
@@ -174,7 +180,6 @@ void disp_clear(void) {
void disp_set_invert(bool invert) {
uint8_t commands[1];
if (invert == true) {
commands[0] = SSD1306_INVERTDISPLAY;
} else {

3
disp.h
View File

@@ -13,9 +13,6 @@ void disp_init(void);
void disp_string(uint8_t posy, uint8_t posx, const char* str);
void disp_send_cmd(uint8_t cmd[], uint8_t size);
void disp_send_data(uint8_t data[], uint16_t size);
void disp_set_invert(bool invert);
void disp_set_sleep(bool sleep);
void disp_set_contrast(uint8_t contrast);

File diff suppressed because it is too large Load Diff

56
i2c.c
View File

@@ -3,7 +3,10 @@
uint8_t i2c_error;
#define SET_TWBR (F_CPU/F_I2C-16UL)/(PSC_I2C*2UL)
void i2c_init(void) {
i2c_error = 0;
switch (PSC_I2C) {
case 4:
TWSR = 0x1;
@@ -18,28 +21,28 @@ void i2c_init(void) {
TWSR = 0x00;
break;
}
TWBR = (uint8_t) SET_TWBR;
TWBR = (uint8_t)SET_TWBR;
TWCR = (1 << TWEN);
}
void i2c_send_addr(uint8_t i2c_addr) {
void i2c_start(void) {
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0 && timeout != 0) {
timeout--;
if (timeout == 0) {
while ((TWCR & (1 << TWINT)) == 0) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_START);
return;
}
};
TWDR = i2c_addr;
}
void i2c_write(uint8_t byte) {
TWDR = byte;
TWCR = (1 << TWINT) | (1 << TWEN);
timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0 && timeout != 0) {
timeout--;
if (timeout == 0) {
i2c_error |= (1 << I2C_ERR_SENDADRESS);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_WRITE);
return;
}
};
@@ -47,29 +50,15 @@ void i2c_send_addr(uint8_t i2c_addr) {
void i2c_stop(void) {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
while (TWCR & (1 << TWSTO));
}
void i2c_send_data(uint8_t byte) {
TWDR = byte;
TWCR = (1 << TWINT) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0 && timeout != 0) {
timeout--;
if (timeout == 0) {
i2c_error |= (1 << I2C_ERR_BYTE);
return;
}
};
}
uint8_t i2c_read_ack(void) {
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0 && timeout != 0) {
timeout--;
if (timeout == 0) {
while ((TWCR & (1 << TWINT)) == 0) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_READACK);
return 0;
}
@@ -77,14 +66,11 @@ uint8_t i2c_read_ack(void) {
return TWDR;
}
uint8_t i2c_read_nack(void) {
TWCR = (1 << TWINT) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0 && timeout != 0) {
timeout--;
if (timeout == 0) {
uint16_t timeout = F_CPU / F_I2C * 4.0;
while ((TWCR & (1 << TWINT)) == 0) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_READNACK);
return 0;
}

16
i2c.h
View File

@@ -4,27 +4,23 @@
#define PSC_I2C 1 // I2C prescaler
#define F_I2C 400000UL // I2C Clock
#define SET_TWBR (F_CPU/F_I2C-16UL)/(PSC_I2C*2UL)
#include <stdio.h>
#include <avr/io.h>
extern uint8_t i2c_error;
#define I2C_ERR_START 0 // Timeout start-condition
#define I2C_ERR_SENDADRESS 1 // Timeout device-adress
#define I2C_ERR_BYTE 2 // Timeout byte-transmission
#define I2C_ERR_READACK 3 // Timeout read acknowledge
#define I2C_ERR_READNACK 4 // Timeout read nacknowledge
#define I2C_ERR_START 0 // Timeout start condition
#define I2C_ERR_WRITE 1 // Timeout byte transmission
#define I2C_ERR_READACK 2 // Timeout read acknowledge
#define I2C_ERR_READNACK 3 // Timeout read nacknowledge
void i2c_init(void);
void i2c_send_addr(uint8_t addr);
void i2c_send_data(uint8_t byte);
void i2c_start(void);
void i2c_write(uint8_t byte);
uint8_t i2c_read_ack(void);
uint8_t i2c_read_nack(void);
void i2c_stop(void);
#endif

32
main.c
View File

@@ -18,43 +18,11 @@
#include <contr.h>
#define PINBADDR ((0x03) + 0x20)
#define DDRBADDR ((0x04) + 0x20)
#define PORTBADDR ((0x05) + 0x20)
#define PINCADDR ((0x06) + 0x20)
#define DDRCADDR ((0x07) + 0x20)
#define PORTCADDR ((0x08) + 0x20)
#define PINDADDR ((0x09) + 0x20)
#define DDRDADDR ((0x0A) + 0x20)
#define PORTDADDR ((0x0B) + 0x20)
//#define VOLBUT_DDRADDR DDRDADDR
//#define VOLBUT_PORTADDR PORTDADDR
//#define VOLBUT_PINDADDR PINDADDR
//#define VOLBUT_OUTNUM PD2
#define VOLBUT_DDRADDR DDRCADDR
#define VOLBUT_PORTADDR PORTCADDR
#define VOLBUT_PINDADDR PINCADDR
#define VOLBUT_OUTNUM PC0
int main(void) {
i2c_init();
disp_init();
adc_init();
timer0_init();
button_init(&volume_button, VOLBUT_DDRADDR,
VOLBUT_PORTADDR, VOLBUT_PINDADDR, VOLBUT_OUTNUM);
button_setup(&volume_button);
button_reset(&volume_button);
contr_init();
contr_setup();
sei();
contr_main();
return 0;
}