This commit is contained in:
Олег Бородин
2025-02-02 20:13:15 +02:00
parent 9ae1e7bc07
commit 693b6b33b8
8 changed files with 253 additions and 26 deletions

11
contr.c
View File

@@ -20,8 +20,6 @@
#include <button.h> #include <button.h>
#include <contr.h> #include <contr.h>
#include <button.h> #include <button.h>
#include <i2c.h> #include <i2c.h>
#include <adc.h> #include <adc.h>
@@ -29,6 +27,7 @@
#include <timer.h> #include <timer.h>
#include <radio.h> #include <radio.h>
button_t volplus_button; button_t volplus_button;
button_t volminus_button; button_t volminus_button;
@@ -45,7 +44,9 @@ void contr_init(void) {
} }
void contr_setup(void) { void contr_setup(void) {
i2c_init(); i2c_init();
disp_init(); disp_init();
button_init(&volplus_button, BTVOLPLUS_DDRADDR, button_init(&volplus_button, BTVOLPLUS_DDRADDR,
@@ -59,12 +60,10 @@ void contr_setup(void) {
button_reset(&volminus_button); button_reset(&volminus_button);
adc_init(); adc_init();
radio_init();
radio_unmute();
radio_volume();
timer0_init(); timer0_init();
sei();
radio_init();
sei();
} }
ISR(TIMER0_OVF_vect) { ISR(TIMER0_OVF_vect) {

BIN
docs/ats20plus.pdf Normal file

Binary file not shown.

38
i2c.c
View File

@@ -1,21 +1,25 @@
#include <i2c.h> #include <i2c.h>
#include <util/delay.h>
uint8_t i2c_error; uint8_t i2c_error;
uint8_t i2c_status;
#define PSC_I2C 1 // I2C prescaler
#define F_I2C 400000UL // I2C Clock
#define SET_TWBR (F_CPU/F_I2C-16UL)/(PSC_I2C*2UL) #define SET_TWBR (F_CPU/F_I2C-16UL)/(PSC_I2C*2UL)
void i2c_init(void) { void i2c_init(void) {
i2c_error = 0; i2c_error = 0;
switch (PSC_I2C) { switch (PSC_I2C) {
case 4: case 4:
TWSR = 0x1; TWSR = 0x01;
break; break;
case 16: case 16:
TWSR = 0x2; TWSR = 0x02;
break; break;
case 64: case 64:
TWSR = 0x3; TWSR = 0x03;
break; break;
default: default:
TWSR = 0x00; TWSR = 0x00;
@@ -28,7 +32,7 @@ void i2c_init(void) {
void i2c_start(void) { 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))) {
if (--timeout == 0) { if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_START); i2c_error |= (1 << I2C_ERR_START);
return; return;
@@ -36,11 +40,22 @@ void i2c_start(void) {
}; };
} }
void i2c_restart(void) {
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while (!(TWCR & (1 << TWINT))) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_RESTART);
return;
}
};
}
void i2c_write(uint8_t byte) { void i2c_write(uint8_t byte) {
TWDR = byte; TWDR = byte;
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 * 2.0;
while ((TWCR & (1 << TWINT)) == 0) { while (!(TWCR & (1 << TWINT))) {
if (--timeout == 0) { if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_WRITE); i2c_error |= (1 << I2C_ERR_WRITE);
return; return;
@@ -48,12 +63,6 @@ void i2c_write(uint8_t byte) {
}; };
} }
void i2c_stop(void) {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
while (TWCR & (1 << TWSTO));
}
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;
@@ -68,7 +77,7 @@ uint8_t i2c_read_ack(void) {
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 * 4.0; uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0) { while ((TWCR & (1 << TWINT)) == 0) {
if (--timeout == 0) { if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_READNACK); i2c_error |= (1 << I2C_ERR_READNACK);
@@ -77,3 +86,8 @@ uint8_t i2c_read_nack(void) {
}; };
return TWDR; return TWDR;
} }
void i2c_stop(void) {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
//while (TWCR & (1 << TWSTO));
}

12
i2c.h
View File

@@ -2,23 +2,25 @@
#ifndef I2C_H_QWERTY #ifndef I2C_H_QWERTY
#define I2C_H_QWERTY #define I2C_H_QWERTY
#define PSC_I2C 1 // I2C prescaler
#define F_I2C 400000UL // I2C Clock
#include <stdio.h> #include <stdio.h>
#include <avr/io.h> #include <avr/io.h>
extern uint8_t i2c_error; extern uint8_t i2c_error;
extern uint8_t i2c_status;
#define I2C_ERR_START 0 // Timeout start condition #define I2C_ERR_START 0 // Timeout start condition
#define I2C_ERR_WRITE 1 // Timeout byte transmission #define I2C_ERR_RESTART 1 // Timeout start condition
#define I2C_ERR_READACK 2 // Timeout read acknowledge #define I2C_ERR_WRITE 2 // Timeout byte transmission
#define I2C_ERR_READNACK 3 // Timeout read nacknowledge #define I2C_ERR_READACK 3 // Timeout read acknowledge
#define I2C_ERR_READNACK 4 // Timeout read nacknowledge
void i2c_init(void); void i2c_init(void);
void i2c_start(void); void i2c_start(void);
void i2c_write(uint8_t byte); void i2c_write(uint8_t byte);
void i2c_restart(void);
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);

2
main.c
View File

@@ -18,8 +18,6 @@
#include <contr.h> #include <contr.h>
int main(void) { int main(void) {
contr_init(); contr_init();
contr_setup(); contr_setup();

199
radio.c Normal file
View File

@@ -0,0 +1,199 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <util/delay.h>
#include <tool.h>
#include <i2c.h>
#include <radio.h>
void udelay(void) {
#define _DELAY 100
for (int i = 0; i < (_DELAY); i++) {
__asm("nop");
}
}
typedef struct {
uint8_t status;
} radio_t;
radio_t radio;
uint8_t radio_get_status(void) {
return radio.status;
}
#define RX_I2CADDR 0xC6
#define I2CADDR_WRITE_BIT 0
#define CMD_POWER_UP 0x01
#define CMD_GET_REV 0x10
#define CMD_POWER_DOWN 0x11
#define CMD_SET_PROP 0x12
#define CMD_GET_PROP 0x13
#define CMD_GET_INTSTAT 0x14
#define CMD_AM_TUNE_FREQ 0x40
#define CMD_FM_TUNE_FREQ 0x20
#define POWERUP_CTSIEN_BIT 7
#define POWERUP_GPO2OEN_BIT 6
#define POWERUP_PATCH_BIT 5
#define POWERUP_XOSCEN_BIT 4
#define POWERUP_FMRDS 0x00
#define POWERUP_AMSWLW 0x01
#define POWERUP_ANALOG 0x05
#define INT_CTS_BIT 7
#define INT_ERR_BIT 6
#define INT_RDSINT_BIT 2
#define INT_ASQINT_BIT 1
#define INT_STCIN_BIT 0
#define STATUS_CTS_BIT 7
#define STATUS_ERR_BIT 6
#define STATUS_RSQINT_BIT 3
#define STATUS_RDSINT_BIT 2
#define STATUS_STCINT_BIT 0
#define PROP_RX_VOLUME 0x4000
#define PROP_RX_HARD_MUTE 0x4001
#define PROP_HMUTE_L_BIT 1
#define PROP_HMUTE_R_BIT 0
#define HI_BYTE(word) (((word) >> 8) & 0xFF)
#define LO_BYTE(word) (((word) >> 0) & 0xFF)
#define RST_PIN PB4
void radio_wait_cts(void) {
uint8_t cts = 0;
uint8_t rcount = 17;
while ((cts &= BIT(STATUS_CTS_BIT)) == 0) {
i2c_start();
i2c_write(RX_I2CADDR);
i2c_write(CMD_GET_INTSTAT);
i2c_restart();
i2c_write(RX_I2CADDR | BIT(I2CADDR_WRITE_BIT));
for (uint8_t i = 0; i < rcount; i++) {
cts = i2c_read_ack();
if ((cts &= BIT(STATUS_CTS_BIT)) != 0) {
break;
}
}
i2c_stop();
}
}
void radio_powerup_fmrds(void) {
i2c_start();
i2c_write(RX_I2CADDR);
i2c_write(CMD_POWER_UP);
i2c_write(POWERUP_FMRDS | BIT(POWERUP_XOSCEN_BIT) | BIT(POWERUP_CTSIEN_BIT));
i2c_write(POWERUP_ANALOG);
i2c_stop();
_delay_ms(300);
}
void radio_set_fm_freq(uint16_t freq) {
//uint8_t cts = 0x00;
i2c_start();
i2c_write(RX_I2CADDR);
i2c_write(CMD_FM_TUNE_FREQ);
i2c_write(0x01);
i2c_write(HI_BYTE(freq));
i2c_write(LO_BYTE(freq));
i2c_write(0);
#if 0
i2c_restart();
i2c_write(RX_I2CADDR | BIT(I2CADDR_WRITE_BIT));
while (cts == 0x00) {
cts = i2c_read_ack();
cts &= BIT(STATUS_CTS_BIT);
}
i2c_read_nack();
#endif
i2c_stop();
}
void radio_set_rx_volume(uint8_t volume) {
i2c_start();
i2c_write(RX_I2CADDR);
i2c_write(CMD_SET_PROP);
i2c_write(0x00);
i2c_write(HI_BYTE(PROP_RX_VOLUME));
i2c_write(LO_BYTE(PROP_RX_VOLUME));
i2c_write(0x00);
i2c_write(volume);
i2c_stop();
}
void radio_set_rx_mute(void) {
i2c_start();
i2c_write(RX_I2CADDR);
i2c_write(CMD_SET_PROP);
i2c_write(0x00);
i2c_write(HI_BYTE(PROP_RX_HARD_MUTE));
i2c_write(LO_BYTE(PROP_RX_HARD_MUTE));
i2c_write(0x00);
i2c_write(0x00 | BIT(PROP_HMUTE_R_BIT));
i2c_stop();
}
uint16_t radio_get_rev(void) {
uint16_t rev = 0x0000;
//i2c_write(CMD_GET_REV);
//i2c_restart();
//i2c_write(RX_I2CADDR | 0x01);
//radio.status = i2c_read_ack();
//i2c_read_ack();
//i2c_read_ack();
//i2c_read_ack();
//i2c_read_ack();
//i2c_read_ack();
//i2c_read_ack();
//i2c_read_ack();
//i2c_read_nack();
//i2c_stop();
return rev;
}
void radio_hw_reset(void) {
REG_SETUP_BIT(DDRB, RST_PIN);
REG_SETDOWN_BIT(PORTB, RST_PIN);
_delay_ms(10);
REG_SETUP_BIT(PORTB, RST_PIN);
_delay_ms(10);
}
void radio_init(void) {
radio.status = 0;
radio_hw_reset();
radio_powerup_fmrds();
radio_wait_cts();
uint16_t freq = 10010;
radio_set_fm_freq(freq);
radio_wait_cts();
uint8_t volume = 38;
radio_set_rx_volume(volume);
radio_wait_cts();
return;
radio_set_rx_mute();
radio_wait_cts();
}
void radio_unmute(void) {}
void radio_volume(void) {}

14
radio.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef RADIO_H_QWERTY
#define RADIO_H_QWERTY
#include <inttypes.h>
#include <avr/pgmspace.h>
void radio_init(void);
void radio_unmute(void);
void radio_volume(void);
uint8_t radio_get_status(void);
#endif

1
tool.h
View File

@@ -18,6 +18,7 @@
#define BIT(bit) (1 << (bit)) #define BIT(bit) (1 << (bit))
uint16_t str_len(uint8_t * str); uint16_t str_len(uint8_t * str);
#endif #endif