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

View File

@@ -25,7 +25,7 @@ void button_setup(button_t *button) {
} }
static bool button_is_pressed(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 true;
} }
return false; return false;

50
contr.c
View File

@@ -21,7 +21,16 @@
#include <contr.h> #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 { typedef struct {
uint8_t volume; uint8_t volume;
@@ -36,10 +45,31 @@ void contr_init(void) {
} }
void contr_setup(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) { 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) { void contr_show_volume(void) {
char dispstr[CONTR_DISPSTR_SIZE]; char dispstr[CONTR_DISPSTR_SIZE];
sprintf(dispstr, "%4d", contr.volume); sprintf(dispstr, "%2d 0x%02X %02X", contr.volume, radio_get_status(), i2c_error);
disp_string(1, 1, dispstr); disp_string(7, 0, dispstr);
} }
#define MAX_VOLUME 64 #define MAX_VOLUME 64
void contr_calc_volume(void) { 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++;
contr.volume_updated = true; contr.volume_updated = true;
} }
if (contr.volume > MAX_VOLUME) { if (button_was_pressed(&volminus_button)) {
contr.volume = 0; if (contr.volume == 0) {
return;
}
contr.volume--;
contr.volume_updated = true; contr.volume_updated = true;
} }
} }

40
contr.h
View File

@@ -3,7 +3,45 @@
#include <stdint.h> #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_init(void);
void contr_setup(void); void contr_setup(void);

43
disp.c
View File

@@ -7,7 +7,7 @@
#include <disp.h> #include <disp.h>
#define DISP_FONT basefont #define DISP_FONT basefont
#define DISP_I2CADDR (0x78 >> 1) #define DISP_I2CADDR 0x78
#define DISP_WIDTH 128 #define DISP_WIDTH 128
#define DISP_HEIGHT 64 #define DISP_HEIGHT 64
@@ -23,15 +23,6 @@
#define DISP_SEND_CMD 0x00 #define DISP_SEND_CMD 0x00
#define DISP_SEND_DATA 0x40 #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_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_SETHIGHCOLUMN 0x10 /* Set Higher Column Start Address for Page Addressing Mode. */
#define SSD1306_MEMORYMODE 0x20 /* Set Memory 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_DEACTIVATE_SCROLL 0x2E /* Deactivate scroll */
#define SSD1306_NOP 0XE3 /* No Operation Command. */ #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 = { const uint8_t init_sequence[] PROGMEM = {
SSD1306_DISPLAYOFF, SSD1306_DISPLAYOFF,
SSD1306_MEMORYMODE, 0x00, SSD1306_MEMORYMODE, 0x00,
@@ -83,20 +87,22 @@ const uint8_t init_sequence[] PROGMEM = {
}; };
void disp_send_cmd(uint8_t cmd[], uint8_t size) { static void disp_send_cmd(uint8_t cmd[], uint8_t size) {
i2c_send_addr((DISP_I2CADDR << 1) | 0); i2c_start();
i2c_send_data(DISP_SEND_CMD); i2c_write(DISP_I2CADDR);
i2c_write(DISP_SEND_CMD);
for (uint8_t i = 0; i < size; i++) { for (uint8_t i = 0; i < size; i++) {
i2c_send_data(cmd[i]); i2c_write(cmd[i]);
} }
i2c_stop(); i2c_stop();
} }
void disp_send_data(uint8_t data[], uint16_t size) { static void disp_send_data(uint8_t data[], uint16_t size) {
i2c_send_addr((DISP_I2CADDR << 1) | 0); i2c_start();
i2c_send_data(DISP_SEND_DATA); i2c_write(DISP_I2CADDR);
i2c_write(DISP_SEND_DATA);
for (uint16_t i = 0; i < size; i++) { for (uint16_t i = 0; i < size; i++) {
i2c_send_data(data[i]); i2c_write(data[i]);
} }
i2c_stop(); i2c_stop();
} }
@@ -174,7 +180,6 @@ void disp_clear(void) {
void disp_set_invert(bool invert) { void disp_set_invert(bool invert) {
uint8_t commands[1]; uint8_t commands[1];
if (invert == true) { if (invert == true) {
commands[0] = SSD1306_INVERTDISPLAY; commands[0] = SSD1306_INVERTDISPLAY;
} else { } 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_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_invert(bool invert);
void disp_set_sleep(bool sleep); void disp_set_sleep(bool sleep);
void disp_set_contrast(uint8_t contrast); void disp_set_contrast(uint8_t contrast);

File diff suppressed because it is too large Load Diff

54
i2c.c
View File

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

16
i2c.h
View File

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

32
main.c
View File

@@ -18,43 +18,11 @@
#include <contr.h> #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) { 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_init();
contr_setup(); contr_setup();
sei();
contr_main(); contr_main();
return 0; return 0;
} }