#define CONFIG_ARCH_EZX_E680 #define MAKE_FTR_HAPTICS typedef unsigned int u32; typedef unsigned char u8; #include #include #include #include #include #include #include "soundcard.h" #include "ezx-common.h" #include "ezx-audio.h" #define RADIO_PACKET_SIZE 5 // i2c radio packet size const int fref = 875; //initial frequency, readable const int frefradio = 0x299D; //initial frequency, radio ic void toggle_output(); short freqtoradio(int freq, bool rec = true); int radiotofreq(short rfreq); int initialize_radio(); bool read_stationlock(int fd); //int read_stationpower(int fd); int read_radiofreq(int fd); int send_station(int fd, short station, bool mono = false); int send_search(int fd, short station, bool next = true, bool mono = false); int main(int argc, char **argv) { unsigned char packet[5]; int fd, status, hstest; //TODO //limit top/bottom frequency in search(auto wrap?) //retrieve station power //compare radio station in search to verify lock on new station //make a nice C++ class :) fd = initialize_radio(); if(fd == -1) { perror("Can't open fm device"); return 1; } char Var[10]; int station = 1017; // 101.7MHz send_station(fd, station); toggle_output(); while(scanf("%c", Var)) { if( Var[0] == 'q' ) break; if( Var[0] == 'o' ) toggle_output(); else if( Var[0] == '+' || Var[0] == '-' ) // increment/decrement 0.1Mhz of actual station { if( Var[0] == '+' ) station++; else station--; send_station(fd, station); printf( "New station: %i\n", station ); } else if( Var[0] == 'a' || Var[0] == 's' ) // search, a is before of actual station // s is after of actual station { if( Var[0] == 's' ) send_search(fd, station, true); else send_search(fd, station, false); if(read_stationlock(fd)) { station = read_radiofreq(fd); printf( "setting new station:%i\n", station ); send_station(fd, station); station = read_radiofreq(fd); //is it set? read again... printf( "new station:%i\n", station ); } else printf( "no station lock found\n" ); } } close(fd); return 0; } //this can be implemented inside a sound server... void toggle_output() { int locationtmp, fd, status; static int location = FM_DEVICE << 4; //default location headset/headphone fd = open("/dev/mixer", O_RDONLY); if(fd == -1) { perror("Can't open mixer device"); return; } locationtmp = location; //location is modified after ioctl status = ioctl(fd, SOUND_MIXER_WRITE_OUTSRC, &locationtmp); location ^= 1; //toggle between headset and loudspeaker if(status == -1) perror("error setting output"); close(fd); } int initialize_radio() { int fd = open("/dev/fmradio", O_RDWR); if(fd == -1) return -1; sleep(1); write(fd, "\xb0\x01\x21\x97\x40", RADIO_PACKET_SIZE); //init in stereo mode, 0x21->0x29 for mono return fd; } int send_station(int fd, short station, bool mono) { unsigned char packet[RADIO_PACKET_SIZE]; short freq = freqtoradio(station); //little endian(xscale) to big endian(radio ic) packet[0] = ((unsigned char *)&freq)[1]; packet[1] = ((unsigned char *)&freq)[0]; packet[2] = 0x21; if(mono) packet[2] |= 0x08; packet[3] = 0x97; packet[4] = 0x40; return write(fd, packet, RADIO_PACKET_SIZE); } int send_search(int fd, short station, bool next, bool mono) { unsigned char packet[RADIO_PACKET_SIZE]; short freq = freqtoradio( next ? ++station : --station ); int ret; //big to little endian packet[0] = ((unsigned char *)&freq)[1] | 0xC0; packet[1] = ((unsigned char *)&freq)[0]; packet[2] = 0x21; if(mono) packet[2] |= 0x08; if(next) packet[2] |= 0x80; packet[3] = 0x97; packet[4] = 0x40; ret = write(fd, packet, RADIO_PACKET_SIZE); sleep(1); //it's less, have to confirm exactly return ret; } int read_radiofreq(int fd) { unsigned char packet[RADIO_PACKET_SIZE]; short rfreq; read(fd, packet, RADIO_PACKET_SIZE); rfreq = ((packet[0] & ~0xC0) << 8) | (packet[1]); //filter read packet return radiotofreq(rfreq); } bool read_stationlock(int fd) { unsigned char packet[5]; //not yet :P return true; } short freqtoradio(int freq, bool rec) { int su; int nums13; int retf; su = freq - fref; // retf = (su * (23 / 29) * 12) + (su * (6 / 29) * 13) + frefhex //float on retf = (int)( (su * 95172) + (su * 26896) + 5000 ) / 10000 + frefradio; // 5000 is required for sending 10.5 to 11 when convertion to int for example if(rec) if( (freqtoradio(freq + 1, false) % 6) != (retf % 6) ) retf++; return (short)retf; } int radiotofreq(short rfreq) { int su; int nums13; int retf; su = rfreq - frefradio; // retf = (su * (23 / 29) / 12 ) + (su * (6 / 29) / 13) + 875 retf = (int)( (su * 6609) + (su * 1591) ) / 100000 + fref; return retf; }