/* * aitendo M6955 dsp radio module control * File: i2c_m6955.c * Author: www.henteko.org * * Created on 2013/11/15, 17:50 */ #include #include "i2c_m6955.h" void i2c_m6955_send(unsigned char reg, unsigned char data) { TinyI2C_start(); TinyI2C_write(0x20); TinyI2C_write(reg); TinyI2C_write(data); TinyI2C_stop(); } unsigned char i2c_m6955_recv(unsigned char reg) { unsigned char c; TinyI2C_start(); TinyI2C_write(0x20); TinyI2C_write(reg); TinyI2C_start(); TinyI2C_write(0x20 | 1); c = TinyI2C_read(0); TinyI2C_stop(); _delay_us(30); return c; } void i2c_m6955_set_band(unsigned char band) { if(band == 0) { i2c_m6955_send(0, 0b10000000); // set mode AM i2c_m6955_send(1, 0b00010001); // set band WM2 and FM2 } else if(band == 1) { i2c_m6955_send(0, 0b11000000); // set mode FM i2c_m6955_send(1, 0b00010001); // set band WM2 and FM2 } else { i2c_m6955_send(0, 0b10000000); // set mode AM i2c_m6955_send(1, 0b01000001); // set band SW5 and FM2 } } void i2c_m6955_tune(unsigned char mode) { if(mode == 1) { // FM mode i2c_m6955_send(0, 0b11000000); _delay_ms(1); i2c_m6955_send(0, 0b11100000); // tune 0->1 _delay_ms(1); i2c_m6955_send(0, 0b11000000); } else { // AM mode i2c_m6955_send(0, 0b10000000); _delay_ms(1); i2c_m6955_send(0, 0b10100000); // tune 0->1 _delay_ms(1); i2c_m6955_send(0, 0b10000000); } } void i2c_m6955_set_freq(unsigned char band, unsigned int freq) { unsigned int ch; if(band == 1) { // set fm freq ch = ((freq - 3000) * 10) / 25; } else if(band == 0) { // set wm freq ch = (freq / 9) * 3; } else { // set sw freq ch = freq / 5; } i2c_m6955_send(3, (ch & 0xff)); i2c_m6955_send(2, ((ch >> 8) | 0x40)); i2c_m6955_tune(band); } unsigned int i2c_m6955_get_freq(unsigned char band) { unsigned int freq; unsigned char high, low; unsigned int ch; low = i2c_m6955_recv(3) ; high = i2c_m6955_recv(2) & 0x1f; ch = (high << 8) | low; if(band == 0) { // MW band freq = ch * 3; } else if(band == 1) { // FM band freq = (ch * 5) / 2 + 3000; } else { // SW band freq = ch * 5; } return freq; } void i2c_m6955_init() { i2c_m6955_send(0, 0b11000000); // b7=power on, b6=fmmode i2c_m6955_send(6, 0b01100001); // b7:2=volume 48/64, b1:radio mode // b0:signal fhase 0:dual 1:single i2c_m6955_send(7, 0b00110001); // b5=base boost, b3:2=auto stereo i2c_m6955_send(9, 0b00000111); // b3=vol control resistor, b2=Xtal } int i2c_m6955_siglevel(unsigned char band) { unsigned int pga_rf, pga_if, rssi; unsigned char tmp; int level; tmp = i2c_m6955_recv(24); pga_rf = tmp & 0xe0 >> 5; pga_if = tmp & 0x1c >> 2; rssi = i2c_m6955_recv(27) & 0x7f; if(band == 1) level = 103 - rssi - 6 * pga_rf - 6 * pga_if; else level = 123 - rssi - 6 * pga_rf - 6 * pga_if; return level; } void i2c_m6955_off(void) { i2c_m6955_send(0, 0b00000000); }