This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Dec 14th, 2012  |  syntax: C  |  size: 6.08 KB  |  views: 282  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // Access from ARM Running Linux
  2.  
  3. #define BCM2708_PERI_BASE        0x20000000
  4. #define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
  5.  
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <dirent.h>
  11. #include <math.h>
  12. #include <fcntl.h>
  13. #include <assert.h>
  14. #include <sys/mman.h>
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17.  
  18. #include <unistd.h>
  19.  
  20. #define PAGE_SIZE (4*1024)
  21. #define BLOCK_SIZE (4*1024)
  22.  
  23. int  mem_fd;
  24. char *gpio_mem, *gpio_map;
  25. char *spi0_mem, *spi0_map;
  26.  
  27.  
  28. // I/O access
  29. volatile unsigned *gpio;
  30. volatile unsigned *allof7e;
  31.  
  32. // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
  33. #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
  34. #define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
  35. #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
  36.  
  37. #define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
  38. #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
  39. #define GPIO_GET *(gpio+13)  // sets   bits which are 1 ignores bits which are 0
  40.  
  41. #define ACCESS(base) *(volatile int*)((int)allof7e+base-0x7e000000)
  42. #define SETBIT(base, bit) ACCESS(base) |= 1<<bit
  43. #define CLRBIT(base, bit) ACCESS(base) &= ~(1<<bit)
  44.  
  45. void setup_io();
  46.  
  47.  
  48. #define CM_GP0CTL (0x7e101070)
  49. #define GPFSEL0 (0x7E200000)
  50. #define CM_GP0DIV (0x7e101074)
  51. #define DMABASE (0x7E007000)
  52.  
  53. struct GPCTL {
  54.     char SRC         : 4;
  55.     char ENAB        : 1;
  56.     char KILL        : 1;
  57.     char             : 1;
  58.     char BUSY        : 1;
  59.     char FLIP        : 1;
  60.     char MASH        : 2;
  61.     unsigned int     : 13;
  62.     char PASSWD      : 8;
  63. };
  64.  
  65. void setup_fm()
  66. {
  67.  
  68.     allof7e = (unsigned *)mmap(
  69.                   NULL,
  70.                   0x01000000,  //len
  71.                   PROT_READ|PROT_WRITE,
  72.                   MAP_SHARED,
  73.                   mem_fd,
  74.                   0x20000000  //base
  75.               );
  76.  
  77.     if ((int)allof7e==-1) exit(-1);
  78.  
  79.     SETBIT(GPFSEL0 , 14);
  80.     CLRBIT(GPFSEL0 , 13);
  81.     CLRBIT(GPFSEL0 , 12);
  82.  
  83.  
  84.     struct GPCTL setupword = {6/*SRC*/, 1, 0, 0, 0, 1,0x5a};
  85.  
  86.     ACCESS(CM_GP0CTL) = *((int*)&setupword);
  87.  
  88.  
  89. }
  90.  
  91. void delay( int i)
  92. {
  93.     for(volatile unsigned int j = 1.25*(1<<i); j; j--);
  94. }
  95.  
  96. void modulate(int m, double filteredFreq)
  97. {
  98.     ACCESS(CM_GP0DIV) = (0x5a << 24) + filteredFreq + m;
  99.     //ACCESS(CM_GP0DIV) = (0x5a << 24) + 0x5000 + m;
  100.         //
  101. }
  102.  
  103.  
  104. void playWav(char* filename, double freq)
  105. {
  106.     int fp = open(filename, 'r');
  107.     int sz = lseek(fp, 0L, SEEK_END);
  108.     lseek(fp, 0L, SEEK_SET);
  109.    
  110.     short* data = (short*)malloc(sz);
  111.     read(fp, data, sz);
  112.     unsigned int rnd=1;
  113.    
  114.     for (int j=22; j<sz/2; j++){ //while (read(fp, &data, 2)) {
  115.         float dval = (float)(data[j])/65536.0*25.0;
  116.         int intval = (int)(floor(dval));
  117.         float frac = dval - (float)intval;
  118.         unsigned int fracval = (unsigned int)(frac*((float)(1<<16))*((float)(1<<16)));
  119.  
  120.         for (int i=0; i<270; i++) {
  121.           rnd = (rnd >> 1) ^ (-(rnd & 1u) & 0xD0000001u);
  122.           modulate( intval + (fracval>rnd?1:0),freq);
  123.         }
  124.     }
  125.  
  126. }
  127.  
  128. //the plan is:
  129. //use PWM to trigger DMA transfer
  130.  
  131. struct CB {
  132.     unsigned int TI;
  133.     unsigned int SOURCE_AD;
  134.     unsigned int DEST_AD;
  135.     unsigned int TXFR_LEN;
  136.     unsigned int STRIDE;
  137.     unsigned int NEXTCONBK;
  138. };
  139.  
  140. struct DMAregs {
  141.     unsigned int CS;
  142.     unsigned int CONBLK_AD;
  143.     unsigned int TI;
  144.     unsigned int SOURCE_AD;
  145.     unsigned int DEST_AD;
  146.     unsigned int TXFR_LEN;
  147.     unsigned int STRIDE;
  148.     unsigned int NEXTCONBK;
  149.     unsigned int DEBUG;
  150. };
  151.  
  152. int main(int argc, char **argv)
  153. {
  154.     int g,rep;
  155.  
  156.     // Set up gpi pointer for direct register access
  157.     setup_io();
  158.  
  159.     // Switch GPIO 7..11 to output mode
  160.  
  161.     /************************************************************************\
  162.      * You are about to change the GPIO settings of your computer.          *
  163.      * Mess this up and it will stop working!                               *
  164.      * It might be a good idea to 'sync' before running this program        *
  165.      * so at least you still have your code changes written to the SD-card! *
  166.     \************************************************************************/
  167.  
  168.     // Set GPIO pins 7-11 to output
  169.     for (g=7; g<=11; g++) {
  170.         INP_GPIO(g); // must use INP_GPIO before we can use OUT_GPIO
  171.         //OUT_GPIO(g);
  172.     }
  173.     //Messy code...
  174.     double freq = 100;
  175.     if (argc==3)
  176.         freq = atof(argv[2]);
  177.     if (freq < 87.5 || freq > 108.0)
  178.       freq = 100;
  179.         double pureFreq = round((500/freq) * 16 * 16 * 16);
  180.     setup_fm();
  181.     modulate(0,pureFreq);
  182.  
  183.     if (argc==3) //We must have 3 args due to the mod :P
  184.       playWav(argv[1], pureFreq);
  185.     else
  186.       fprintf(stderr, "Usage:   program wavfile.wav frequency\n\nWhere wavfile is 16 bit 44.1kHz Mono\nAnd the frequency between 87.5 and 108.0\n");
  187.    
  188.     return 0;
  189.  
  190. } // main
  191.  
  192.  
  193. //
  194. // Set up a memory regions to access GPIO
  195. //
  196. void setup_io()
  197. {
  198.     /* open /dev/mem */
  199.     if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
  200.         printf("can't open /dev/mem \n");
  201.         exit (-1);
  202.     }
  203.  
  204.     /* mmap GPIO */
  205.  
  206.     // Allocate MAP block
  207.     if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
  208.         printf("allocation error \n");
  209.         exit (-1);
  210.     }
  211.  
  212.     // Make sure pointer is on 4K boundary
  213.     if ((unsigned long)gpio_mem % PAGE_SIZE)
  214.         gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE);
  215.  
  216.     // Now map it
  217.     gpio_map = (unsigned char *)mmap(
  218.                    gpio_mem,
  219.                    BLOCK_SIZE,
  220.                    PROT_READ|PROT_WRITE,
  221.                    MAP_SHARED|MAP_FIXED,
  222.                    mem_fd,
  223.                    GPIO_BASE
  224.                );
  225.  
  226.     if ((long)gpio_map < 0) {
  227.         printf("mmap error %d\n", (int)gpio_map);
  228.         exit (-1);
  229.     }
  230.  
  231.     // Always use volatile pointer!
  232.     gpio = (volatile unsigned *)gpio_map;
  233.  
  234.  
  235. } // setup_io
clone this paste RAW Paste Data