// To run: // wget -O - http://beta.etherpad.org/p/pihackfm/export/txt 2>/dev/null | gcc -lm -std=c99 -g -xc - && time ./a.out // Access from ARM Running Linux #define BCM2708_PERI_BASE 0x20000000 #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ #include #include #include #include #include #include #include #include #include #include #include #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) //added by rgrasell@gmail.com int freq_const; //added by rgrasell@gmail.com int mem_fd; char *gpio_mem, *gpio_map; char *spi0_mem, *spi0_map; // I/O access volatile unsigned *gpio; volatile unsigned *allof7e; // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) #define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 #define GPIO_GET *(gpio+13) // sets bits which are 1 ignores bits which are 0 #define ACCESS(base) *(volatile int*)((int)allof7e+base-0x7e000000) #define SETBIT(base, bit) ACCESS(base) |= 1<> 1) ^ (-(rnd & 1u) & 0xD0000001u); modulate( intval + (fracval>rnd?1:0)); } //printf("%8f %8x %8f %08x\n", dval, intval, frac, fracval); //delay(9); } } //the plan is: //use PWM to trigger DMA transfer struct CB { unsigned int TI; unsigned int SOURCE_AD; unsigned int DEST_AD; unsigned int TXFR_LEN; unsigned int STRIDE; unsigned int NEXTCONBK; }; struct DMAregs { unsigned int CS; unsigned int CONBLK_AD; unsigned int TI; unsigned int SOURCE_AD; unsigned int DEST_AD; unsigned int TXFR_LEN; unsigned int STRIDE; unsigned int NEXTCONBK; unsigned int DEBUG; }; /* //TODO! Make DMA work. We decided that this needs to be a kernel mode driver void setupDMA(){ DMAregs* DMA0 = &(ACCESS(DMABASE )); //activate DMA0->CS = (1<<20) | (1<<20) | 1 } */ int main(int argc, char **argv) { int g,rep; // Set up gpi pointer for direct register access setup_io(); // Switch GPIO 7..11 to output mode /************************************************************************\ * You are about to change the GPIO settings of your computer. * * Mess this up and it will stop working! * * It might be a good idea to 'sync' before running this program * * so at least you still have your code changes written to the SD-card! * \************************************************************************/ // Set GPIO pins 7-11 to output for (g=7; g<=11; g++) { INP_GPIO(g); // must use INP_GPIO before we can use OUT_GPIO //OUT_GPIO(g); } setup_fm(); modulate(0); //if statement modified by rgrasell@gmail.com to check for new argument, and to set freq_const if (argc==3){ float temp = 500.0 / atof(argv[2]); temp *= (16*16*16); freq_const = (int)temp; playWav(argv[1]); } else fprintf(stderr, "Usage: program wavfile.wav frequency \n\nWhere wavfile is 16 bit 44.1kHz Monon and frequency is a floating point number\n"); return 0; //setup_DMA() /* int lastregs[9*15]; int inuse[9*15]; memset(&inuse, 0, 9*15*4); for(int i = 0; i < 1000000; i++) for (int ch = 0; ch <= 14; ch++) for (int reg = 0; reg <= 0x20/4; reg++) { int curr = ACCESS((DMABASE + 0x100*ch + reg*4)); if (lastregs[ch*9+reg] != curr) { inuse[ch*9+reg]++; lastregs[ch*9+reg] = curr; } //printf("addr %#010x: %#010x\n",0x100*ch + reg, ACCESS(DMABASE + 0x100*ch + reg)); } for (int ch = 0; ch <= 14; ch++) for (int reg = 0; reg <= 0x20/4; reg++) printf("addr %#010x inuse: %#010x\n",0x100*ch + reg, inuse[ch*9+reg]); */ printf("addr %#010x: %#010x\n",0x200, ACCESS(DMABASE + 0x200)); while(!(ACCESS(DMABASE + 0x200) & 0xF << 16)); printf("addr %#010x: %#010x\n",0x200, ACCESS(DMABASE + 0x200)); /* printf("start\n"); // frequency counter on gpio 7 int oldval=0; for (int i=0; i<1000000;) { int newval = GPIO_GET & 1<<10; if (oldval^newval) { oldval=newval; i++; } }; printf("done\n"); return 0; */ //Sawtooth wave! while(1) { for(int i = -40; i <= 40; i++) { modulate(i); printf("Modulating: %d\n", i); delay(25); } } for (rep=0; rep<10; rep++) { for (g=7; g<=11; g++) { GPIO_SET = 1<