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 <contr.h>
#include <button.h>
#include <i2c.h>
#include <adc.h>
@@ -29,6 +27,7 @@
#include <timer.h>
#include <radio.h>
button_t volplus_button;
button_t volminus_button;
@@ -45,7 +44,9 @@ void contr_init(void) {
}
void contr_setup(void) {
i2c_init();
disp_init();
button_init(&volplus_button, BTVOLPLUS_DDRADDR,
@@ -59,12 +60,10 @@ void contr_setup(void) {
button_reset(&volminus_button);
adc_init();
radio_init();
radio_unmute();
radio_volume();
timer0_init();
sei();
radio_init();
sei();
}
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 <util/delay.h>
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)
void i2c_init(void) {
i2c_error = 0;
switch (PSC_I2C) {
case 4:
TWSR = 0x1;
TWSR = 0x01;
break;
case 16:
TWSR = 0x2;
TWSR = 0x02;
break;
case 64:
TWSR = 0x3;
TWSR = 0x03;
break;
default:
TWSR = 0x00;
@@ -28,7 +32,7 @@ void i2c_init(void) {
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) {
while (!(TWCR & (1 << TWINT))) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_START);
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) {
TWDR = byte;
TWCR = (1 << TWINT) | (1 << TWEN);
uint16_t timeout = F_CPU / F_I2C * 2.0;
while ((TWCR & (1 << TWINT)) == 0) {
while (!(TWCR & (1 << TWINT))) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_WRITE);
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) {
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
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) {
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) {
if (--timeout == 0) {
i2c_error |= (1 << I2C_ERR_READNACK);
@@ -77,3 +86,8 @@ uint8_t i2c_read_nack(void) {
};
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
#define I2C_H_QWERTY
#define PSC_I2C 1 // I2C prescaler
#define F_I2C 400000UL // I2C Clock
#include <stdio.h>
#include <avr/io.h>
extern uint8_t i2c_error;
extern uint8_t i2c_status;
#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
#define I2C_ERR_RESTART 1 // Timeout start condition
#define I2C_ERR_WRITE 2 // Timeout byte transmission
#define I2C_ERR_READACK 3 // Timeout read acknowledge
#define I2C_ERR_READNACK 4 // Timeout read nacknowledge
void i2c_init(void);
void i2c_start(void);
void i2c_write(uint8_t byte);
void i2c_restart(void);
uint8_t i2c_read_ack(void);
uint8_t i2c_read_nack(void);
void i2c_stop(void);

2
main.c
View File

@@ -18,8 +18,6 @@
#include <contr.h>
int main(void) {
contr_init();
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

3
tool.h
View File

@@ -16,7 +16,8 @@
#define REG_SETDOWN(reg, value) ((reg) &= ~(value))
#define REG_BIT_VALUE(reg, value) ((reg) & (1 << (value)))
#define BIT(bit) (1 << (bit))
#define BIT(bit) (1 << (bit))
uint16_t str_len(uint8_t * str);