RocketLogger  1.0
pru.c
Go to the documentation of this file.
1 
5 #define _FILE_OFFSET_BITS 64
6 
7 #include "pru.h"
8 
9 // PRU TIMEOUT WRAPPER
10 
12 pthread_mutex_t waiting = PTHREAD_MUTEX_INITIALIZER;
13 
15 pthread_cond_t done = PTHREAD_COND_INITIALIZER;
16 
21 void *pru_wait_event(void* voidEvent) {
22 
23  unsigned int event = *((unsigned int *) voidEvent);
24 
25  // allow the thread to be killed at any time
26  int oldtype;
27  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
28 
29  // wait for pru event
30  prussdrv_pru_wait_event(event);
31 
32  // notify main program
33  pthread_cond_signal(&done);
34 
35  return NULL;
36 }
37 
44 int pru_wait_event_timeout(unsigned int event, unsigned int timeout) {
45 
46  struct timespec abs_time;
47  pthread_t tid;
48  int err;
49 
50  pthread_mutex_lock(&waiting);
51 
52  // pthread cond_timedwait expects an absolute time to wait until
53  clock_gettime(CLOCK_REALTIME, &abs_time);
54  abs_time.tv_sec += timeout;
55 
56  pthread_create(&tid, NULL, pru_wait_event, (void *) &event);
57 
58  err = pthread_cond_timedwait(&done, &waiting, &abs_time);
59 
60  if (!err) {
61  pthread_mutex_unlock(&waiting);
62  }
63 
64  return err;
65 }
66 
67 
68 
69 
70 
71 // PRU MEMORY MAPPING
75 void* map_pru_memory(void) {
76 
77  // get pru memory location and size
78  unsigned int pru_memory = read_file_value(MMAP_FILE "addr");
79  unsigned int size = read_file_value(MMAP_FILE "size");
80 
81  // memory map file
82  int fd;
83  if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){
84  rl_log(ERROR, "failed to open /dev/mem");
85  return NULL;
86  }
87 
88  // map shared memory into userspace
89  void* pru_mmap = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)pru_memory);
90 
91  if(pru_mmap == (void *) -1) {
92  rl_log(ERROR, "failed to map base address");
93  return NULL;
94  }
95 
96  close(fd);
97 
98  return pru_mmap;
99 }
100 
106 int unmap_pru_memory(void* pru_mmap) {
107 
108  // get pru memory size
109  unsigned int size = read_file_value(MMAP_FILE "size");
110 
111  if(munmap(pru_mmap, size) == -1) {
112  rl_log(ERROR, "failed to unmap memory");
113  return FAILURE;
114  }
115 
116  return SUCCESS;
117 
118 }
119 
120 
121 
122 
123 // PRU INITIALISATION
124 
130 
131  prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, (unsigned int*) &state, sizeof(int));
132 
133 }
134 
139 int pru_init(void) {
140 
141  // init PRU
142  tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
143  prussdrv_init ();
144  if (prussdrv_open(PRU_EVTOUT_0) == -1) {
145  rl_log(ERROR, "failed to open PRU");
146  return FAILURE;
147  }
148  prussdrv_pruintc_init(&pruss_intc_initdata);
149 
150  return SUCCESS;
151 }
152 
160 int pru_data_setup(struct pru_data_struct* pru, struct rl_conf* conf, uint32_t avg_factor) {
161 
162  uint32_t pru_sample_rate;
163 
164  // set state
165  if(conf->mode == LIMIT) {
166  pru->state = PRU_LIMIT;
167  } else {
168  pru->state = PRU_CONTINUOUS;
169  }
170 
171  // set sampling rate configuration
172  switch (conf->sample_rate) {
173  case 1:
174  pru_sample_rate = K1;
175  pru->precision = PRECISION_HIGH;
176  pru->sample_size = SIZE_HIGH;
177  break;
178  case 10:
179  pru_sample_rate = K1;
180  pru->precision = PRECISION_HIGH;
181  pru->sample_size = SIZE_HIGH;
182  break;
183  case 100:
184  pru_sample_rate = K1;
185  pru->precision = PRECISION_HIGH;
186  pru->sample_size = SIZE_HIGH;
187  break;
188  case 1000:
189  pru_sample_rate = K1;
190  pru->precision = PRECISION_HIGH;
191  pru->sample_size = SIZE_HIGH;
192  break;
193  case 2000:
194  pru_sample_rate = K2;
195  pru->precision = PRECISION_HIGH;
196  pru->sample_size = SIZE_HIGH;
197  break;
198  case 4000:
199  pru_sample_rate = K4;
200  pru->precision = PRECISION_HIGH;
201  pru->sample_size = SIZE_HIGH;
202  break;
203  case 8000:
204  pru_sample_rate = K8;
205  pru->precision = PRECISION_HIGH;
206  pru->sample_size = SIZE_HIGH;
207  break;
208  case 16000:
209  pru_sample_rate = K16;
210  pru->precision = PRECISION_HIGH;
211  pru->sample_size = SIZE_HIGH;
212  break;
213  case 32000:
214  pru_sample_rate = K32;
215  pru->precision = PRECISION_LOW;
216  pru->sample_size = SIZE_LOW;
217  break;
218  case 64000:
219  pru_sample_rate = K64;
220  pru->precision = PRECISION_LOW;
221  pru->sample_size = SIZE_LOW;
222  break;
223  default:
224  rl_log(ERROR, "wrong sample rate");
225  return FAILURE;
226  }
227 
228  // set buffer infos
229  pru->sample_limit = conf->sample_limit * avg_factor;
230  pru->buffer_size = (conf->sample_rate * avg_factor) / conf->update_rate;
231 
232  uint32_t buffer_size_bytes = pru->buffer_size * (pru->sample_size * NUM_CHANNELS + PRU_DIG_SIZE) + PRU_BUFFER_STATUS_SIZE;
234  pru->buffer1_location = pru->buffer0_location + buffer_size_bytes;
235 
236 
237  // set commands
239  pru->commands[0] = RESET;
240  pru->commands[1] = SDATAC;
241  pru->commands[2] = WREG|CONFIG3|CONFIG3DEFAULT; // write configuration
242  pru->commands[3] = WREG|CONFIG1|CONFIG1DEFAULT | pru_sample_rate;
243 
244  // set channel gains
245  pru->commands[4] = WREG|CH1SET|GAIN2; // High Range A
246  pru->commands[5] = WREG|CH2SET|GAIN2; // High Range B
247  pru->commands[6] = WREG|CH3SET|GAIN1; // Medium Range
248  pru->commands[7] = WREG|CH4SET|GAIN1; // Low Range A
249  pru->commands[8] = WREG|CH5SET|GAIN1; // Low Range B
250  pru->commands[9] = WREG|CH6SET|GAIN1; // Voltage 1
251  pru->commands[10] = WREG|CH7SET|GAIN1; // Voltage 2
252  pru->commands[11] = RDATAC; // continuous reading
253 
254  return SUCCESS;
255 }
256 
257 
258 
259 
266 int pru_sample(FILE* data, struct rl_conf* conf) {
267 
268  // average (for low rates)
269  uint32_t avg_factor = 1;
270  if(conf->sample_rate < MIN_ADC_RATE) {
271  avg_factor = MIN_ADC_RATE / conf->sample_rate;
272  }
273 
274 
275  // METER
276  if(conf->mode == METER) {
277  meter_init();
278  }
279 
280 
281  // WEBSERVER
282  int sem_id = -1;
283  struct web_shm* web_data = (struct web_shm*) -1;
284 
285  if (conf->enable_web_server == 1) {
286  // semaphores
287  sem_id = create_sem();
288  set_sem(sem_id, DATA_SEM, 1);
289 
290  // shared memory
291  web_data = create_web_shm();
292 
293  // determine web channels count (merged)
294  int num_web_channels = count_channels(conf->channels);
296  num_web_channels--;
297  }
299  num_web_channels--;
300  }
302  num_web_channels += NUM_DIGITAL_INPUTS;
303  }
304  web_data->num_channels = num_web_channels;
305 
306  // web buffer sizes
308 
309  int i;
310  for(i=0; i<WEB_RING_BUFFER_COUNT; i++) {
311  int web_buffer_element_size = buffer_sizes[i] * num_web_channels*sizeof(int64_t);
312  int web_buffer_length = NUM_WEB_POINTS / buffer_sizes[i];
313  reset_buffer(&web_data->buffer[i], web_buffer_element_size, web_buffer_length);
314  }
315  }
316 
317 
318 
319  // PRU SETUP
320 
321  // Map the PRU's interrupts
322  tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
323  prussdrv_pruintc_init(&pruss_intc_initdata);
324 
325 
326  // setup PRU
327  struct pru_data_struct pru;
328  pru_data_setup(&pru, conf, avg_factor);
329  unsigned int number_buffers = ceil_div(conf->sample_limit*avg_factor, pru.buffer_size);
330  unsigned int buffer_size_bytes = pru.buffer_size * (pru.sample_size * NUM_CHANNELS + PRU_DIG_SIZE) + PRU_BUFFER_STATUS_SIZE;
331 
332  // check memory size
333  unsigned int max_size = read_file_value(MMAP_FILE "size");
334  if(2*buffer_size_bytes > max_size) {
335  rl_log(ERROR, "not enough memory allocated. Run:\n rmmod uio_pruss\n modprobe uio_pruss extram_pool_sz=0x%06x", 2*buffer_size_bytes);
336  pru.state = PRU_OFF;
337  }
338 
339  // map PRU memory into userspace
340  void* buffer0 = map_pru_memory();
341  void* buffer1 = buffer0 + buffer_size_bytes;
342 
343 
344 
345  // FILE STORING
346 
347  // file header lead-in
348  struct rl_file_header file_header;
349  setup_lead_in(&(file_header.lead_in), conf);
350 
351  // channel array
352  int total_channel_count = file_header.lead_in.channel_bin_count + file_header.lead_in.channel_count;
353  struct rl_file_channel file_channel[total_channel_count];
354  file_header.channel = file_channel;
355 
356  // complete file header
357  setup_header(&file_header, conf);
358 
359  // store header
360  if(conf->file_format == BIN) {
361  store_header_bin(data, &file_header);
362  } else if (conf->file_format == CSV) {
363  store_header_csv(data, &file_header);
364  }
365 
366 
367 
368  // EXECUTION
369 
370  // write configuration to PRU memory
371  prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, (unsigned int*) &pru, sizeof(struct pru_data_struct));
372 
373  // run SPI on PRU0
374  if (prussdrv_exec_program (0, PRU_CODE) < 0) {
375  rl_log(ERROR, "PRU code not found");
376  pru.state = PRU_OFF;
377  }
378 
379  // wait for first PRU event
380  if(pru_wait_event_timeout(PRU_EVTOUT_0, PRU_TIMEOUT) == ETIMEDOUT) {
381  // timeout occured
382  rl_log(ERROR, "PRU not responding");
383  pru.state = PRU_OFF;
384  }
385 
386  // clear event
387  prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
388 
389  unsigned int i;
390  uint32_t buffer_lost = 0;
391  void* buffer_addr;
392  uint32_t samples_buffer; // number of samples per buffer
393  uint32_t num_files = 1; // number of files stored
394 
395  // sampling started
398 
399  // continuous sampling loop
400  for(i=0; status.sampling == SAMPLING_ON && status.state == RL_RUNNING && !(conf->mode == LIMIT && i>=number_buffers); i++) {
401 
402  if(conf->file_format != NO_FILE) {
403 
404  // check if max file size reached
405  uint64_t file_size = (uint64_t) ftello(data);
406  uint64_t margin = conf->sample_rate * sizeof(int32_t) * (NUM_CHANNELS+1) + sizeof(struct time_stamp);
407 
408  if(conf->max_file_size !=0 && file_size + margin > conf->max_file_size) {
409 
410  // close old data file
411  fclose(data);
412 
413  // determine new file name
414  char file_name[MAX_PATH_LENGTH];
415  char new_file_ending[MAX_PATH_LENGTH];
416  strcpy(file_name, conf->file_name);
417 
418  // search for last .
419  char target = '.';
420  char* file_ending = file_name;
421  while(strchr(file_ending, target) != NULL) {
422  file_ending = strchr(file_ending, target);
423  file_ending++; // Increment file_ending, otherwise we'll find target at the same location
424  }
425  file_ending--;
426 
427  // add file number
428  sprintf(new_file_ending, "_p%d", num_files++);
429  strcat(new_file_ending, file_ending);
430  strcpy(file_ending, new_file_ending);
431 
432  // open new data file
433  data = fopen(file_name, "w+");
434 
435  // update header for new file
436  file_header.lead_in.data_block_count = 0;
437  file_header.lead_in.sample_count = 0;
438 
439  // store header
440  if(conf->file_format == BIN) {
441  store_header_bin(data, &file_header);
442  } else if (conf->file_format == CSV) {
443  store_header_csv(data, &file_header);
444  }
445 
446  rl_log(INFO, "new datafile: %s", file_name);
447  }
448  }
449 
450  // select current buffer
451  if(i%2 == 0) {
452  buffer_addr = buffer0;
453  } else {
454  buffer_addr = buffer1;
455  }
456  // select buffer size
457  if(i < number_buffers-1 || pru.sample_limit % pru.buffer_size == 0) {
458  samples_buffer = pru.buffer_size; // full buffer size
459  } else {
460  samples_buffer = pru.sample_limit % pru.buffer_size; // unfull buffer size
461  }
462 
463  // Wait for event completion from PRU
464  // only check for timeout on first buffer (else it does not work!)
465  if (i == 0) {
466  if(pru_wait_event_timeout(PRU_EVTOUT_0, PRU_TIMEOUT) == ETIMEDOUT) {
467  // timeout occurred
468  rl_log(ERROR, "ADC not responding");
469  break;
470  }
471  } else {
472  prussdrv_pru_wait_event(PRU_EVTOUT_0);
473  }
474 
475  // clear event
476  prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
477 
478 
479  // check for overrun (compare buffer numbers)
480  uint32_t buffer = *((uint32_t*) buffer_addr);
481  if (buffer != i) {
482  buffer_lost += (buffer - i);
483  rl_log(WARNING, "overrun: %d samples (%d buffer) lost (%d in total)", (buffer - i) * pru.buffer_size, buffer - i, buffer_lost);
484  i = buffer;
485  }
486 
487  // handle the buffer
488  handle_data_buffer(data, buffer_addr+4, pru.sample_size, samples_buffer, conf, sem_id, web_data);
489 
490  // update and write header
491  if (conf->file_format != NO_FILE) {
492  // update the number of samples stored
493  file_header.lead_in.data_block_count += 1;
494  file_header.lead_in.sample_count += samples_buffer/avg_factor;
495 
496  if(conf->file_format == BIN) {
497  update_header_bin(data, &file_header);
498  } else if(conf->file_format == CSV) {
499  update_header_csv(data, &file_header);
500  }
501 
502  }
503 
504  // update and write state
505  status.samples_taken += samples_buffer/avg_factor;
506  status.buffer_number = i+1 - buffer_lost;
508 
509  // notify web clients
510  // Note: There is a possible race condition here, which might result in one web client not getting notified once, do we care?
511  if(conf->enable_web_server == 1) {
512  int num_web_clients = semctl(sem_id, WAIT_SEM, GETNCNT);
513  set_sem(sem_id, WAIT_SEM, num_web_clients);
514  }
515 
516  // print meter output
517  if(conf->mode == METER) {
518  meter_print_buffer(conf, buffer_addr+4, pru.sample_size);
519  }
520  }
521 
522 
523 
524  // FILE FINISH (flush)
525  if (conf->file_format != NO_FILE && status.state != RL_ERROR) {
526  // print info
527  rl_log(INFO, "stored %llu samples to file", status.samples_taken);
528 
529  printf("Stored %llu samples to file.\n", status.samples_taken);
530 
531  fflush(data);
532  }
533 
534 
535  // PRU FINISH (unmap memory)
536  unmap_pru_memory(buffer0);
537 
538 
539  // WEBSERVER FINISH
540  // unmap shared memory
541  if (conf->enable_web_server == 1) {
542  remove_sem(sem_id);
543  shmdt(web_data);
544  }
545 
546 
547  // METER FINISH
548  if(conf->mode == METER) {
549  meter_stop();
550  }
551 
552  // STATE
553  if(status.state == RL_ERROR) {
554  return FAILURE;
555  }
556 
557  return SUCCESS;
558 
559 }
560 
561 
562 
563 
567 void pru_stop(void) {
568 
569  // write OFF to PRU state (so PRU can clean up)
571 
572  // wait for interrupt (if no ERROR occured)
573  if(status.state != RL_ERROR) {
574  pru_wait_event_timeout(PRU_EVTOUT_0, PRU_TIMEOUT);
575  prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT); // clear event
576  }
577 }
578 
582 void pru_close(void) {
583 
584  // Disable PRU and close memory mappings
585  prussdrv_pru_disable(0);
586  prussdrv_exit();
587 }
int create_sem(void)
Definition: sem.c:11
int write_status(struct rl_status *status)
Definition: util.c:85
Limited sampling mode (limited by number of samples to take)
Definition: types.h:134
struct ringbuffer buffer[WEB_RING_BUFFER_COUNT]
Array of ring buffers for different time scales.
Definition: web.h:70
#define NUM_DIGITAL_INPUTS
Number of RocketLogger digital channels.
Definition: types.h:84
rl_mode mode
Sampling mode.
Definition: types.h:204
#define WREG
Definition: pru.h:59
int pru_data_setup(struct pru_data_struct *pru, struct rl_conf *conf, uint32_t avg_factor)
Definition: pru.c:160
void store_header_csv(FILE *data, struct rl_file_header *file_header)
#define PRECISION_LOW
Definition: pru.h:115
#define FAILURE
Definition: types.h:53
#define SUCCESS
Definition: types.h:50
struct rl_file_lead_in lead_in
File header lead in (constant size)
Definition: rl_file.h:151
void meter_print_buffer(struct rl_conf *conf, void *buffer_addr, uint32_t sample_size)
Definition: meter.c:40
#define SIZE_LOW
Definition: pru.h:121
CSV format.
Definition: types.h:151
rl_pru_state state
Current PRU state.
Definition: pru.h:143
struct rl_status status
Current status of RocketLogger.
Definition: rl_server.c:42
void update_header_bin(FILE *data, struct rl_file_header *file_header)
#define BUFFER1_SIZE
Size of 1s/div buffer.
Definition: web.h:31
#define RDATAC
Definition: pru.h:55
#define NUM_WEB_POINTS
Number of data points in web plot.
Definition: web.h:40
#define K64
Definition: pru.h:93
#define NUMBER_ADC_COMMANDS
Number of ADC commands.
Definition: pru.h:136
#define WAIT_SEM
Number of wait semaphore in set (blocks all server processes, until new data is available) ...
Definition: types.h:275
void rl_log(rl_log_type type, const char *format,...)
Definition: log.c:12
#define CONFIG1DEFAULT
Definition: pru.h:98
#define K32
Definition: pru.h:92
int read_file_value(char filename[])
Definition: util.c:156
void meter_init(void)
Definition: meter.c:17
#define PRU_TIMEOUT
PRU time out in seconds.
Definition: pru.h:124
#define BUFFER10_SIZE
Size of 10s/div buffer.
Definition: web.h:33
int set_sem(int sem_id, int sem_num, int val)
Definition: sem.c:85
#define K1
Definition: pru.h:87
uint32_t num_channels
Number of channels sampled.
Definition: web.h:68
int unmap_pru_memory(void *pru_mmap)
Definition: pru.c:106
enum pru_state rl_pru_state
int ceil_div(int n, int d)
Definition: util.c:116
Limited sampling mode.
Definition: pru.h:131
struct rl_file_channel * channel
Channels definitions (binary and normal)
Definition: rl_file.h:157
#define GAIN1
Definition: pru.h:80
int digital_inputs
En-/disable digital inputs.
Definition: types.h:216
#define MAX_PATH_LENGTH
Maximum path length in characters.
Definition: types.h:76
uint64_t sample_count
Total sample count.
Definition: rl_file.h:101
uint16_t channel_bin_count
Binary channel count.
Definition: rl_file.h:116
#define PRECISION_HIGH
Definition: pru.h:114
int enable_web_server
En-/disable plots on web interface.
Definition: types.h:218
#define PRU_CODE
PRU binary file location.
Definition: pru.h:107
#define CH4SET
Definition: pru.h:71
int sem_id
ID of semaphore set.
Definition: rl_server.c:24
Binary format.
Definition: types.h:152
void reset_buffer(struct ringbuffer *buffer, int element_size, int length)
Definition: web.c:55
#define DATA_SEM
Number of data semaphore in set (manages access to shared memory data)
Definition: types.h:273
int pru_sample(FILE *data, struct rl_conf *conf)
Definition: pru.c:266
rl_state state
State.
Definition: types.h:234
Continuous sampling mode.
Definition: pru.h:132
uint64_t samples_taken
Number of samples taken.
Definition: types.h:238
struct web_shm * create_web_shm(void)
Definition: web.c:11
#define I2L_INDEX
Definition: types.h:189
#define CONFIG1
Definition: pru.h:65
state
Definition: types.h:116
int remove_sem(int sem_id)
Definition: sem.c:24
struct web_shm * web_data
Pointer to shared memory data.
Definition: rl_server.c:26
uint32_t buffer_size
Shared buffer size.
Definition: pru.h:153
int sample_limit
Sample limit (0 for continuous)
Definition: types.h:210
Definition: types.h:202
#define NUM_CHANNELS
Maximum number of RocketLogger channels.
Definition: types.h:78
#define CHANNEL_ENABLED
Channel sampling enabled.
Definition: types.h:178
Warning.
Definition: types.h:168
#define CH2SET
Definition: pru.h:69
#define CONFIG3
Definition: pru.h:67
uint32_t number_commands
Number of ADC commands to send.
Definition: pru.h:157
#define BUFFER100_SIZE
Size of 100s/div buffer.
Definition: web.h:35
#define I1H_INDEX
Definition: types.h:184
char file_name[MAX_PATH_LENGTH]
Data file name.
Definition: types.h:226
#define PRU_DIG_SIZE
Size of PRU digital information in bytes.
Definition: types.h:88
#define CONFIG3DEFAULT
Definition: pru.h:100
uint32_t sample_limit
Samples to take (0 for continuous)
Definition: pru.h:155
#define CH3SET
Definition: pru.h:70
Running.
Definition: types.h:118
int channels[NUM_CHANNELS]
Channels to sample.
Definition: types.h:212
#define K2
Definition: pru.h:88
#define K8
Definition: pru.h:90
uint16_t channel_count
Analog channel count.
Definition: rl_file.h:119
#define CH5SET
Definition: pru.h:72
void store_header_bin(FILE *data, struct rl_file_header *file_header)
#define PRU_BUFFER_STATUS_SIZE
Size of PRU buffer status in bytes.
Definition: types.h:90
rl_file_format file_format
File format.
Definition: types.h:222
uint32_t buffer_number
Number of buffers taken.
Definition: types.h:240
void * map_pru_memory(void)
Definition: pru.c:75
#define WEB_RING_BUFFER_COUNT
Number of ring buffers in shared memory.
Definition: web.h:13
uint32_t sample_size
Sample size in shared memory.
Definition: pru.h:147
int update_rate
Data update rate.
Definition: types.h:208
void pru_stop(void)
Definition: pru.c:567
void pru_close(void)
Definition: pru.c:582
#define RESET
Definition: pru.h:51
#define SIZE_HIGH
Definition: pru.h:120
uint32_t precision
ADC precision (in bit)
Definition: pru.h:145
Definition: web.h:64
Error.
Definition: types.h:167
void meter_stop(void)
Definition: meter.c:30
#define SDATAC
Definition: pru.h:56
void update_header_csv(FILE *data, struct rl_file_header *file_header)
int sample_rate
Sampling rate.
Definition: types.h:206
#define GAIN2
Definition: pru.h:81
No file.
Definition: types.h:150
void * pru_wait_event(void *voidEvent)
Definition: pru.c:21
#define I2H_INDEX
Definition: types.h:188
int pru_init(void)
Definition: pru.c:139
pthread_cond_t done
Notification variable.
Definition: pru.c:15
int buffer_sizes[WEB_RING_BUFFER_COUNT]
Buffer sizes for different time scales.
Definition: rl_server.c:45
uint32_t buffer0_location
Pointer to shared buffer 0.
Definition: pru.h:149
uint64_t max_file_size
Maximum data file size.
Definition: types.h:224
Sampling.
Definition: types.h:127
rl_sampling sampling
Sampling state.
Definition: types.h:236
int count_channels(int channels[NUM_CHANNELS])
Definition: util.c:39
uint32_t buffer1_location
Pointer to shared buffer 1.
Definition: pru.h:151
Information.
Definition: types.h:169
#define MIN_ADC_RATE
Minimal ADC sampling rate.
Definition: types.h:108
#define K4
Definition: pru.h:89
uint32_t commands[NUMBER_ADC_COMMANDS]
ADC commands to send.
Definition: pru.h:159
int pru_wait_event_timeout(unsigned int event, unsigned int timeout)
Definition: pru.c:44
#define I1L_INDEX
Definition: types.h:185
PRU off.
Definition: pru.h:130
uint32_t data_block_count
Number of data blocks stored in the file.
Definition: rl_file.h:98
#define CH6SET
Definition: pru.h:73
void handle_data_buffer(FILE *data, void *buffer_addr, uint32_t sample_size, uint32_t samples_buffer, struct rl_conf *conf, int sem_id, struct web_shm *web_data_ptr)
Meter mode (display current values in terminal)
Definition: types.h:136
#define MMAP_FILE
Memory map file.
Definition: pru.h:105
Error.
Definition: types.h:119
#define CH1SET
Definition: pru.h:68
void pru_set_state(rl_pru_state state)
Definition: pru.c:129
pthread_mutex_t waiting
PRU access mutex.
Definition: pru.c:12
void setup_lead_in(struct rl_file_lead_in *lead_in, struct rl_conf *conf)
Definition: file_handling.c:67
#define DIGITAL_INPUTS_ENABLED
Digital input sampling ensabled.
Definition: types.h:197
void setup_header(struct rl_file_header *file_header, struct rl_conf *conf)
#define K16
Definition: pru.h:91
#define CH7SET
Definition: pru.h:74