fmrds
This commit is contained in:
11
contr.c
11
contr.c
@@ -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
BIN
docs/ats20plus.pdf
Normal file
Binary file not shown.
38
i2c.c
38
i2c.c
@@ -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
12
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 <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
2
main.c
@@ -18,8 +18,6 @@
|
||||
|
||||
#include <contr.h>
|
||||
|
||||
|
||||
|
||||
int main(void) {
|
||||
contr_init();
|
||||
contr_setup();
|
||||
|
||||
199
radio.c
Normal file
199
radio.c
Normal 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
14
radio.h
Normal 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
|
||||
Reference in New Issue
Block a user