diff --git a/contr.c b/contr.c index 2c1cc44..4fe04e6 100644 --- a/contr.c +++ b/contr.c @@ -20,8 +20,6 @@ #include #include - - #include #include #include @@ -29,6 +27,7 @@ #include #include + 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) { diff --git a/docs/ats20plus.pdf b/docs/ats20plus.pdf new file mode 100644 index 0000000..29018ba Binary files /dev/null and b/docs/ats20plus.pdf differ diff --git a/i2c.c b/i2c.c index c67922b..b7cbc76 100644 --- a/i2c.c +++ b/i2c.c @@ -1,21 +1,25 @@ #include +#include 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)); +} diff --git a/i2c.h b/i2c.h index 5c051b3..bf58389 100644 --- a/i2c.h +++ b/i2c.h @@ -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 #include 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); diff --git a/main.c b/main.c index 30afee5..335fbf5 100644 --- a/main.c +++ b/main.c @@ -18,8 +18,6 @@ #include - - int main(void) { contr_init(); contr_setup(); diff --git a/radio.c b/radio.c new file mode 100644 index 0000000..40122c0 --- /dev/null +++ b/radio.c @@ -0,0 +1,199 @@ + +#include +#include +#include +#include + +#include +#include +#include + +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) {} diff --git a/radio.h b/radio.h new file mode 100644 index 0000000..5b63bc8 --- /dev/null +++ b/radio.h @@ -0,0 +1,14 @@ +#ifndef RADIO_H_QWERTY +#define RADIO_H_QWERTY + +#include +#include + + +void radio_init(void); +void radio_unmute(void); +void radio_volume(void); + +uint8_t radio_get_status(void); + +#endif diff --git a/tool.h b/tool.h index 3c66565..5bdced4 100644 --- a/tool.h +++ b/tool.h @@ -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);