Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // i2c fm parallax part 27984
- // bs2 and spin code available
- // device has 2 I2C address, ending in 0, no addresses required Ahhhh
- // write configregs 5x2 read status 2x2
- // have to enable tune to set channel
- #include <Wire.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <string.h>
- // SDA pin is 9 module pin 1 no external pullups OK
- // SCL pin is 5 module pin 2
- // grnd to module pin 10 v3.3-5v to module pin 9
- // device ID
- #define SLAVE_ID 0x20 >> 1
- #define CONFIG_WORDS 5
- #define STATUS_WORDS 4
- static uint16_t Config0[CONFIG_WORDS] = {0xD001, 0, 0x0400, 0x86D3, 0x4000};
- static uint16_t Config[CONFIG_WORDS], Status[STATUS_WORDS];
- // config 0 register 02
- #define DHIZ 15
- #define DMUTE 14
- #define MONO 13
- #define BASS 12
- #define CLK32_INPUT_ENB 10
- #define SEEK 8
- #define CLK_MODE 4
- #define SOFT_RESET 1
- #define ENABLE 0
- #define CLK_MODE_MASK (7 << CLK_MODE)
- #define SEEK_MASK (3 << SEEK)
- #define SEEK_UP (3 << SEEK)
- #define SEEK_DOWN (1 << SEEK)
- // config 1 register 03
- #define CHAN 6
- #define TUNE 4
- #define BAND 2
- #define SPACE 0
- #define CHAN_MASK (0xff << CHAN)
- #define BAND_MASK ( 3 << BAND)
- #define SPACE_MASK ( 3 << SPACE)
- // config 2 register 04
- #define STCEIN 14
- #define DE 11
- #define I2S_ENABLED 6
- #define GPIO3 4
- #define GPIO2 2
- #define GPIO1 0
- #define GPIO3_MASK ( 3 << GPIO3)
- #define GPIO2_MASK ( 3 << GPIO2)
- #define GPIO1_MASK ( 3 << GPIO1)
- // config 3 register 05
- #define INT_MODE 15
- #define SEEKTH 8
- #define LNA_PORT_SEL 6
- #define LNA_ICSEL_BIT 4
- #define VOLUME 0
- #define SEEKTH_MASK (0x7f << SEEKTH)
- #define LNA_PORT_MASK (2 << LNA_PORT_SEL)
- #define LNA_ICSEL_MASK (2 << LNA_ICSEL_BIT)
- #define VOLUME_MASK (0x0f << VOLUME)
- // status regs
- // status 0 register 0a
- #define STC 14
- #define SF 13
- #define ST 10
- #define READCHAN 0
- #define READCHAN_MASK (0xff << READCHAN)
- // status 1 register 0b
- #define RSS 9
- #define FM_TRUE 8
- #define FM_READY 7
- #define RSS_MASK (0x7f << RSS)
- // assume band 0 760 for other spacing .1 MHz
- #define MAX_PRESETS 10
- #define MAX_FREQ 1080
- #define MIN_FREQ 870
- #define MAX_SST 127
- #define MAX_VOL 15
- uint16_t fm_vol=1, fm_chan = 975; // channel spacing 100KHz
- uint16_t fm_rss, fm_readchan,fm_sst=6,fm_st,fm_true,fm_ready,fm_stc,fm_sf;
- uint16_t fm_seek, fm_presets[MAX_PRESETS] = {919,975}, fm_presetnext=2;;
- bool seeking;
- void setup()
- {
- int channel;
- Wire.begin(9,5); // connect I2C
- delay(5);
- SerialUSB.println("FM Demo");
- fm_reset();
- printConfig();
- printPresets();
- delay(100);
- getStatus();
- printStatus();
- }
- void loop()
- {
- uint8_t c;
- bool update;
- SerialUSB.println();
- SerialUSB.println("Freq +/- Vol >/< Seek u/d Preset 0-9 AddPreset A Reset R SST x/y");
- SerialUSB.println(" Enter command character:");
- while(!SerialUSB.available()) delay(1);
- c = SerialUSB.read();
- SerialUSB.println((char)c);
- update = false;
- switch(c) {
- case '+':
- update = chan_update(fm_chan+1);
- break;
- case '-':
- update = chan_update(fm_chan-1);
- break;
- case '>':
- update = vol_update(fm_vol+1);
- break;
- case '<':
- update = vol_update(fm_vol-1);
- break;
- case 'u':
- Config[0] &= ~SEEK_MASK;
- Config[0] |= SEEK_UP;
- seeking = update = true;
- break;
- case 'd':
- Config[0] &= ~SEEK_MASK;
- Config[0] |= SEEK_DOWN;
- seeking = update = true;
- break;
- case 'x':
- update = sst_update(fm_sst+1);
- break;
- case 'y':
- update = sst_update(fm_sst-1);
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- chan_update(fm_presets[c - '0']);
- update = true;
- break;
- case 'A':
- add_preset();
- break;
- case 'R':
- fm_reset();
- update = true;
- break;
- case '?':
- getStatus();
- printConfig();
- printStatus();
- printPresets();
- break;
- default:
- break;
- }
- if (update || seeking) {
- setConfig();
- delay(800); // let seek complete ... spin on flags?
- getStatus();
- if (seeking && fm_stc) {
- seek_disable();
- chan_update(fm_seek + MIN_FREQ);
- setConfig();
- }
- tune_disable();
- printConfig();
- printStatus();
- }
- }
- // config updates
- void fm_reset() {
- seeking = false;
- fm_vol = 1;
- fm_chan = 975;
- fm_sst = 6;
- memcpy(Config,Config0,CONFIG_WORDS * sizeof(uint16_t));
- Config[1] &= ~CHAN_MASK;
- Config[1] |= (fm_chan - MIN_FREQ) << CHAN;
- Config[3] &= ~VOLUME_MASK;
- Config[3] |= fm_vol << VOLUME;
- tune_enable();
- setConfig();
- tune_disable();
- }
- void tune_enable() {
- Config[1] |= (1 << TUNE);
- }
- void tune_disable() {
- Config[1] &= ~(1 << TUNE);
- }
- void seek_disable() {
- seeking = false;
- Config[0] &= ~SEEK_MASK; // turn off seek
- }
- bool vol_update(int val) {
- if (val < 0 || val > MAX_VOL) return false;
- fm_vol = val;
- Config[3] &= ~VOLUME_MASK;
- Config[3] |= fm_vol << VOLUME;
- return true;
- }
- bool chan_update(int val) {
- if (val < MIN_FREQ || val > MAX_FREQ) return false;
- fm_chan = val;
- Config[1] &= ~CHAN_MASK;
- Config[1] |= (fm_chan - MIN_FREQ) << CHAN;
- tune_enable();
- return true;
- }
- bool sst_update(int val) {
- if (val < 0 || val > MAX_SST) return false;
- fm_sst = val;
- Config[3] &= ~SEEKTH_MASK;
- Config[3] |= fm_sst << SEEKTH;
- return true;
- }
- void add_preset() {
- if (fm_presetnext >= MAX_PRESETS) return;
- fm_presets[fm_presetnext++] = fm_chan;
- printPresets();
- }
- // Set configuration register
- void setConfig()
- {
- int i;
- Wire.beginTransmission(SLAVE_ID);
- for(i=0; i< CONFIG_WORDS;i++) {
- Wire.send((int)Config[i]>>8);
- Wire.send((int)(Config[i] & 0xff));
- }
- Wire.endTransmission();
- }
- void getStatus()
- {
- int i;
- Wire.requestFrom(SLAVE_ID, STATUS_WORDS*2);
- for(i=0; i< STATUS_WORDS;i++) {
- Status[i] = Wire.receive();
- Status[i] = Status[i]<<8 | Wire.receive();
- }
- fm_seek = Status[0] & READCHAN_MASK;
- fm_stc = Status[0] >> STC & 1;
- fm_sf = Status[0] >> SF & 1;
- fm_st = Status[0] >> ST & 1;
- fm_rss = (Status[1] & RSS_MASK) >> RSS;
- fm_true = Status[1] >> FM_TRUE & 1;
- fm_ready = Status[1] >> FM_READY & 1;
- }
- void printConfig() {
- int chan;
- char str[128];
- sprintf(str,"config %04x %04x %04x %04x",Config[0],Config[1],Config[2],Config[3]);
- SerialUSB.println(str);
- chan = ((Config[1] & CHAN_MASK) >> CHAN ) + MIN_FREQ;
- sprintf(str," fm channel %d.%d volume %d ss %d sst %d",
- chan/10,chan%10,fm_vol,fm_rss,fm_sst);
- SerialUSB.println(str);
- }
- void printStatus() {
- int chan;
- char str[128];
- sprintf(str,"status %04x %04x",Status[0],Status[1]);
- SerialUSB.println(str);
- chan = fm_seek + MIN_FREQ;
- if(seeking) SerialUSB.print("seeking ... ");
- sprintf(str," seek channel %d.%d ss %d stereo %d complete %d fail %d %d %d",
- chan/10,chan%10,fm_rss,fm_st,fm_stc,fm_sf,fm_true,fm_ready);
- SerialUSB.println(str);
- }
- void printPresets() {
- int chan,i;
- char str[128];
- SerialUSB.print("Presets: ");
- for (i=0;i<fm_presetnext;i++) {
- chan = fm_presets[i];
- sprintf(str,"%d.%d ",chan/10,chan%10);
- SerialUSB.print(str);
- }
- SerialUSB.println();
- }
- #define SID (0x22 >> 1)
- void i2cdump(uint8_t addr, int n)
- {
- int i;
- uint16_t buff[8];
- char str[128];
- SerialUSB.print(addr,HEX); SerialUSB.println(" dump");
- Wire.beginTransmission(SID);
- Wire.send(addr); // start addr
- Wire.endTransmission();
- Wire.requestFrom(SID, n*2);
- for(i=0; i< n;i++) {
- buff[i] = Wire.receive();
- buff[i] = buff[i]<<8 | Wire.receive();
- sprintf(str,"%04x ",buff[i]);
- SerialUSB.print(str);
- }
- SerialUSB.println();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement