Exemplo n.º 1
0
void main (int argc, char *argv[])
{
  mbox_t h_procs_mbox;  // Semaphore to signal the original process that we're done
  mbox_t h_n2_mbox;
  // Convert the command-line strings into integers for use as handles
  h_procs_mbox = dstrtol(argv[1], NULL, 10);
  h_n2_mbox = dstrtol(argv[2], NULL, 10);
  
  if (mbox_open(h_n2_mbox) == MBOX_FAIL) {
    Printf("inject_n2 (%d): Could not open the mailbox!\n", getpid());
    Exit();
  }
  Printf("--PID %d: INJECT N2 molecule\n", getpid());
  if (mbox_send(h_n2_mbox, 0, NULL) == MBOX_FAIL) {
    Printf("inject_n2 (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }
    
  // Signal the mbox to tell the original process that we're done
  if (mbox_open(h_procs_mbox) == MBOX_FAIL) {
    Printf("inject_n2 (%d): Could not open the mailbox!\n", getpid());
    Exit();
  }
  if (mbox_send(h_procs_mbox, 0, NULL) == MBOX_FAIL) {
    Printf("inject_n2 (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }
  // Printf("*****%s ended\n", argv[0]);
}
Exemplo n.º 2
0
void main (int argc, char *argv[])
{
  missile_code mc;         // Used to access missile codes from mailbox
  mbox_t mbox_N;           // Handle to the mbox_N
  mbox_t mbox_O2;
  mbox_t mbox_NO2;
  sem_t s_procs_completed; // Semaphore to signal the original process that we're done

  if (argc != 5) { 
    Printf("Usage: %s <handle_to_mbox_N><handle_to_mbox_O2><handle_to_mbox_NO2> <handle_to_page_mapped_semaphore>\n"); 
    Exit();
  } 

  // Convert the command-line strings into integers for use as handles
  mbox_N = dstrtol(argv[1], NULL, 10); // The "10" means base 10
  mbox_O2 = dstrtol(argv[2],NULL,10);
  mbox_NO2 = dstrtol(argv[3],NULL,10);

  s_procs_completed = dstrtol(argv[4], NULL, 10);

  // Open the mailbox
  if (mbox_open(mbox_N) == MBOX_FAIL) {
    Printf("Could not open the mbox_N!\n");
    Exit();
  }
  if (mbox_open(mbox_O2) == MBOX_FAIL) {
    Printf("Could not open the mbox_N!\n");
    Exit();
  }
  if (mbox_open(mbox_NO2) == MBOX_FAIL) {
    Printf("Could not open the mbox_N!\n");
    Exit();
  }

  // Wait for a message from the mailbox
  if (mbox_recv(mbox_N, sizeof(mc), (void *)&mc) == MBOX_FAIL) {
    Printf("Could not receive message from mbox_N!\n");
    Exit();
  }
  if (mbox_recv(mbox_O2, sizeof(mc), (void *)&mc) == MBOX_FAIL) {
    Printf("Could not receive message from mbox_O2!\n");
    Exit();
  }
  if (mbox_send(mbox_NO2, sizeof(missile_code), (void *)&mc) == MBOX_FAIL) {
    Printf("Could not send message to mbox_NO2!\n");
    Exit();
  }
  else Printf("Got 1 NO2!\n");
 
  // Now print a message to show that everything worked
 // Printf("spawn_me (%d): Received missile code: %c\n", getpid(), mc.really_important_char);

  // Signal the semaphore to tell the original process that we're done
  if(sem_signal(s_procs_completed) != SYNC_SUCCESS) {
    Printf("spawn_me (%d): Bad semaphore s_procs_completed (%d)!\n", getpid(), s_procs_completed);
    Exit();
  }

//  Printf("spawn_me (%d): Done!\n", getpid());
}
Exemplo n.º 3
0
int main(int argc, char **argv) {
	bool v3dsupported = AllocatorBase::v3d2Supported();
	AllocatorBase *allocator;
	//dispmanxtest();
	//return 0;
	if (v3dsupported) {
		v3d2_init();
		puts("using new v3d2 driver");
		allocator = new V3D2Allocator();
	} else {
		puts("using mailbox fallback");
		allocator = new MailboxAllocator();
	}
	
	// map v3d's registers into our address space.
	v3d = (unsigned *) mapmem(0x20c00000, 0x1000);
	
	if(v3d[V3D_IDENT0] != 0x02443356) { // Magic number.
		printf("Error: V3D pipeline isn't powered up and accessable.\n");
		exit(-1);
	}
	
	int mbox = mbox_open();
	testTriangle(mbox,allocator);
	//testBinner(allocator,v3d);
	return 0;
	// We now have access to the v3d registers, we should do something.
	for (int i=12; i<26; i+=1) {
		NopSled sled(allocator,(1<<i)+0xa);
		sled.benchmark(v3d);
	}
	
	return 0;
}
static int mbox_property(int file_desc, void *buf)
{
   int fd = file_desc;
   int ret_val = -1;

   if (fd < 0) {
      fd = mbox_open();
   }
   if (fd >= 0) {
      ret_val = ioctl(fd, IOCTL_MBOX_PROPERTY, buf);

      if (ret_val < 0) {
         printf("ioctl_set_msg failed, errno %d: %m\n", errno);
      }
   }
#ifdef DEBUG
   unsigned *p = buf; int i; unsigned size = *(unsigned *)buf;
   for (i=0; i<size/4; i++)
      printf("%04x: 0x%08x\n", i*sizeof *p, p[i]);
#endif
   if (file_desc < 0)
      mbox_close(fd);

   return ret_val;
}
Exemplo n.º 5
0
static void
terminate(int dummy)
{
	int i;

	dprintf("Resetting DMA...\n");
	if (dma_reg && mbox.virt_addr) {
		for (i = 0; i < num_channels; i++)
			channel_pwm[i] = 0;
		update_pwm();
		udelay(CYCLE_TIME_US);
		dma_reg[DMA_CS] = DMA_RESET;
		udelay(10);
	}

	dprintf("Freeing mbox memory...\n");
	if (mbox.virt_addr != NULL) {
		unmapmem(mbox.virt_addr, NUM_PAGES * PAGE_SIZE);
		if (mbox.handle <= 2) {
			/* we need to reopen mbox file */
			mbox.handle = mbox_open();
		}
		mem_unlock(mbox.handle, mbox.mem_ref);
		mem_free(mbox.handle, mbox.mem_ref);
		mbox_close(mbox.handle);
	}
	dprintf("Unlink %s...\n", DEVFILE);
	unlink(DEVFILE);
	dprintf("Unlink %s...\n", DEVFILE_MBOX);
	unlink(DEVFILE_MBOX);
	printf("pi-blaster stopped.\n");

	exit(1);
}
Exemplo n.º 6
0
int main(int argc, char *argv[])
{
  int mb = mbox_open();
  unsigned words[MAX_WORDS] = {};
  int i;

  if (argc < 2 || argc+1 >= MAX_WORDS)
  {
    printf("Usage %s [word0] [word1] ...\n", argv[0]);
    return 1;
  }

  words[0] = (argc+2) * sizeof words[0];
  words[1] = 0; // process request
  for (i=1; i<argc; i++)
    words[i+1] = strtoul(argv[i], 0, 0);

  words[argc+1] = 0; // end tag

  int s = mbox_property(mb, words);

  mbox_close(mb);

  for (i=0; i<argc+2; i++)
     printf("0x%08x ", words[i]);
  printf("\n");
  return s;
}
Exemplo n.º 7
0
int main(int argc, char *argv[]) {
    int i, j, k, ret, loops, freq, log2_N, jobs, N, mb = mbox_open();
    unsigned t[2];
    double tsq[2];

    GPU_FFT_COMPLEX *base;
    struct GPU_FFT *fft;

    log2_N = argc>1? atoi(argv[1]) : 12; // 8 <= log2_N <= 21
    jobs   = argc>2? atoi(argv[2]) : 1;  // transforms per batch
    loops  = argc>3? atoi(argv[3]) : 1;  // test repetitions

    if (argc<2 || jobs<1 || loops<1) {
        printf(Usage);
        return -1;
    }

    N = 1<<log2_N; // FFT length
    ret = gpu_fft_prepare(mb, log2_N, GPU_FFT_REV, jobs, &fft); // call once

    switch(ret) {
        case -1: printf("Unable to enable V3D. Please check your firmware is up to date.\n"); return -1;
        case -2: printf("log2_N=%d not supported.  Try between 8 and 21.\n", log2_N);         return -1;
        case -3: printf("Out of memory.  Try a smaller batch or increase GPU memory.\n");     return -1;
        case -4: printf("Unable to map Videocore peripherals into ARM memory space.\n");      return -1;
    }

    for (k=0; k<loops; k++) {

        for (j=0; j<jobs; j++) {
            base = fft->in + j*fft->step; // input buffer
            for (i=0; i<N; i++) base[i][0] = base[i][1] = 0;
            freq = j+1;
            base[freq][0] = base[N-freq][0] = 0.5;
        }

        usleep(1); // Yield to OS
        t[0] = Microseconds();
        gpu_fft_execute(fft); // call one or many times
        t[1] = Microseconds();

        tsq[0]=tsq[1]=0;
        for (j=0; j<jobs; j++) {
            base = fft->out + j*fft->step; // output buffer
            freq = j+1;
            for (i=0; i<N; i++) {
                double re = cos(2*GPU_FFT_PI*freq*i/N);
                tsq[0] += pow(re, 2);
                tsq[1] += pow(re - base[i][0], 2) + pow(base[i][1], 2);
            }
        }

        printf("rel_rms_err = %0.2g, usecs = %d, k = %d\n",
            sqrt(tsq[1]/tsq[0]), (t[1]-t[0])/jobs, k);
    }

    gpu_fft_release(fft); // Videocore memory lost if not freed !
    return 0;
}
Exemplo n.º 8
0
void main (int argc, char *argv[])
{
  char so4[SO4_SIZE] = {'S', 'O', '4'};

  mbox_t h_mbox;           // Handle to the mailbox
  sem_t s_procs_completed; // Semaphore to signal the original process that we're done

  if (argc != 3) { 
    Printf("Usage: %s <handle_to_mailbox> <handle_to_page_mapped_semaphore>\n"); 
    Exit();
  } 

  // Convert the command-line strings into integers for use as handles
  h_mbox = dstrtol(argv[1], NULL, 10); // The "10" means base 10
  s_procs_completed = dstrtol(argv[2], NULL, 10);

  // Open the mailbox
  if (mbox_open(h_mbox) == MBOX_FAIL) {
    Printf("Generator SO4 (%d): Could not open the mailbox!\n", getpid());
    Exit();
  }

  // Send a message to the mailbox
  if (mbox_send(h_mbox, SO4_SIZE, (void *) so4) == MBOX_FAIL) {
    Printf("Generator SO4 (%d): Could not send message to the mailbox %d!\n", getpid(), h_mbox);
    Exit();
  }
 
  // Now print a message to show that everything worked
  Printf("Generate SO4 Molecule\n");

  // Close the mbox
  if (mbox_close(h_mbox) == MBOX_FAIL) {
    Printf("Generator SO4 (%d): Could not close the mailbox!\n", getpid());
    Exit();
  }


  // Signal the semaphore to tell the original process that we're done
  if(sem_signal(s_procs_completed) != SYNC_SUCCESS) {
    Printf("Generator SO4 (%d): Bad semaphore s_procs_completed (%d)!\n", getpid(), s_procs_completed);
    Exit();
  }

  Printf("Generator SO4 (%d): Done!\n", getpid());

}
Exemplo n.º 9
0
char InitDma(void *FunctionTerminate)
{
	//printf("Init DMA\n");
	
	// Catch all signals possible - it is vital we kill the DMA engine
	// on process exit!
	int i;
	for (i = 0; i < 64; i++) {
		struct sigaction sa;

		memset(&sa, 0, sizeof(sa));
		sa.sa_handler = FunctionTerminate;//terminate;
		sigaction(i, &sa, NULL);
	}

	NUM_SAMPLES = NUM_SAMPLES_MAX;

	/* Use the mailbox interface to the VC to ask for physical memory */
	/*unlink(MBFILE);
	if (mknod(MBFILE, S_IFCHR|0600, makedev(100, 0)) < 0)
	{
		printf("Failed to create mailbox device\n");
		return 0;
	}
	*/
	mbox.handle = mbox_open();
	if (mbox.handle < 0)
	{
		printf("Failed to open mailbox\n");
		return(0);
	}
	
	mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES* PAGE_SIZE, PAGE_SIZE, mem_flag);
	/* TODO: How do we know that succeeded? */
	//printf("mem_ref %x\n", mbox.mem_ref);
	mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref);
	//printf("bus_addr = %x\n", mbox.bus_addr);
	mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES* PAGE_SIZE);
	//printf("virt_addr %p\n", mbox.virt_addr);
	virtbase = (uint32_t *)mbox.virt_addr;
	//printf("virtbase %p\n", virtbase);
	return(1);
	
}
Exemplo n.º 10
0
int main(int argc, char **argv) {
  mbox = mbox_open();

  // The blob now has this nice handy call which powers up the v3d pipeline.
  qpu_enable(mbox, 1);

  // map v3d's registers into our address space.
  v3d = (unsigned *) mapmem(0x20c00000, 0x1000);

  if(v3d[V3D_IDENT0] != 0x02443356) { // Magic number.
    printf("Error: V3D pipeline isn't powered up and accessable.\n");
    exit(-1);
  }

  // We now have access to the v3d registers, we should do something.
  testTriangle();

  return 0;
}
Exemplo n.º 11
0
void main (int argc, char *argv[])
{
    sem_t s_procs_completed;    // Semaphore to signal the original process that we're done
    mbox_t mb_n2;                // mailbox for H2O atom

    Printf("Starting N2 Injection - PID %d \n", getpid());

    if (argc > 4 ) { 
        Printf("Usage: "); Printf(argv[0]); Printf(" <handle_to_proc_semaphore> <handle_to_N2_mailbox>\n"); 
        Exit();
    } 

    // Convert the command-line strings into integers for use as handles
    s_procs_completed = dstrtol(argv[1], NULL, 10);
    mb_n2 = dstrtol(argv[2], NULL, 10);
   
    if(!mbox_open(mb_n2)){
        Printf("Bad mailbox open mb_n2\n");
        Exit();
    }

    Printf("opened n2 mailbox\n");

    if(mbox_send(mb_n2, 2, (void *) "N2") != MBOX_SUCCESS){
        Printf("N2 send error\n");
    }
    Printf("Sent N2 to mb_n2\n");

    if(!mbox_close(mb_n2)){
        Printf("Bad mailbox open mb_n2\n");
        Exit();
    }

    // Signal the semaphore to tell the original process that we're done
    Printf("Inject N2: PID %d is complete.\n", getpid());

    if(sem_signal(s_procs_completed) != SYNC_SUCCESS) {
        Printf("Bad semaphore s_procs_completed (%d) in ", s_procs_completed); Printf(argv[0]); Printf(", exiting...\n");
        Exit();
    }
}
Exemplo n.º 12
0
Arquivo: main.c Projeto: alexburov/fft
int main(int argc, char *argv[]) {
     unsigned t[2];
     struct GPU_FFT_COMPLEX *dataIn,*dataOut;
     struct GPU_FFT *fftinfo;

     int mb = mbox_open();
     gpu_fft_prepare(mb,12,GPU_FFT_FWD,1,&fftinfo);

     dataIn = fftinfo->in;
     dataOut = fftinfo->out;

     usleep(1); // Yield to OS
     t[0] = Microseconds();
     gpu_fft_execute(fftinfo); // call one or many times
     t[1] = Microseconds();

     printf("usecs = %d\n", (t[1]-t[0]));

     gpu_fft_release(fftinfo); // Videocore memory lost if not freed !
     return 0;
}
Exemplo n.º 13
0
void main (int argc, char *argv[])
{
  message m;         // Used to access missile codes from mailbox
  //mbox_t h_mbox;           // Handle to the mailbox
  sem_t s_procs_completed; // Semaphore to signal the original process that we're done
  int h2o_mbox;

  if (argc != 3) {
    Printf("\tUsage: %s <handle_to_h2o_mailbox> <handle_to_page_mapped_semaphore>\n");
    Exit();
  }

  // Convert the command-line strings into integers for use as handles
  h2o_mbox = dstrtol(argv[1], NULL, 10); // The "10" means base 10
  s_procs_completed = dstrtol(argv[2], NULL, 10);

  // Open the mailbox
  if (mbox_open(h2o_mbox) == MBOX_FAIL) {
    Printf("\tspawn_water (%d): Could not open h2o the mailbox!\n", getpid());
    Exit();
  }


  if (mbox_send(h2o_mbox, sizeof(m), (void *)&m) == MBOX_FAIL) {
    Printf("\tspawn_water (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }

  // Now print a message to show that everything worked
  Printf("\tspawn_water (%d): H2O molcule created. Injecting it into atmosphere. %d\n", getpid());

  Printf("\tspawn_water (%d): Done!\n\n", getpid());
  // Signal the semaphore to tell the original process that we're done
  if(sem_signal(s_procs_completed) != SYNC_SUCCESS) {
    Printf("\tspawn_water (%d): Bad semaphore s_procs_completed (%d)!\n", getpid(), s_procs_completed);
    Exit();
  }


}
Exemplo n.º 14
0
static int mbox_property(int file_desc, void *buf) {
    int fd = file_desc;
    int ret_val = -1;

    if (fd < 0) {
        fd = mbox_open();
    }

    if (fd >= 0) {
        ret_val = ioctl(fd, IOCTL_MBOX_PROPERTY, buf);

        if (ret_val < 0) {
            perror("ioctl_set_msg failed\n");
        }
    }

    if (file_desc < 0) {
        mbox_close(fd);
    }

    return ret_val;
}
Exemplo n.º 15
0
void main (int argc, char *argv[])
{
  char h2_buffer[H2_SIZE];
  char o2_buffer[O2_SIZE];
  char so2_buffer[SO2_SIZE];

  char h2so4_molecule[H2SO4_SIZE] = {'H', '2', 'S', 'O', '4'};

  mbox_t h_mbox_h2;
  mbox_t h_mbox_o2;
  mbox_t h_mbox_so2;
  mbox_t h_mbox_h2so4;

  sem_t s_procs_completed; // Semaphore to signal the original process that we're done

  /* int ct; */
  /* Printf("argc = %d\n", argc); */
  /* for(ct = 0 ; ct < argc; ct++){ */
  /*   Printf("argv[%d] = %s\n", ct, argv[ct]); */
  /* } */

  if (argc != 6) { 
    Printf("Usage: %s <mailbox h2> <mailbox o2> <mailbox so2> <mailbox h2so4> <handle_to_page_mapped_semaphore>\n"); 
    Exit();
  } 

  // Convert the command-line strings into integers for use as handles
  h_mbox_h2 = dstrtol(argv[1], NULL, 10); // The "10" means base 10
  h_mbox_o2 = dstrtol(argv[2], NULL, 10); // The "10" means base 10
  h_mbox_so2 = dstrtol(argv[3], NULL, 10); // The "10" means base 10
  h_mbox_h2so4 = dstrtol(argv[4], NULL, 10); // The "10" means base 10


  s_procs_completed = dstrtol(argv[5], NULL, 10);

  // Open the h2 mailbox
  if (mbox_open(h_mbox_h2) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not open the so4 mailbox!\n", getpid());
    Exit();
  }

  // Wait for the h2 molecule from the mailbox
  if (mbox_recv(h_mbox_h2, H2_SIZE, (void *) h2_buffer) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not receive message from the mbox %d!\n", getpid(), h_mbox_h2);
    Exit();
  }

  // Close the h2 mailbox
  if (mbox_close(h_mbox_h2) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not close the mailbox!\n", getpid());
    Exit();
  }


  // Open the o2 mailbox
  if (mbox_open(h_mbox_o2) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not open the o2 mailbox!\n", getpid());
    Exit();
  }
  

  // Send the o2 to the o2 mailbox
  if (mbox_recv(h_mbox_o2, O2_SIZE, (void *) o2_buffer) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not send message to the mbox %d!\n", getpid(), h_mbox_o2);
    Exit();
  }

  // Close the o2 mailbox
  if (mbox_close(h_mbox_o2) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not close the mailbox!\n", getpid());
    Exit();
  }


  // Open the SO2 mailbox
  if (mbox_open(h_mbox_so2) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not open the so2 mailbox!\n", getpid());
    Exit();
  }

  // Send the SO2 to the SO2 mailbox
  if (mbox_recv(h_mbox_so2, SO2_SIZE, (void *) so2_buffer) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not send message to the mbox %d!\n", getpid(), h_mbox_so2);
    Exit();
  }

  // Close the SO2 mailbox
  if (mbox_close(h_mbox_so2) == MBOX_FAIL) {
    Printf("Reaction 2 (%d): Could not close the mailbox!\n", getpid());
    Exit();
  }

    // Open the h2so4 mailbox
  if (mbox_open(h_mbox_h2so4) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not open the h2so4 mailbox!\n", getpid());
    Exit();
  }
  

  // Send the h2so4 to the o2 mailbox
  if (mbox_send(h_mbox_h2so4, H2SO4_SIZE, (void *) h2so4_molecule) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not send message to the mbox %d!\n", getpid(), h_mbox_h2so4);
    Exit();
  }

  // Close the h2so4 mailbox
  if (mbox_close(h_mbox_h2so4) == MBOX_FAIL) {
    Printf("Reaction 3 (%d): Could not close the mailbox!\n", getpid());
    Exit();
  }



  // Now print a message to show that everything worked
  Printf("A molecule H2SO4 has been generated\n");

  // Signal the semaphore to tell the original process that we're done
  if(sem_signal(s_procs_completed) != SYNC_SUCCESS) {
    Printf("Reaction 3 (%d): Bad semaphore s_procs_completed (%d)!\n", getpid(), s_procs_completed);
    Exit();
  }

  Printf("Reaction 3 (%d): Done!\n", getpid());
}
Exemplo n.º 16
0
void main (int argc, char *argv[])
{
  int ct;

  char h2o_buffer_1[H2O_SIZE];
  char h2o_buffer_2[H2O_SIZE];

  char h2_molecule[H2_SIZE] = {'H', '2'};
  char o2_molecule[O2_SIZE] = {'O', '2'};
  
  mbox_t h_mbox_h2o;           // Handle to the mailbox for h2o
  mbox_t h_mbox_h2;
  mbox_t h_mbox_o2;

  sem_t s_procs_completed; // Semaphore to signal the original process that we're done

  if (argc != 5) { 
    Printf("Usage: %s <mailbox h2o> <mailbox h2> <mailbox o2> <handle_to_page_mapped_semaphore>\n"); 
    Exit();
  } 

  // Convert the command-line strings into integers for use as handles
  h_mbox_h2o = dstrtol(argv[1], NULL, 10); // The "10" means base 10
  h_mbox_h2 = dstrtol(argv[2], NULL, 10); // The "10" means base 10
  h_mbox_o2 = dstrtol(argv[3], NULL, 10); // The "10" means base 10

  s_procs_completed = dstrtol(argv[4], NULL, 10);

  // Open the h2o mailbox
  if (mbox_open(h_mbox_h2o) == MBOX_FAIL) {
    Printf("Reaction 1 (%d): Could not open the h2o mailbox!\n", getpid());
    Exit();
  }

  // Wait for the first h2o molecule from the mailbox
  if (mbox_recv(h_mbox_h2o, H2O_SIZE, (void *) h2o_buffer_1) == MBOX_FAIL) {
    Printf("Reaction 1 (%d): Could not receive message from the mbox %d!\n", getpid(), h_mbox_h2o);
    Exit();
  }

  // Wait for the second h2o molecule from the mailbox  
  if (mbox_recv(h_mbox_h2o, H2O_SIZE, (void *) h2o_buffer_2) == MBOX_FAIL) {
    Printf("Reaction 1 (%d): Could not receive message from the mbox %d!\n", getpid(), h_mbox_h2o);
    Exit();
  }

  // Close the h2o mailbox
  if (mbox_close(h_mbox_h2o) == MBOX_FAIL) {
    Printf("Reaction 1 (%d): Could not close the mailbox!\n", getpid());
    Exit();
  }

  // Open the h2 mailbox
  if (mbox_open(h_mbox_h2) == MBOX_FAIL) {
    Printf("Reaction 1 (%d): Could not open the h2 mailbox!\n", getpid());
    Exit();
  }


  // Send the first h2 to the h2 mailbox
  if (mbox_send(h_mbox_h2, H2_SIZE, (void *) h2_molecule) == MBOX_FAIL) {
    Printf("Generator h2 (%d): Could not send message to the mbox %d!\n", getpid(), h_mbox_h2);
    Exit();
  }

  // Send the second h2 to the h2 mailbox
  if (mbox_send(h_mbox_h2, H2_SIZE, (void *) h2_molecule) == MBOX_FAIL) {
    Printf("Generator h2 (%d): Could not send message to the mbox %d!\n", getpid(), h_mbox_h2);
    Exit();
  }


  // Close the h2 mailbox
  if (mbox_close(h_mbox_h2) == MBOX_FAIL) {
    Printf("Generator h2 (%d): Could not close the mailbox!\n", getpid());
    Exit();
  }


  // Open the o2 mailbox
  if (mbox_open(h_mbox_o2) == MBOX_FAIL) {
    Printf("Reaction 1 (%d): Could not open the o2 mailbox!\n", getpid());
    Exit();
  }
  

  // Send the o2 to the o2 mailbox
  if (mbox_send(h_mbox_o2, O2_SIZE, (void *) o2_molecule) == MBOX_FAIL) {
    Printf("Reaction o2 (%d): Could not send message to the mbox %d!\n", getpid(), h_mbox_o2);
    Exit();
  }

  // Close the o2 mailbox
  if (mbox_close(h_mbox_o2) == MBOX_FAIL) {
    Printf("Reaction o2 (%d): Could not close the mailbox!\n", getpid());
    Exit();
  }

  // Now print a message to show that everything worked
  Printf("Two molecules H2 has been generated\n");
  Printf("A molecule O2 has been generated\n");

  // Signal the semaphore to tell the original process that we're done
  if(sem_signal(s_procs_completed) != SYNC_SUCCESS) {
    Printf("Reaction 1 (%d): Bad semaphore s_procs_completed (%d)!\n", getpid(), s_procs_completed);
    Exit();
  }

  Printf("Reaction 1 (%d): Done!\n", getpid());
}
Exemplo n.º 17
0
void main (int argc, char *argv[])
{
  message m;         // Used to access missile codes from mailbox
  //mbox_t h_mbox;           // Handle to the mailbox
  sem_t s_procs_completed; // Semaphore to signal the original process that we're done
  int so2_mbox,h2_mbox,o2_mbox;

  if (argc != 5) {
    Printf("\tUsage: %s <handle_to_so2_mailbox> <handle_to_h2_mailbox> <handle_to_o2_mailbox> <handle_to_page_mapped_semaphore>\n");
    Exit();
  }

  // Convert the command-line strings into integers for use as handles
  so2_mbox = dstrtol(argv[1], NULL, 10); // The "10" means base 10
  h2_mbox = dstrtol(argv[2], NULL, 10);
  o2_mbox = dstrtol(argv[3], NULL, 10);
  s_procs_completed = dstrtol(argv[4], NULL, 10);


  // Open the mailbox
  if (mbox_open(so2_mbox) == MBOX_FAIL) {
    Printf("\tspawn_rx3 (%d): Could not open the so2 mailbox!\n", getpid());
    Exit();
  }
  if (mbox_open(h2_mbox) == MBOX_FAIL) {
    Printf("\tspawn_rx3 (%d): Could not open the h2 mailbox!\n", getpid());
    Exit();
  }
  if (mbox_open(o2_mbox) == MBOX_FAIL) {
    Printf("\tspawn_rx3 (%d): Could not open the o2 mailbox!\n", getpid());
    Exit();
  }


  // Wait for a message from the mailbox
  if (mbox_recv(so2_mbox, sizeof(m), (void *)&m) == MBOX_FAIL) {
    Printf("\tspawn_rx3 (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }
  if (mbox_recv(h2_mbox, sizeof(m), (void *)&m) == MBOX_FAIL) {
    Printf("\tspawn_rx3 (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }
  if (mbox_recv(o2_mbox, sizeof(m), (void *)&m) == MBOX_FAIL) {
    Printf("\tspawn_rx3 (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }

  // Now print a message to show that everything worked
  Printf("\tspawn_rx3 (%d): 1 molcule of H2, SO2 and O2 are present. starting reaction 3\n", getpid());
  //Printf("\tspawn_rx3 (%d): Reaction in process, will take 2 yields.\n", getpid());
  //yield();
  //yield();
//  sleep(1);
  Printf("\tspawn_rx3 (%d): Consuming 1 molcule of H2, SO2 and O2.\n", getpid());
  Printf("\tspawn_rx3 (%d): H2SO4 molecule created.\n", getpid());


  Printf("\tspawn_rx3 (%d): Done!\n\n", getpid());
  // Signal the semaphore to tell the original process that we're done
  if(sem_signal(s_procs_completed) != SYNC_SUCCESS) {
    Printf("\tspawn_rx3 (%d): Bad semaphore s_procs_completed (%d)!\n", getpid(), s_procs_completed);
    Exit();
  }

}
Exemplo n.º 18
0
int
main(int argc, char **argv)
{
	parseargs(argc, argv);
	mbox.handle = mbox_open();
	if (mbox.handle < 0)
		fatal("Failed to open mailbox\n");
	unsigned mbox_board_rev = get_board_revision(mbox.handle);
	printf("MBox Board Revision: %#x\n", mbox_board_rev);
	get_model(mbox_board_rev);
	unsigned mbox_dma_channels = get_dma_channels(mbox.handle);
	printf("DMA Channels Info: %#x, using DMA Channel: %d\n", mbox_dma_channels, DMA_CHAN_NUM);

	printf("Using hardware:                 %5s\n", delay_hw == DELAY_VIA_PWM ? "PWM" : "PCM");
	printf("Number of channels:             %5d\n", (int)num_channels);
	printf("PWM frequency:               %5d Hz\n", 1000000/CYCLE_TIME_US);
	printf("PWM steps:                      %5d\n", NUM_SAMPLES);
	printf("Maximum period (100  %%):      %5dus\n", CYCLE_TIME_US);
	printf("Minimum period (%1.3f%%):      %5dus\n", 100.0*SAMPLE_US / CYCLE_TIME_US, SAMPLE_US);
	printf("DMA Base:                  %#010x\n", DMA_BASE);

	setup_sighandlers();

	/* map the registers for all DMA Channels */
	dma_virt_base = map_peripheral(DMA_BASE, (DMA_CHAN_SIZE * (DMA_CHAN_MAX + 1)));
	/* set dma_reg to point to the DMA Channel we are using */
	dma_reg = dma_virt_base + DMA_CHAN_NUM * (DMA_CHAN_SIZE / sizeof(dma_reg));
	pwm_reg = map_peripheral(PWM_BASE, PWM_LEN);
	pcm_reg = map_peripheral(PCM_BASE, PCM_LEN);
	clk_reg = map_peripheral(CLK_BASE, CLK_LEN);
	gpio_reg = map_peripheral(GPIO_BASE, GPIO_LEN);

	/* Use the mailbox interface to the VC to ask for physical memory */
	mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES * PAGE_SIZE, PAGE_SIZE, mem_flag);
	/* TODO: How do we know that succeeded? */
	dprintf("mem_ref %u\n", mbox.mem_ref);
	mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref);
	dprintf("bus_addr = %#x\n", mbox.bus_addr);
	mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES * PAGE_SIZE);
	dprintf("virt_addr %p\n", mbox.virt_addr);

	if ((unsigned long)mbox.virt_addr & (PAGE_SIZE-1))
		fatal("pi-blaster: Virtual address is not page aligned\n");

	/* we are done with the mbox */
	mbox_close(mbox.handle);
	mbox.handle = -1;
	
	//fatal("TempFatal\n");

	init_ctrl_data();
	init_hardware();
	init_channel_pwm();
	// Init pin2gpio array with 0/false values to avoid locking all of them as PWM.
	init_pin2gpio();
	// Only calls update_pwm after ctrl_data calculates the pin mask to unlock all pins on start.
	init_pwm();
	unlink(DEVFILE);
	if (mkfifo(DEVFILE, 0666) < 0)
		fatal("pi-blaster: Failed to create %s: %m\n", DEVFILE);
	if (chmod(DEVFILE, 0666) < 0)
		fatal("pi-blaster: Failed to set permissions on %s: %m\n", DEVFILE);

	printf("Initialised, ");
	if (daemonize) {
		if (daemon(0,1) < 0) 
			fatal("pi-blaster: Failed to daemonize process: %m\n");
		else
			printf("Daemonized, ");
	}
	printf("Reading %s.\n", DEVFILE);

	go_go_go();

	return 0;
}
Exemplo n.º 19
0
static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr)
{
    const char *myname = "deliver_mailbox_file";
    DSN_BUF *why = state.msg_attr.why;
    MBOX   *mp;
    int     mail_copy_status;
    int     deliver_status;
    int     copy_flags;
    long    end;
    struct stat st;

    /*
     * Make verbose logging easier to understand.
     */
    state.level++;
    if (msg_verbose)
	MSG_LOG_STATE(myname, state);

    /*
     * Don't deliver trace-only requests.
     */
    if (DEL_REQ_TRACE_ONLY(state.request->flags)) {
	dsb_simple(why, "2.0.0", "delivers to mailbox");
	return (sent(BOUNCE_FLAGS(state.request),
		     SENT_ATTR(state.msg_attr)));
    }

    /*
     * Initialize. Assume the operation will fail. Set the delivered
     * attribute to reflect the final recipient.
     */
    if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0)
	msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp));
    state.msg_attr.delivered = state.msg_attr.rcpt.address;
    mail_copy_status = MAIL_COPY_STAT_WRITE;

    /*
     * Lock the mailbox and open/create the mailbox file.
     * 
     * Write the file as the recipient, so that file quota work.
     */
    copy_flags = MAIL_COPY_MBOX;

    set_eugid(usr_attr.uid, usr_attr.gid);
    mp = mbox_open(usr_attr.mailbox, O_APPEND | O_WRONLY | O_CREAT,
		   S_IRUSR | S_IWUSR, &st, -1, -1,
		   virtual_mbox_lock_mask, "4.2.0", why);
    if (mp != 0) {
	if (S_ISREG(st.st_mode) == 0) {
	    vstream_fclose(mp->fp);
	    msg_warn("recipient %s: destination %s is not a regular file",
		     state.msg_attr.rcpt.address, usr_attr.mailbox);
	    dsb_simple(why, "5.3.5", "mail system configuration error");
	} else if (var_strict_mbox_owner && st.st_uid != usr_attr.uid) {
	    vstream_fclose(mp->fp);
	    dsb_simple(why, "4.2.0",
	      "destination %s is not owned by recipient", usr_attr.mailbox);
	    msg_warn("specify \"%s = no\" to ignore mailbox ownership mismatch",
		     VAR_STRICT_MBOX_OWNER);
	} else {
	    end = vstream_fseek(mp->fp, (off_t) 0, SEEK_END);
	    mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp,
					 copy_flags, "\n", why);
	}
	mbox_release(mp);
    }
    set_eugid(var_owner_uid, var_owner_gid);

    /*
     * As the mail system, bounce, defer delivery, or report success.
     */
    if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) {
	deliver_status = DEL_STAT_DEFER;
    } else if (mail_copy_status != 0) {
	vstring_sprintf_prepend(why->reason, "delivery failed to mailbox %s: ",
				usr_attr.mailbox);
	deliver_status =
	    (STR(why->status)[0] == '4' ?
	     defer_append : bounce_append)
	    (BOUNCE_FLAGS(state.request),
	     BOUNCE_ATTR(state.msg_attr));
    } else {
	dsb_simple(why, "2.0.0", "delivered to mailbox");
	deliver_status = sent(BOUNCE_FLAGS(state.request),
			      SENT_ATTR(state.msg_attr));
    }
    return (deliver_status);
}
Exemplo n.º 20
0
void init_fft() {
	int ret;
	mb = mbox_open();
	ret = gpu_fft_prepare(mb, log2N, GPU_FFT_FWD, 1, &fft);
}
Exemplo n.º 21
0
static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr)
{
    const char *myname = "deliver_mailbox_file";
    char   *spool_dir;
    char   *mailbox;
    DSN_BUF *why = state.msg_attr.why;
    MBOX   *mp;
    int     mail_copy_status;
    int     deliver_status;
    int     copy_flags;
    VSTRING *biff;
    long    end;
    struct stat st;
    uid_t   spool_uid;
    gid_t   spool_gid;
    uid_t   chown_uid;
    gid_t   chown_gid;

    /*
     * Make verbose logging easier to understand.
     */
    state.level++;
    if (msg_verbose)
	MSG_LOG_STATE(myname, state);

    /*
     * Don't deliver trace-only requests.
     */
    if (DEL_REQ_TRACE_ONLY(state.request->flags)) {
	dsb_simple(why, "2.0.0", "delivers to mailbox");
	return (sent(BOUNCE_FLAGS(state.request), SENT_ATTR(state.msg_attr)));
    }

    /*
     * Initialize. Assume the operation will fail. Set the delivered
     * attribute to reflect the final recipient.
     */
    if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0)
	msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp));
    if (var_frozen_delivered == 0)
	state.msg_attr.delivered = state.msg_attr.rcpt.address;
    mail_copy_status = MAIL_COPY_STAT_WRITE;
    if (*var_home_mailbox) {
	spool_dir = 0;
	mailbox = concatenate(usr_attr.home, "/", var_home_mailbox, (char *) 0);
    } else {
	spool_dir = var_mail_spool_dir;
	mailbox = concatenate(spool_dir, "/", state.msg_attr.user, (char *) 0);
    }

    /*
     * Mailbox delivery with least privilege. As long as we do not use root
     * privileges this code may also work over NFS.
     * 
     * If delivering to the recipient's home directory, perform all operations
     * (including file locking) as that user (Mike Muuss, Army Research
     * Laboratory, USA).
     * 
     * If delivering to the mail spool directory, and the spool directory is
     * world-writable, deliver as the recipient; if the spool directory is
     * group-writable, use the recipient user id and the mail spool group id.
     * 
     * Otherwise, use root privileges and chown the mailbox.
     */
    if (spool_dir == 0
	|| stat(spool_dir, &st) < 0
	|| (st.st_mode & S_IWOTH) != 0) {
	spool_uid = usr_attr.uid;
	spool_gid = usr_attr.gid;
    } else if ((st.st_mode & S_IWGRP) != 0) {
	spool_uid = usr_attr.uid;
	spool_gid = st.st_gid;
    } else {
	spool_uid = 0;
	spool_gid = 0;
    }
    if (spool_uid == usr_attr.uid) {
	chown_uid = -1;
	chown_gid = -1;
    } else {
	chown_uid = usr_attr.uid;
	chown_gid = usr_attr.gid;
    }
    if (msg_verbose)
	msg_info("spool_uid/gid %ld/%ld chown_uid/gid %ld/%ld",
		 (long) spool_uid, (long) spool_gid,
		 (long) chown_uid, (long) chown_gid);

    /*
     * Lock the mailbox and open/create the mailbox file. Depending on the
     * type of locking used, we lock first or we open first.
     * 
     * Write the file as the recipient, so that file quota work.
     */
    copy_flags = MAIL_COPY_MBOX;
    if ((local_deliver_hdr_mask & DELIVER_HDR_FILE) == 0)
	copy_flags &= ~MAIL_COPY_DELIVERED;

    set_eugid(spool_uid, spool_gid);
    mp = mbox_open(mailbox, O_APPEND | O_WRONLY | O_CREAT,
		   S_IRUSR | S_IWUSR, &st, chown_uid, chown_gid,
		   local_mbox_lock_mask, "5.2.0", why);
    if (mp != 0) {
	if (spool_uid != usr_attr.uid || spool_gid != usr_attr.gid)
	    set_eugid(usr_attr.uid, usr_attr.gid);
	if (S_ISREG(st.st_mode) == 0) {
	    vstream_fclose(mp->fp);
	    dsb_simple(why, "5.2.0",
		       "destination %s is not a regular file", mailbox);
	} else if (var_strict_mbox_owner && st.st_uid != usr_attr.uid) {
	    vstream_fclose(mp->fp);
	    dsb_simple(why, "4.2.0",
		       "destination %s is not owned by recipient", mailbox);
	    msg_warn("specify \"%s = no\" to ignore mailbox ownership mismatch",
		     VAR_STRICT_MBOX_OWNER);
	} else {
	    end = vstream_fseek(mp->fp, (off_t) 0, SEEK_END);
	    mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp,
					 copy_flags, "\n", why);
	}
	if (spool_uid != usr_attr.uid || spool_gid != usr_attr.gid)
	    set_eugid(spool_uid, spool_gid);
	mbox_release(mp);
    }
    set_eugid(var_owner_uid, var_owner_gid);

    /*
     * As the mail system, bounce, defer delivery, or report success.
     */
    if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) {
	deliver_status = DEL_STAT_DEFER;
    } else if (mail_copy_status != 0) {
	vstring_sprintf_prepend(why->reason,
				"cannot update mailbox %s for user %s. ",
				mailbox, state.msg_attr.user);
	deliver_status =
	    (STR(why->status)[0] == '4' ?
	     defer_append : bounce_append)
	    (BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr));
    } else {
	dsb_simple(why, "2.0.0", "delivered to mailbox");
	deliver_status = sent(BOUNCE_FLAGS(state.request),
			      SENT_ATTR(state.msg_attr));
	if (var_biff) {
	    biff = vstring_alloc(100);
	    vstring_sprintf(biff, "%s@%ld", usr_attr.logname, (long) end);
	    biff_notify(STR(biff), VSTRING_LEN(biff) + 1);
	    vstring_free(biff);
	}
    }

    /*
     * Clean up.
     */
    myfree(mailbox);
    return (deliver_status);
}
Exemplo n.º 22
0
int     deliver_file(LOCAL_STATE state, USER_ATTR usr_attr, char *path)
{
    const char *myname = "deliver_file";
    struct stat st;
    MBOX   *mp;
    DSN_BUF *why = state.msg_attr.why;
    int     mail_copy_status = MAIL_COPY_STAT_WRITE;
    int     deliver_status;
    int     copy_flags;

    /*
     * Make verbose logging easier to understand.
     */
    state.level++;
    if (msg_verbose)
	MSG_LOG_STATE(myname, state);

    /*
     * DUPLICATE ELIMINATION
     * 
     * Skip this file if it was already delivered to as this user.
     */
    if (been_here(state.dup_filter, "file %ld %s", (long) usr_attr.uid, path))
	return (0);

    /*
     * DELIVERY POLICY
     * 
     * Do we allow delivery to files?
     */
    if ((local_file_deliver_mask & state.msg_attr.exp_type) == 0) {
	dsb_simple(why, "5.7.1", "mail to file is restricted");
	/* Account for possible owner- sender address override. */
	return (bounce_workaround(state));
    }

    /*
     * Don't deliver trace-only requests.
     */
    if (DEL_REQ_TRACE_ONLY(state.request->flags)) {
	dsb_simple(why, "2.0.0", "delivers to file: %s", path);
	return (sent(BOUNCE_FLAGS(state.request),
		     SENT_ATTR(state.msg_attr)));
    }

    /*
     * DELIVERY RIGHTS
     * 
     * Use a default uid/gid when none are given.
     */
    if (usr_attr.uid == 0 && (usr_attr.uid = var_default_uid) == 0)
	msg_panic("privileged default user id");
    if (usr_attr.gid == 0 && (usr_attr.gid = var_default_gid) == 0)
	msg_panic("privileged default group id");

    /*
     * If the name ends in /, use maildir-style delivery instead.
     */
    if (path[strlen(path) - 1] == '/')
	return (deliver_maildir(state, usr_attr, path));

    /*
     * Deliver. From here on, no early returns or we have a memory leak.
     */
    if (msg_verbose)
	msg_info("deliver_file (%ld,%ld): %s",
		 (long) usr_attr.uid, (long) usr_attr.gid, path);
    if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0)
	msg_fatal("seek queue file %s: %m", state.msg_attr.queue_id);

    /*
     * As the specified user, open or create the file, lock it, and append
     * the message.
     */
    copy_flags = MAIL_COPY_MBOX;
    if ((local_deliver_hdr_mask & DELIVER_HDR_FILE) == 0)
	copy_flags &= ~MAIL_COPY_DELIVERED;

    set_eugid(usr_attr.uid, usr_attr.gid);
    mp = mbox_open(path, O_APPEND | O_CREAT | O_WRONLY,
		   S_IRUSR | S_IWUSR, &st, -1, -1,
		   local_mbox_lock_mask | MBOX_DOT_LOCK_MAY_FAIL,
		   "5.2.0", why);
    if (mp != 0) {
	if (S_ISREG(st.st_mode) && st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
	    vstream_fclose(mp->fp);
	    dsb_simple(why, "5.7.1", "file is executable");
	} else {
	    mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp,
					 S_ISREG(st.st_mode) ? copy_flags :
					 (copy_flags & ~MAIL_COPY_TOFILE),
					 "\n", why);
	}
	mbox_release(mp);
    }
    set_eugid(var_owner_uid, var_owner_gid);

    /*
     * As the mail system, bounce, defer delivery, or report success.
     */
    if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) {
	deliver_status = DEL_STAT_DEFER;
    } else if (mail_copy_status != 0) {
	vstring_sprintf_prepend(why->reason,
				"cannot append message to file %s: ", path);
	if (STR(why->status)[0] == '4')
	    deliver_status =
		defer_append(BOUNCE_FLAGS(state.request),
			     BOUNCE_ATTR(state.msg_attr));
	else
	    /* Account for possible owner- sender address override. */
	    deliver_status = bounce_workaround(state);
    } else {
	dsb_simple(why, "2.0.0", "delivered to file: %s", path);
	deliver_status = sent(BOUNCE_FLAGS(state.request),
			      SENT_ATTR(state.msg_attr));
    }
    return (deliver_status);
}
Exemplo n.º 23
0
void main (int argc, char *argv[])
{
  message m;         // Used to access missile codes from mailbox
  mbox_t h_mbox;           // Handle to the mailbox
  sem_t s_procs_completed; // Semaphore to signal the original process that we're done
  int so4_mbox,so2_mbox,o2_mbox;

  if (argc != 5) {
    Printf("\tUsage: %s <handle_to_so4_mailbox> <handle_to_so2_mailbox> <handle_to_o2_mailbox> <handle_to_page_mapped_semaphore>\n");
    Exit();
  }

  // Convert the command-line strings into integers for use as handles
  so4_mbox = dstrtol(argv[1], NULL, 10); // The "10" means base 10
  so2_mbox = dstrtol(argv[2], NULL, 10);
  o2_mbox = dstrtol(argv[3], NULL, 10);
  s_procs_completed = dstrtol(argv[4], NULL, 10);


  // Open the mailbox
  if (mbox_open(so4_mbox) == MBOX_FAIL) {
    Printf("\tspawn_rx2 (%d): Could not open the so4 mailbox!\n", getpid());
    Exit();
  }
  if (mbox_open(so2_mbox) == MBOX_FAIL) {
    Printf("\tspawn_rx2 (%d): Could not open the so2 mailbox!\n", getpid());
    Exit();
  }
  if (mbox_open(o2_mbox) == MBOX_FAIL) {
    Printf("\tspawn_rx2 (%d): Could not open the o2 mailbox!\n", getpid());
    Exit();
  }


  // Wait for a message from the mailbox
  if (mbox_recv(so4_mbox, sizeof(m), (void *)&m) == MBOX_FAIL) {
    Printf("\tspawn_rx2 (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }
  Printf("\tspawn_rx2 (%d): One SO4 molecule present. Begin reaction...\n", getpid());
//  sleep(1);
  if (mbox_send(so2_mbox, sizeof(m), (void *)&m) == MBOX_FAIL) {
    Printf("\tspawn_rx2 (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }
  Printf("\tspawn_rx2 (%d):Created an SO2 molecule... continue\n", getpid());
//  sleep(1);
  if (mbox_send(o2_mbox, sizeof(m), (void *)&m) == MBOX_FAIL) {
    Printf("\tspawn_rx2 (%d): Could not map the virtual address to the memory!\n", getpid());
    Exit();
  }
  Printf("\tspawn_rx2 (%d):Created an O2 molecule\n", getpid());
  // Now print a message to show that everything worked

  //Printf("\tspawn_rx2 (%d): Reaction is process, will take %d seconds\n", getpid(),10);
  //sleep(10);
  Printf("\tspawn_rx2 (%d): Done!\n\n", getpid());
  // Signal the semaphore to tell the original process that we're done
  if(sem_signal(s_procs_completed) != SYNC_SUCCESS) {
    Printf("\tspawn_rx2 (%d): Bad semaphore s_procs_completed (%d)!\n", getpid(), s_procs_completed);
    Exit();
  }


}
Exemplo n.º 24
0
char InitDma(void *FunctionTerminate)
{
    DMA_CHANNEL=4;
    if (system("rm -f linuxversion.txt") != 0) {
        fprintf(stderr, "rm failed\n");
    }
    if (system("uname -r >> linuxversion.txt") != 0) {
        fprintf(stderr, "uname failed\n");
    }
    char *line = NULL;
    size_t size;
//	int fLinux=open("Flinuxversion.txt", "r');
    FILE * flinux=fopen("linuxversion.txt", "r");
    if (getline(&line, &size, flinux) == -1)
    {
        printf("Could no get Linux version\n");
    }
    else
    {
        if(line[0]=='3')
        {
            printf("Wheezy\n");
            DMA_CHANNEL=DMA_CHANNEL_WHEEZY;
        }

        if(line[0]=='4')
        {
            printf("Jessie\n");
            DMA_CHANNEL=DMA_CHANNEL_JESSIE;
        }

    }
    //printf("Init DMA\n");

    // Catch all signals possible - it is vital we kill the DMA engine
    // on process exit!
    int i;
    for (i = 0; i < 64; i++) {
        struct sigaction sa;

        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = FunctionTerminate;//terminate;
        sigaction(i, &sa, NULL);
    }

    //NUM_SAMPLES = NUM_SAMPLES_MAX;

    /* Use the mailbox interface to the VC to ask for physical memory */
    /*
    unlink(MBFILE);
    if (mknod(MBFILE, S_IFCHR|0600, makedev(100, 0)) < 0)
    {
    	printf("Failed to create mailbox device\n");
    	return 0;
    }*/
    mbox.handle = mbox_open();
    if (mbox.handle < 0)
    {
        printf("Failed to open mailbox\n");
        return(0);
    }
    mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES* PAGE_SIZE, PAGE_SIZE, mem_flag);
    /* TODO: How do we know that succeeded? */
    //printf("mem_ref %x\n", mbox.mem_ref);
    mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref);
    //printf("bus_addr = %x\n", mbox.bus_addr);
    mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES* PAGE_SIZE);
    //printf("virt_addr %p\n", mbox.virt_addr);
    virtbase = (uint8_t *)((uint32_t *)mbox.virt_addr);
    //printf("virtbase %p\n", virtbase);
    return(1);

}
Exemplo n.º 25
0
int main(int argc, char *argv[]) {

	int mb = mbox_open();

	/* Enable QPU for execution */
	int qpu_enabled = !qpu_enable(mb, 1);
	if (!qpu_enabled) {
		printf("Unable to enable QPU.  Check your firmware is latest.");
		goto cleanup;
	}

	/* Allocate GPU memory and map it into ARM address space */
	unsigned size = 4096;
	unsigned align = 4096;
    	unsigned handle = mem_alloc(mb, size, align, GPU_MEM_FLG);
	if (!handle) {
		printf("Failed to allocate GPU memory.");
		goto cleanup;
	}
	void *gpu_pointer = (void *)mem_lock(mb, handle);
	void *arm_pointer = mapmem((unsigned)gpu_pointer+GPU_MEM_MAP, size);

	unsigned *p = (unsigned *)arm_pointer;

	/*
	   +---------------+ <----+
	   |  QPU Code     |      |
	   |  ...          |      |
	   +---------------+ <--+ |
	   |  Uniforms     |    | |
	   +---------------+    | |
	   |  QPU0 Uniform -----+ |
	   |  QPU0 Start   -------+
	   |  ...                 |
	   |  QPUn Uniform        |
	   |  QPUn PC      -------+
	   +---------------+
	*/

	/* Copy QPU program into GPU memory */
	unsigned *qpu_code = p;
	memcpy(p, program, sizeof program);
	p += (sizeof program)/(sizeof program[0]);

	/* Build Uniforms */
	unsigned *qpu_uniform = p;
	*p++ = 1;
	
	/* Build QPU Launch messages */
	unsigned *qpu_msg = p;
	*p++ = as_gpu_address(qpu_uniform);
	*p++ = as_gpu_address(qpu_code);

	int i;
	for (i=0; i<16+1+2; i++) {
		printf("%08x: %08x\n", gpu_pointer+i*4, ((unsigned *)arm_pointer)[i]);
	}
	printf("qpu exec %08x\n", gpu_pointer + ((void *)qpu_msg - arm_pointer));

	/* Launch QPU program and block till its done */
    	unsigned r = execute_qpu(mb, GPU_QPUS, as_gpu_address(qpu_msg), 1, 10000);
	printf("%d\n", r);

cleanup:
	/* Release GPU memory */
	if (arm_pointer) {
		unmapmem(arm_pointer, size);
	}
    	if (handle) {
		mem_unlock(mb, handle);
    		mem_free(mb, handle);
	}
	
	/* Release QPU */
	if (qpu_enabled) {
	    	qpu_enable(mb, 0);
	}
	
	/* Release mailbox */
	mbox_close(mb);

}
Exemplo n.º 26
0
/**
 * Allocate and initialize memory, buffers, pages, PWM, DMA, and GPIO.
 *
 * @param    ws2811  ws2811 instance pointer.
 *
 * @returns  0 on success, -1 otherwise.
 */
int ws2811_init(ws2811_t *ws2811)
{
    ws2811_device_t *device;
    const rpi_hw_t *rpi_hw;
    int chan;

    ws2811->rpi_hw = rpi_hw_detect();
    if (!ws2811->rpi_hw)
    {
        return -1;
    }
    rpi_hw = ws2811->rpi_hw;

    ws2811->device = malloc(sizeof(*ws2811->device));
    if (!ws2811->device)
    {
        return -1;
    }
    device = ws2811->device;

    // Determine how much physical memory we need for DMA
    device->mbox.size = PWM_BYTE_COUNT(max_channel_led_count(ws2811), ws2811->freq) +
                        sizeof(dma_cb_t);
    // Round up to page size multiple
    device->mbox.size = (device->mbox.size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);

    device->mbox.handle = mbox_open();
    if (device->mbox.handle == -1)
    {
        return -1;
    }

    device->mbox.mem_ref = mem_alloc(device->mbox.handle, device->mbox.size, PAGE_SIZE,
                                     rpi_hw->videocore_base == 0x40000000 ? 0xC : 0x4);
    if (device->mbox.mem_ref == 0)
    {
       return -1;
    }

    device->mbox.bus_addr = mem_lock(device->mbox.handle, device->mbox.mem_ref);
    if (device->mbox.bus_addr == (uint32_t) ~0UL)
    {
       mem_free(device->mbox.handle, device->mbox.size);
       return -1;
    }
    device->mbox.virt_addr = mapmem(BUS_TO_PHYS(device->mbox.bus_addr), device->mbox.size);

    // Initialize all pointers to NULL.  Any non-NULL pointers will be freed on cleanup.
    device->pwm_raw = NULL;
    device->dma_cb = NULL;
    for (chan = 0; chan < RPI_PWM_CHANNELS; chan++)
    {
        ws2811->channel[chan].leds = NULL;
    }

    // Allocate the LED buffers
    for (chan = 0; chan < RPI_PWM_CHANNELS; chan++)
    {
        ws2811_channel_t *channel = &ws2811->channel[chan];

        channel->leds = malloc(sizeof(ws2811_led_t) * channel->count);
        if (!channel->leds)
        {
            goto err;
        }

        memset(channel->leds, 0, sizeof(ws2811_led_t) * channel->count);

        if (!channel->strip_type)
        {
          channel->strip_type=WS2811_STRIP_RGB;
        }
    }

    device->dma_cb = (dma_cb_t *)device->mbox.virt_addr;
    device->pwm_raw = (uint8_t *)device->mbox.virt_addr + sizeof(dma_cb_t);

    pwm_raw_init(ws2811);

    memset((dma_cb_t *)device->dma_cb, 0, sizeof(dma_cb_t));

    // Cache the DMA control block bus address
    device->dma_cb_addr = addr_to_bus(device, device->dma_cb);

    // Map the physical registers into userspace
    if (map_registers(ws2811))
    {
        goto err;
    }

    // Initialize the GPIO pins
    if (gpio_init(ws2811))
    {
        unmap_registers(ws2811);
        goto err;
    }

    // Setup the PWM, clocks, and DMA
    if (setup_pwm(ws2811))
    {
        unmap_registers(ws2811);
        goto err;
    }

    return 0;

err:
    ws2811_cleanup(ws2811);

    return -1;
}
Exemplo n.º 27
0
void main (int argc, char *argv[])
{
  int numprocs;               // Used to store number of processes to create
  int i;                          // Loop index variable
  missile_code mc;                // Used as message for mailbox
  
  int num_N2;                     //numer of N2 injection
  int num_H2O;                    //number of H2O injection
  int num_N2_2N;                  //number of reaction1
  int num_H2O_H2_O2;              //number of reaction2
  int num_N_O2_NO2;               //number of reaction3
  int number_N2;                  //number of N2 molecules
  int number_H2O;                 //number of H2O molecules

  mbox_t mbox_N2;                  //N2 mailbox
  mbox_t mbox_N;                   //N mailbox
  mbox_t mbox_H2O;                 //H2O mailbox
  mbox_t mbox_H2;                  //H2 mailbox
  mbox_t mbox_O2;                  //O2 mailbox
  mbox_t mbox_NO2;                 //NO2 mailbox
  
  sem_t s_procs_completed;        // Semaphore used to wait until all spawned processes have completed
  char mbox_N2_str[10];            // Used as command-line argument to pass mem_handle to new processes
  char mbox_N_str[10];
  char mbox_H2O_str[10];
  char mbox_H2_str[10];
  char mbox_O2_str[10];
  char mbox_NO2_str[10];
  char s_procs_completed_str[10]; // Used as command-line argument to pass page_mapped handle to new processes

  if (argc != 3) {
    Printf("Usage: ");Printf(argv[0]);Printf("<number of N2 molecules> <number of H2O molecules\n");
    Exit();
  }
  
  // Convert string from ascii command line argument to integer number
  number_N2 = dstrtol(argv[1],NULL,10); //the "10" means base 10
  number_H2O = dstrtol(argv[2],NULL,10);
  
  if(number_H2O%2 ==1){
     num_H2O = number_H2O;
     num_H2O_H2_O2 = (number_H2O-1)/2;
     num_N2 = number_N2;
     num_N2_2N = number_N2;
     if (2*num_N2>num_H2O_H2_O2){    //number of N larger than number of O2
         num_N_O2_NO2 = num_H2O_H2_O2;
     }
     else{
         num_N_O2_NO2 = 2*num_N2;
     }
   }
  else{
     num_H2O = number_H2O;
     num_H2O_H2_O2 =(number_H2O)/2;
     num_N2 = number_N2;
     num_N2_2N = number_N2;
     if (2*num_N2>num_H2O_H2_O2){  //number of N larger than number of O2
        num_N_O2_NO2 = num_H2O_H2_O2;
     }
     else{
         num_N_O2_NO2 = 2*num_N2;
     }
   }
   
   numprocs=num_H2O+num_N2+num_H2O_H2_O2+num_N2_2N+num_N_O2_NO2;

  // Allocate space for a mailbox
  if ((mbox_N2 = mbox_create()) == MBOX_FAIL) {
    Printf("makeprocs (%d): ERROR: could not allocate mailbox!", getpid());
    Exit();
  }

  if ((mbox_N = mbox_create()) == MBOX_FAIL) {
    Printf("makeprocs (%d): ERROR: could not allocate mailbox!", getpid());
    Exit();
  }

  if ((mbox_O2 = mbox_create()) == MBOX_FAIL) {
    Printf("makeprocs (%d): ERROR: could not allocate mailbox!", getpid());
    Exit();
  }
  
  if ((mbox_NO2 = mbox_create()) == MBOX_FAIL) {
    Printf("makeprocs (%d): ERROR: could not allocate mailbox!", getpid());
    Exit();
  }

  if ((mbox_H2O = mbox_create()) == MBOX_FAIL) {
    Printf("makeprocs (%d): ERROR: could not allocate mailbox!", getpid());
    Exit();
  }

  if ((mbox_H2 = mbox_create()) == MBOX_FAIL) {
    Printf("makeprocs (%d): ERROR: could not allocate mailbox!", getpid());
    Exit();
  }

  // Open mailbox to prevent deallocation
  if (mbox_open(mbox_N2) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not open mailbox %d!\n", getpid(), mbox_N2);
    Exit();
  }

  if (mbox_open(mbox_N) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not open mailbox %d!\n", getpid(), mbox_N);
    Exit();
  }

  if (mbox_open(mbox_H2O) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not open mailbox %d!\n", getpid(), mbox_H2O);
    Exit();
  }

  if (mbox_open(mbox_H2) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not open mailbox %d!\n", getpid(), mbox_H2);
    Exit();
  }
  if (mbox_open(mbox_O2) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not open mailbox %d!\n", getpid(), mbox_O2);
    Exit();
  }
  if (mbox_open(mbox_NO2) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not open mailbox %d!\n", getpid(), mbox_NO2);
    Exit();
  }
  // Put some values in the mc structure to send as a message
  mc.numprocs = numprocs;
  mc.really_important_char = 'A';

  // Create semaphore to not exit this process until all other processes 
  // have signalled that they are complete.  To do this, we will initialize
  // the semaphore to (-1) * (number of signals), where "number of signals"
  // should be equal to the number of processes we're spawning - 1.  Once 
  // each of the processes has signaled, the semaphore should be back to
  // zero and the final sem_wait below will return.
  if ((s_procs_completed = sem_create(-(numprocs-1))) == SYNC_FAIL) {
    Printf("makeprocs (%d): Bad sem_create\n", getpid());
    Exit();
  }

  // Setup the command-line arguments for the new process.  We're going to
  // pass the handles to the shared memory page and the semaphore as strings
  // on the command line, so we must first convert them from ints to strings.
  ditoa(mbox_N2, mbox_N2_str);
  ditoa(mbox_H2O, mbox_H2O_str);
  ditoa(mbox_N, mbox_N_str);
  ditoa(mbox_H2, mbox_H2_str);
  ditoa(mbox_O2, mbox_O2_str);
  ditoa(mbox_NO2, mbox_NO2_str);
  ditoa(s_procs_completed, s_procs_completed_str);

  // Now we can create the processes.  Note that you MUST end your call to
  // process_create with a NULL argument so that the operating system
  // knows how many arguments you are sending.
  for(i=0; i<num_N2; i++) {
    process_create(FILENAME_TO_RUN_0, 0, 0, mbox_N2_str,s_procs_completed_str, NULL);
 //   Printf("makeprocs (%d): Process %d created\n", getpid(), i);
  }
  for(i=0; i<num_H2O; i++) {
    process_create(FILENAME_TO_RUN_1, 0, 0, mbox_H2O_str, s_procs_completed_str, NULL);
//    Printf("makeprocs (%d): Process %d created\n", getpid(), i);
  }
  for(i=0; i<num_N2_2N; i++) {
    process_create(FILENAME_TO_RUN_2, 0, 0, mbox_N2_str,mbox_N_str, s_procs_completed_str, NULL);
//    Printf("makeprocs (%d): Process %d created\n", getpid(), i);
  }
  for(i=0; i<num_H2O_H2_O2; i++) {
    process_create(FILENAME_TO_RUN_3, 0, 0, mbox_H2O_str,mbox_H2_str,mbox_O2_str, s_procs_completed_str, NULL);
//    Printf("makeprocs (%d): Process %d created\n", getpid(), i);
  }
  for(i=0; i<num_N_O2_NO2; i++) {
    process_create(FILENAME_TO_RUN_4, 0, 0, mbox_N_str,mbox_O2_str,mbox_NO2_str, s_procs_completed_str, NULL);
//    Printf("makeprocs (%d): Process %d created\n", getpid(), i);
  }

  // And finally, wait until all spawned processes have finished.
  if (sem_wait(s_procs_completed) != SYNC_SUCCESS) {
    Printf("Bad semaphore s_procs_completed (%d) in ", s_procs_completed); Printf(argv[0]); Printf("\n");
    Exit();
  }
  if (mbox_close(mbox_N2) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not close mailbox %d!\n", getpid(), mbox_N2);
    Exit();
  }
  if (mbox_close(mbox_N) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not close mailbox %d!\n", getpid(), mbox_N);
    Exit();
  }
  if (mbox_close(mbox_O2) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not close mailbox %d!\n", getpid(), mbox_O2);
    Exit();
  }
  if (mbox_close(mbox_NO2) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not close mailbox %d!\n", getpid(), mbox_NO2);
    Exit();
  }
  if (mbox_close(mbox_H2O) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not close mailbox %d!\n", getpid(), mbox_H2O);
    Exit();
  }
  if (mbox_close(mbox_H2) == MBOX_FAIL) {
    Printf("makeprocs (%d): Could not close mailbox %d!\n", getpid(), mbox_H2);
    Exit();
  }
  Printf("makeprocs (%d): All other processes completed, exiting main process.\n", getpid());
}
Exemplo n.º 28
0
int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, float ppm, char *control_pipe) {
    // Catch all signals possible - it is vital we kill the DMA engine
    // on process exit!
    for (int i = 0; i < 64; i++) {
        struct sigaction sa;

        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = terminate;
        sigaction(i, &sa, NULL);
    }
        
    dma_reg = map_peripheral(DMA_VIRT_BASE, DMA_LEN);
    pwm_reg = map_peripheral(PWM_VIRT_BASE, PWM_LEN);
    clk_reg = map_peripheral(CLK_VIRT_BASE, CLK_LEN);
    gpio_reg = map_peripheral(GPIO_VIRT_BASE, GPIO_LEN);

    // Use the mailbox interface to the VC to ask for physical memory.
    mbox.handle = mbox_open();
    if (mbox.handle < 0)
        fatal("Failed to open mailbox. Check kernel support for vcio / BCM2708 mailbox.\n");
    printf("Allocating physical memory: size = %d     ", NUM_PAGES * 4096);
    if(! (mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES * 4096, 4096, MEM_FLAG))) {
        fatal("Could not allocate memory.\n");
    }
    // TODO: How do we know that succeeded?
    printf("mem_ref = %u     ", mbox.mem_ref);
    if(! (mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref))) {
        fatal("Could not lock memory.\n");
    }
    printf("bus_addr = %x     ", mbox.bus_addr);
    if(! (mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES * 4096))) {
        fatal("Could not map memory.\n");
    }
    printf("virt_addr = %p\n", mbox.virt_addr);
    

    // GPIO4 needs to be ALT FUNC 0 to output the clock
    gpio_reg[GPFSEL0] = (gpio_reg[GPFSEL0] & ~(7 << 12)) | (4 << 12);

    // Program GPCLK to use MASH setting 1, so fractional dividers work
    clk_reg[GPCLK_CNTL] = 0x5A << 24 | 6;
    udelay(100);
    clk_reg[GPCLK_CNTL] = 0x5A << 24 | 1 << 9 | 1 << 4 | 6;

    ctl = (struct control_data_s *) mbox.virt_addr;
    dma_cb_t *cbp = ctl->cb;
    uint32_t phys_sample_dst = CM_GP0DIV;
    uint32_t phys_pwm_fifo_addr = PWM_PHYS_BASE + 0x18;


    // Calculate the frequency control word
    // The fractional part is stored in the lower 12 bits
    uint32_t freq_ctl = ((float)(PLLFREQ / carrier_freq)) * ( 1 << 12 );


    for (int i = 0; i < NUM_SAMPLES; i++) {
        ctl->sample[i] = 0x5a << 24 | freq_ctl;    // Silence
        // Write a frequency sample
        cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP;
        cbp->src = mem_virt_to_phys(ctl->sample + i);
        cbp->dst = phys_sample_dst;
        cbp->length = 4;
        cbp->stride = 0;
        cbp->next = mem_virt_to_phys(cbp + 1);
        cbp++;
        // Delay
        cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP | BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(5);
        cbp->src = mem_virt_to_phys(mbox.virt_addr);
        cbp->dst = phys_pwm_fifo_addr;
        cbp->length = 4;
        cbp->stride = 0;
        cbp->next = mem_virt_to_phys(cbp + 1);
        cbp++;
    }
    cbp--;
    cbp->next = mem_virt_to_phys(mbox.virt_addr);

    // Here we define the rate at which we want to update the GPCLK control 
    // register.
    //
    // Set the range to 2 bits. PLLD is at 500 MHz, therefore to get 228 kHz
    // we need a divisor of 500000 / 2 / 228 = 1096.491228
    //
    // This is 1096 + 2012*2^-12 theoretically
    //
    // However the fractional part may have to be adjusted to take the actual
    // frequency of your Pi's oscillator into account. For example on my Pi,
    // the fractional part should be 1916 instead of 2012 to get exactly 
    // 228 kHz. However RDS decoding is still okay even at 2012.
    //
    // So we use the 'ppm' parameter to compensate for the oscillator error

    float divider = (500000./(2*228*(1.+ppm/1.e6)));
    uint32_t idivider = (uint32_t) divider;
    uint32_t fdivider = (uint32_t) ((divider - idivider)*pow(2, 12));
    
    printf("ppm corr is %.4f, divider is %.4f (%d + %d*2^-12) [nominal 1096.4912].\n", 
                ppm, divider, idivider, fdivider);

    pwm_reg[PWM_CTL] = 0;
    udelay(10);
    clk_reg[PWMCLK_CNTL] = 0x5A000006;              // Source=PLLD and disable
    udelay(100);
    // theorically : 1096 + 2012*2^-12
    clk_reg[PWMCLK_DIV] = 0x5A000000 | (idivider<<12) | fdivider;
    udelay(100);
    clk_reg[PWMCLK_CNTL] = 0x5A000216;              // Source=PLLD and enable + MASH filter 1
    udelay(100);
    pwm_reg[PWM_RNG1] = 2;
    udelay(10);
    pwm_reg[PWM_DMAC] = PWMDMAC_ENAB | PWMDMAC_THRSHLD;
    udelay(10);
    pwm_reg[PWM_CTL] = PWMCTL_CLRF;
    udelay(10);
    pwm_reg[PWM_CTL] = PWMCTL_USEF1 | PWMCTL_PWEN1;
    udelay(10);
    

    // Initialise the DMA
    dma_reg[DMA_CS] = BCM2708_DMA_RESET;
    udelay(10);
    dma_reg[DMA_CS] = BCM2708_DMA_INT | BCM2708_DMA_END;
    dma_reg[DMA_CONBLK_AD] = mem_virt_to_phys(ctl->cb);
    dma_reg[DMA_DEBUG] = 7; // clear debug error flags
    dma_reg[DMA_CS] = 0x10880001;    // go, mid priority, wait for outstanding writes

    
    uint32_t last_cb = (uint32_t)ctl->cb;

    // Data structures for baseband data
    float data[DATA_SIZE];
    int data_len = 0;
    int data_index = 0;

    // Initialize the baseband generator
    if(fm_mpx_open(audio_file, DATA_SIZE) < 0) return 1;
    
    // Initialize the RDS modulator
    char myps[9] = {0};
    set_rds_pi(pi);
    set_rds_rt(rt);
    uint16_t count = 0;
    uint16_t count2 = 0;
    int varying_ps = 0;
    
    if(ps) {
        set_rds_ps(ps);
        printf("PI: %04X, PS: \"%s\".\n", pi, ps);
    } else {
        printf("PI: %04X, PS: <Varying>.\n", pi);
        varying_ps = 1;
    }
    printf("RT: \"%s\"\n", rt);
    
    // Initialize the control pipe reader
    if(control_pipe) {
        if(open_control_pipe(control_pipe) == 0) {
            printf("Reading control commands on %s.\n", control_pipe);
        } else {
            printf("Failed to open control pipe: %s.\n", control_pipe);
            control_pipe = NULL;
        }
    }
    
    
    printf("Starting to transmit on %3.1f MHz.\n", carrier_freq/1e6);

    for (;;) {
        // Default (varying) PS
        if(varying_ps) {
            if(count == 512) {
                snprintf(myps, 9, "%08d", count2);
                set_rds_ps(myps);
                count2++;
            }
            if(count == 1024) {
                set_rds_ps("RPi-Live");
                count = 0;
            }
            count++;
        }
        
        if(control_pipe && poll_control_pipe() == CONTROL_PIPE_PS_SET) {
            varying_ps = 0;
        }
        
        usleep(5000);

        uint32_t cur_cb = mem_phys_to_virt(dma_reg[DMA_CONBLK_AD]);
        int last_sample = (last_cb - (uint32_t)mbox.virt_addr) / (sizeof(dma_cb_t) * 2);
        int this_sample = (cur_cb - (uint32_t)mbox.virt_addr) / (sizeof(dma_cb_t) * 2);
        int free_slots = this_sample - last_sample;

        if (free_slots < 0)
            free_slots += NUM_SAMPLES;

        while (free_slots >= SUBSIZE) {
            // get more baseband samples if necessary
            if(data_len == 0) {
                if( fm_mpx_get_samples(data) < 0 ) {
                    terminate(0);
                }
                data_len = DATA_SIZE;
                data_index = 0;
            }
            
            float dval = data[data_index] * (DEVIATION / 10.);
            data_index++;
            data_len--;

            int intval = (int)((floor)(dval));
            //int frac = (int)((dval - (float)intval) * SUBSIZE);


            ctl->sample[last_sample++] = (0x5A << 24 | freq_ctl) + intval; //(frac > j ? intval + 1 : intval);
            if (last_sample == NUM_SAMPLES)
                last_sample = 0;

            free_slots -= SUBSIZE;
        }
        last_cb = (uint32_t)mbox.virt_addr + last_sample * sizeof(dma_cb_t) * 2;
    }

    return 0;
}