KISS Data Aquisition and Control System
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

966 lines
32 KiB

  1. // Copyright Doug Lewis Sept 2017
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <prussdrv.h>
  5. #include <pruss_intc_mapping.h>
  6. #include <stdint.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <errno.h>
  10. #include <signal.h>
  11. #include <fcntl.h>
  12. #include <ctype.h>
  13. #include <termios.h>
  14. #include <sys/types.h>
  15. #include <sys/mman.h>
  16. #include <sys/socket.h>
  17. #include <netinet/in.h>
  18. #include <netdb.h>
  19. #include <arpa/inet.h>
  20. #include </home/erps/daq2/pruSrc/pruadc.h>
  21. unsigned int adc_pru_data0[ADC_PRU_DATA_SIZE];
  22. unsigned int adc_pru_data1[ADC_PRU_DATA_SIZE];
  23. typedef struct adc_conf_t {
  24. unsigned int cycles_per_clock;
  25. unsigned int down_sample;
  26. unsigned int control_string;
  27. unsigned int num_blocks; // File size in number of 128k blocks to record
  28. unsigned int block_size;
  29. unsigned int mode;
  30. unsigned int addr;
  31. unsigned int size;
  32. } adc_conf;
  33. unsigned int readFileValue(char filename[]){
  34. FILE* fp;
  35. unsigned int value = 0;
  36. fp = fopen(filename, "rt");
  37. fscanf(fp, "%x", &value);
  38. fclose(fp);
  39. return value;
  40. }
  41. unsigned int adc_conf_set_address(adc_conf *conf) {
  42. //conf->addr = ADC_PRU_DATA_SIZE + readFileValue(MMAP1_LOC "addr");
  43. conf->addr = readFileValue(MMAP1_LOC "addr");
  44. }
  45. unsigned int adc_conf_get_address(adc_conf *conf) {
  46. return (conf->addr);
  47. }
  48. unsigned int adc_conf_set_size(adc_conf *conf) {
  49. conf->size = readFileValue(MMAP1_LOC "size");
  50. }
  51. unsigned int adc_conf_get_size(adc_conf *conf) {
  52. return(conf->size);
  53. }
  54. int adc_conf_set_cycles_per_clock (adc_conf *conf, unsigned int cycles) {
  55. conf->cycles_per_clock = cycles;
  56. }
  57. unsigned int adc_conf_get_cycles_per_clock (adc_conf *conf) {
  58. return (conf->cycles_per_clock) ;
  59. }
  60. int adc_conf_set_mode(adc_conf *conf, unsigned int mode){
  61. conf->mode = mode;
  62. }
  63. int adc_conf_set_block_size(adc_conf *conf, unsigned int block_size){
  64. conf->block_size = block_size;
  65. }
  66. unsigned int adc_conf_get_mode (adc_conf *conf) {
  67. return (conf->mode) ;
  68. }
  69. int adc_conf_set_down_sample(adc_conf *conf, unsigned int down_sample){
  70. conf->down_sample = down_sample;
  71. }
  72. unsigned int adc_conf_get_down_sample(adc_conf *conf){
  73. return (conf->down_sample);
  74. }
  75. int adc_conf_set_control_string(adc_conf *conf, unsigned int control_string){
  76. conf->control_string = control_string;
  77. }
  78. unsigned int adc_conf_get_control_string(adc_conf *conf){
  79. return (conf->control_string);
  80. }
  81. int adc_conf_set_data_file_size(adc_conf *conf, unsigned int data_file_size){
  82. conf->num_blocks = data_file_size;
  83. }
  84. unsigned int adc_conf_get_data_file_size(adc_conf *conf){
  85. return (conf->num_blocks);
  86. }
  87. int default_daq_init(adc_conf *conf) {
  88. adc_conf_set_cycles_per_clock(conf, ADS_CLOCKS);
  89. adc_conf_set_mode(conf, STOP);
  90. adc_conf_set_down_sample(conf, ADS_SAMPLE_DIVISOR);
  91. adc_conf_set_control_string(conf, ADS_CONTROL_STRING);
  92. adc_conf_set_block_size(conf, BUFSIZE); // Default block size is 128k
  93. adc_conf_set_data_file_size(conf, DAQ_FILE_SIZE);
  94. adc_conf_set_address(conf);
  95. adc_conf_set_size(conf);
  96. }
  97. int adc_conf_settings(adc_conf *conf) {
  98. return (OK);
  99. }
  100. int main(int argc, char **argv)
  101. {
  102. char in_char = '0';
  103. struct adc_conf *conf;
  104. unsigned int *sample;
  105. void *addr;
  106. int read_fd;
  107. int client_sock_fd = 0;
  108. int i = 0;
  109. conf = malloc(sizeof (adc_conf));
  110. sample = malloc(sizeof(unsigned int) * 8);
  111. if(getuid()!=0){
  112. printf("You must run this program as root. Exiting.\n");
  113. exit(EXIT_FAILURE);
  114. }
  115. // Initialize structure used by prussdrv_pruintc_intc
  116. // PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h
  117. tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
  118. // Read in the location and address of PRU shared memory. This value changes
  119. // each time a new block of memory is allocated.
  120. default_daq_init((adc_conf *) conf);
  121. // data for setting up the ADC on PRU0.
  122. adc_pru_data0[0] = adc_conf_get_cycles_per_clock ((adc_conf *)conf);
  123. adc_pru_data0[1] = adc_conf_get_mode ((adc_conf *)conf);
  124. adc_pru_data0[2] = adc_conf_get_control_string ((adc_conf *)conf);
  125. adc_pru_data0[3] = CHANGE; // First time through, set to reflect changed.
  126. adc_pru_data0[4] = adc_conf_get_address((adc_conf *)conf);
  127. adc_pru_data0[5] = adc_conf_get_size((adc_conf *)conf);
  128. adc_pru_data0[6] = adc_conf_get_down_sample ((adc_conf *)conf);
  129. adc_pru_data0[7] = adc_conf_get_data_file_size ((adc_conf *)conf);
  130. // data for setting up the ADC on PRU1.
  131. adc_pru_data1[0] = adc_conf_get_cycles_per_clock ((adc_conf *)conf);
  132. adc_pru_data1[1] = adc_conf_get_mode ((adc_conf *)conf);
  133. adc_pru_data1[2] = adc_conf_get_control_string ((adc_conf *)conf);
  134. adc_pru_data1[3] = CHANGE; // First time through, set to reflect changed.
  135. adc_pru_data1[4] = adc_conf_get_address((adc_conf *)conf);
  136. adc_pru_data1[5] = adc_conf_get_size((adc_conf *)conf);
  137. adc_pru_data1[6] = adc_conf_get_down_sample ((adc_conf *)conf);
  138. adc_pru_data1[7] = adc_conf_get_data_file_size ((adc_conf *)conf);
  139. for (i = 8; i < 32; i ++)
  140. adc_pru_data1[i] = 0;
  141. printf("PRU1 Clock Counter %d \n", adc_pru_data1[0]);
  142. printf("PRU1 ADC State %d \n", adc_pru_data1[1]);
  143. printf("ADC1 Control String %x \n", adc_pru_data1[2]);
  144. printf("ADC1 Control String Modified %d \n", adc_pru_data1[3]);
  145. printf("PRU Shared Memory Address Pool: 0x%x\n", adc_pru_data1[4]);
  146. printf("PRU Shared Memory Pool Size: 0x%x\n", adc_pru_data1[5]);
  147. printf("Sample Divisor: 0x%x\n", adc_pru_data1[6]);
  148. printf("Number of 128k blocks to record 0x%x\n", adc_pru_data1[7]);
  149. // Allocate and initialize memory
  150. prussdrv_init ();
  151. prussdrv_open (PRU_EVTOUT_0);
  152. // Write the address and size into PRU0 Data RAM0.
  153. prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, 32);
  154. // Map PRU's interrupts
  155. prussdrv_pruintc_init(&pruss_intc_initdata);
  156. // Load and execute the PRU program on the PRU
  157. prussdrv_exec_program (PRU1_ADC_CONTROL_PRU, "./pruadc1.bin");
  158. printf("ADC Control PRU1 program running on PRU %x \n", PRU1_ADC_CONTROL_PRU);
  159. //prussdrv_exec_program (PRU0_ADC_CONTROL_PRU, "./pruadc0.bin");
  160. //printf("ADC Control PRU0 program running on PRU %x \n", PRU0_ADC_CONTROL_PRU);
  161. if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){
  162. printf("Failed to open memory!");
  163. return (ERR);
  164. }
  165. while (in_char != 'q') {
  166. printf("Enter Command : \n");
  167. scanf( " %c", &in_char);
  168. switch (in_char) {
  169. // Write the file to a binary file. It cannot be opened to look at
  170. // and will require postprocessing.
  171. case 'b' :
  172. printf("Binary data collection to file \n");
  173. printf("Data collection started \n");
  174. adc_pru_data0[1] = RUN;
  175. adc_pru_data0[3] = CHANGE;
  176. prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE);
  177. // prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, adc_pru_data0, ADC_PRU_DATA_SIZE);
  178. data_to_bin_file (conf, client_sock_fd);
  179. break;
  180. case 'c' :
  181. generate_cal_data( );
  182. break;
  183. case 'e':
  184. client_sock_fd = create_bind_accept_sock();
  185. if (client_sock_fd != ERR)
  186. printf("Socket Successfully created \n");
  187. printf("Entering client control mode \n");
  188. client_main(conf, client_sock_fd, adc_pru_data0, adc_pru_data1);
  189. break;
  190. // Write the file in a formatted hex value, with space separation
  191. // between each of the channels in a sample so that the file is
  192. // human readable for quick looks.
  193. case 'f' :
  194. printf("Formatted data collection \n");
  195. printf("Data collection started \n");
  196. adc_pru_data1[1] = RUN;
  197. adc_pru_data1[3] = CHANGE;
  198. prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE);
  199. //prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, adc_pru_data0, ADC_PRU_DATA_SIZE);
  200. write_file_formatted ((adc_conf *)conf, 1);
  201. //write_file_formatted ((adc_conf *)conf, 0);
  202. break;
  203. case 'h' :
  204. printf("Data collection halted \n");
  205. adc_pru_data1[1] = STOP;
  206. adc_pru_data1[3] = CHANGE;
  207. prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE);
  208. prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, adc_pru_data0, ADC_PRU_DATA_SIZE);
  209. break;
  210. // Get a single sample, print it to the screen
  211. case 'o':
  212. printf("getting a single sample \n");
  213. adc_pru_data1[1] = RUN;
  214. adc_pru_data1[3] = CHANGE;
  215. adc_conf_set_block_size((adc_conf *)conf, 32);
  216. prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE);
  217. sampleGet((adc_conf *)conf, 1, sample);
  218. break;
  219. // Write the file as binary. Indicate to PRU1 that this is a throughput test.
  220. // The data from PRU1 will contain a 24 bit counter which is incremented for
  221. // each sample.`
  222. case 't' :
  223. printf("Throughput Test Mode, Binary data collection to file \n");
  224. printf("Data generation started \n");
  225. adc_pru_data1[1] = TEST;
  226. adc_pru_data1[3] = CHANGE;
  227. addr = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, adc_pru_data1[4] & ~MAP_MASK);
  228. bzero((void *) addr, (size_t) (PRU1_START_OFFSET + BUF_HDR_SIZE));
  229. prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE);
  230. data_to_bin_file ((adc_conf *)conf, client_sock_fd);
  231. break;
  232. case 's' :
  233. printf("Start PRU Data collection, and return \n");
  234. adc_pru_data1[1] = TEST;
  235. adc_pru_data1[3] = CHANGE;
  236. prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE);
  237. break;
  238. case 'p' :
  239. get_buff_stats((adc_conf *)conf);
  240. break;
  241. default :
  242. printf("Command not recognized %c \n", in_char);
  243. }
  244. }
  245. prussdrv_exit ();
  246. }
  247. int client_main(adc_conf *conf, int clientSockFd)
  248. {
  249. char sendMessage[256] = {'\0'};
  250. char recvMessage[256];
  251. char exit[256];
  252. char timeString[32];
  253. int readSize = 0;
  254. char recStartMessage[256];
  255. size_t length = 0;
  256. strcpy(exit, "exit");
  257. while (strncmp(exit, recvMessage, 4) != 0)
  258. {
  259. readSize = recv(clientSockFd, recvMessage, sizeof(recvMessage) , 0);
  260. printf("Received message: %s from client \n", recvMessage);
  261. if (strncmp("record", recvMessage, 6) == 0)
  262. {
  263. strncpy (sendMessage, "recstart,2000 \0 ", 13);
  264. length = strlen(sendMessage);
  265. send(clientSockFd, sendMessage, length, 0);
  266. strncpy(timeString, &recvMessage[6], 14);
  267. recording_start(conf,
  268. clientSockFd,
  269. timeString);
  270. strncpy (sendMessage, "recdone ", 16);
  271. length = strlen(sendMessage);
  272. send(clientSockFd, sendMessage, length, 0);
  273. }
  274. }
  275. close(clientSockFd);
  276. }
  277. int recording_start( adc_conf *conf,
  278. int client_sock_fd,
  279. char timeString[])
  280. {
  281. char fileString[128] = "/home/erps/data/dataFile";
  282. printf("Binary data collection to file \n");
  283. printf("Data collection started \n");
  284. //adc_pru_data1[1] = TEST;
  285. adc_pru_data1[1] = RUN;
  286. adc_pru_data1[3] = CHANGE;
  287. prussdrv_pru_write_memory(PRUSS0_PRU1_DATARAM, 0, adc_pru_data1, ADC_PRU_DATA_SIZE);
  288. // prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, adc_pru_data0, ADC_PRU_DATA_SIZE);
  289. strncat(fileString, timeString, 14);
  290. strncat(fileString, ".bin\0", 6);
  291. printf("Recording File = %s \n", fileString);
  292. data_to_bin_file (conf, client_sock_fd, fileString);
  293. }
  294. // Write data to a file so that the hex info can be looked at raw.
  295. // Formatting makes it easy to look at hex values of each channel per sample.
  296. // Also, this operation takes a relatively small set of samples, as opposed to
  297. // a longer duration continuous recording.
  298. int write_file_formatted (adc_conf *conf, int pru_num)
  299. {
  300. int read_fd;
  301. FILE *write_fd;
  302. void *map_base, *virt_addr;
  303. unsigned long read_result;
  304. int result;
  305. unsigned int addr = conf->addr;
  306. unsigned int size = conf->size;
  307. if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){
  308. printf("Failed to open memory!");
  309. return (ERR);
  310. }
  311. printf("Memory file open successfully \n");
  312. if (pru_num == 1) {
  313. if((write_fd = fopen("/home/erps/data/outfile1.dat", "w")) == NULL){
  314. printf("Failed to open data file \n");
  315. return (ERR);
  316. addr += PRU1_START_OFFSET;
  317. printf("waiting on interrupt \n");
  318. prussdrv_pru_wait_event (PRU_EVTOUT_0);
  319. }
  320. } else if (pru_num == 0) {
  321. if((write_fd = fopen("/home/erps/data/outfile0.dat", "w")) == NULL){
  322. printf("Failed to open data file \n");
  323. return (ERR);
  324. addr += PRU0_START_OFFSET;
  325. }
  326. } else {
  327. printf("Invalid PRU %d \n", pru_num);
  328. return(ERR);
  329. }
  330. printf("Data file open successfully \n");
  331. map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, addr & ~MAP_MASK);
  332. if(map_base == (void *) -1) {
  333. printf("Failed to map base address");
  334. return (ERR);
  335. }
  336. printf("Reading data \n");
  337. int i = 0;
  338. int j = 0;
  339. for(i = 0; i < size; i+= (8 * BYTES_PER_SAMPLE)){
  340. for (j = 0; j < 8; j++) {
  341. virt_addr = map_base + (addr & MAP_MASK);
  342. read_result = *((uint32_t *) virt_addr);
  343. fprintf( write_fd, "0x%08x ", read_result);
  344. addr += BYTES_PER_SAMPLE;
  345. }
  346. fprintf(write_fd, "\n");
  347. }
  348. if ((result = fclose (write_fd)) != 0) {
  349. printf("Error closing data file %d \n", result);
  350. }
  351. return (OK);
  352. }
  353. int sampleGet (adc_conf *conf, int pru_num, uint32_t *sample)
  354. {
  355. int read_fd;
  356. FILE *write_fd;
  357. void *map_base, *virt_addr;
  358. unsigned long read_result;
  359. int result;
  360. unsigned int addr = conf->addr;
  361. if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){
  362. printf("Failed to open memory!");
  363. return (ERR);
  364. }
  365. printf("Memory file open successfully \n");
  366. map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, conf->addr & ~MAP_MASK);
  367. if(map_base == (void *) -1) {
  368. printf("Failed to map base address");
  369. return (ERR);
  370. }
  371. printf("Reading data \n");
  372. int i = 0;
  373. int j = 0;
  374. for(i = 0; i < conf->size; i+= (8 * BYTES_PER_SAMPLE)){
  375. for (j = 0; j < 8; j++) {
  376. virt_addr = map_base + (addr & MAP_MASK);
  377. //read_result = *((uint32_t *) virt_addr);
  378. *sample = *((uint32_t *) virt_addr);
  379. sample ++;
  380. printf( "0x%08x ", sample);
  381. addr += BYTES_PER_SAMPLE;
  382. }
  383. fprintf(write_fd, "\n");
  384. }
  385. return (OK);
  386. }
  387. int get_buff_stats(adc_conf *conf)
  388. {
  389. int i, buffs, buff_head_ptr;
  390. int read_fd;
  391. void *map_base, *virt_addr;
  392. unsigned long read_result;
  393. unsigned int addr = conf->addr;
  394. unsigned int pru1_wr_flag = addr;
  395. unsigned int pru1_buff_count = addr + 4;
  396. unsigned int pru1_head = addr + 8;
  397. unsigned int pru1_wrap_count = addr +12;
  398. unsigned int pru0_wr_flag = addr + 0x80;
  399. unsigned int pru0_buff_count = addr + 0x84;
  400. unsigned int pru0_head = addr + 0x88;
  401. unsigned int pru0_wrap_count = addr + 0x92;
  402. if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){
  403. printf("Failed to open memory!");
  404. return (ERR);
  405. }
  406. printf("Memory file open successfully \n");
  407. map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, addr & ~MAP_MASK);
  408. if(map_base == (void *) -1) {
  409. printf("Failed to map base address");
  410. return (ERR);
  411. }
  412. virt_addr = map_base + (pru1_wr_flag & MAP_MASK);
  413. read_result = *((uint32_t *) virt_addr);
  414. printf ("PRU1_WR_FLAG = %x ", read_result);
  415. virt_addr = map_base + (pru1_buff_count & MAP_MASK);
  416. read_result = *((uint32_t *) virt_addr);
  417. printf ("PRU1_BUFF_COUNT = %x ", read_result);
  418. addr += 4;
  419. virt_addr = map_base + (pru1_head & MAP_MASK);
  420. read_result = *((uint32_t *) virt_addr);
  421. printf ("PRU1_HEAD = %x ", read_result);
  422. virt_addr = map_base + (pru1_wrap_count & MAP_MASK);
  423. read_result = *((uint32_t *) virt_addr);
  424. printf ("PRU1_WRAP_COUNT = %x \n", read_result);
  425. virt_addr = map_base + (addr & MAP_MASK);
  426. read_result = *((uint32_t *) virt_addr);
  427. printf ("PRU0_WR_FLAG = %x ", read_result);
  428. virt_addr = map_base + (addr & MAP_MASK);
  429. read_result = *((uint32_t *) virt_addr);
  430. printf ("PRU0_BUFF_COUNT = %x ", read_result);
  431. virt_addr = map_base + (addr & MAP_MASK);
  432. read_result = *((uint32_t *) virt_addr);
  433. printf ("PRU0_HEAD = %x ", read_result);
  434. virt_addr = map_base + (addr & MAP_MASK);
  435. read_result = *((uint32_t *) virt_addr);
  436. printf ("PRU0_WRAP_COUNT = %x \n\n", read_result);
  437. return (OK);
  438. }
  439. int tail_increment(int tail, int num)
  440. {
  441. tail += num;
  442. if (tail == QUEUE_SIZE)
  443. tail = 0;
  444. return (tail);
  445. }
  446. int create_bind_accept_sock()
  447. {
  448. #define PORT 8888
  449. struct sockaddr_in server, client;
  450. int addr_len = sizeof(server);
  451. int sock_descriptor, client_sock;
  452. int backlog = 5;
  453. sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
  454. if(sock_descriptor == ERR)
  455. {
  456. printf("Error opening socket\n");
  457. return -1;
  458. }
  459. printf("Socket Created \n");
  460. server.sin_port = htons(PORT);
  461. server.sin_addr.s_addr = INADDR_ANY;
  462. server.sin_family = AF_INET;
  463. if (bind(sock_descriptor, (struct sockaddr *)&server, sizeof(struct sockaddr_in) ) == -1)
  464. {
  465. printf("Error binding socket\n");
  466. return (ERR);
  467. }
  468. printf("Socket Successfully bound to port %u\n", PORT);
  469. listen(sock_descriptor, backlog);
  470. addr_len = sizeof(server);
  471. client_sock = accept(sock_descriptor, (struct sockaddr *) &client, (socklen_t*) &addr_len);
  472. if (client_sock < 0)
  473. {
  474. error("ERROR on accept");
  475. }
  476. else
  477. {
  478. printf("Client socket connection accepted \n");
  479. }
  480. return(client_sock);
  481. }
  482. int send_buffs_to_host (void *virt_addr, int num_buffs_to_write, int sock_fd) {
  483. int32_t bytesToSend = num_buffs_to_write * BUFSIZE;
  484. int32_t sent = 0;
  485. uint8_t *addr = virt_addr;
  486. struct timeval timeout;
  487. timeout.tv_sec = 2;
  488. timeout.tv_usec = 0;
  489. while (bytesToSend > 0 || (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) > 0))
  490. //while (bytesToSend > 0)
  491. {
  492. if ((sent = send(sock_fd, (uint8_t*)addr, bytesToSend, 0)) < 0)
  493. {
  494. printf("ERROR: Failed to send buffer contents across TCPIP.\n");
  495. system("ifconfig eth0 192.168.8.2");
  496. return(ERR);
  497. }
  498. bytesToSend -= sent;
  499. addr += sent;
  500. }
  501. }
  502. process_buffers(void *virt_addr, int num_buffs_to_write, int sock_fd, FILE *write_fd, int8_t flash_record, int8_t network_send)
  503. {
  504. uint32_t wr_num;
  505. if (flash_record == ENABLED)
  506. wr_num = write_buffs_to_flash (virt_addr, num_buffs_to_write, write_fd);
  507. if (network_send == ENABLED)
  508. send_buffs_to_host (virt_addr, num_buffs_to_write, sock_fd);
  509. }
  510. int write_buffs_to_flash (void *virt_addr, int num_buffs_to_write, FILE * write_fd) {
  511. int wr_num = 0;
  512. wr_num = fwrite ( virt_addr, sizeof(uint8_t), num_buffs_to_write * BUFSIZE, write_fd);
  513. if (wr_num != num_buffs_to_write * BUFSIZE)
  514. {
  515. printf ("Error writing flash file %d \n", errno);
  516. strerror(errno);
  517. }
  518. return (wr_num);
  519. }
  520. int data_to_bin_file (adc_conf *conf, int client_sock_fd, char dataFile[])
  521. {
  522. int i, j, k;
  523. int buffs = 0;
  524. unsigned long read_result;
  525. int read_fd;
  526. FILE *write_fd;
  527. void *map_base, *virt_addr;
  528. void *pru1_wr_flag_addr;
  529. void *pru1_buff_count_addr;
  530. void *pru1_head_addr;
  531. void *pru1_wrap_count_addr;
  532. int wr_num = 0;
  533. int tail = 0;
  534. int num_buffs = 0;
  535. int num_buffs_to_write = 0;
  536. int last_count = 0;
  537. int num_buffs_processed = 0;
  538. volatile unsigned long pru1_wr_flag = 0;
  539. volatile unsigned long pru1_buff_count = 0;
  540. volatile unsigned long pru1_head = 0;
  541. volatile unsigned long pru1_wrap_count = 0;
  542. unsigned int addr = conf->addr;
  543. unsigned int pru1_conf_addr = conf->addr;
  544. int iteration = 0;
  545. int count = 0;
  546. int network_send = TRUE;
  547. //int network_send = FALSE;
  548. int flash_record = TRUE;
  549. if((read_fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1){
  550. printf("Failed to open memory!");
  551. return (ERR);
  552. }
  553. printf("Memory file open successfully \n");
  554. write_fd = fopen(dataFile, "wb");
  555. if( write_fd == NULL){
  556. printf("Failed to open data file \n");
  557. return (ERR);
  558. }
  559. printf("Data file open successfully \n");
  560. map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, read_fd, addr & ~MAP_MASK);
  561. if(map_base == (void *) -1) {
  562. printf("Failed to map base address");
  563. return (ERR);
  564. }
  565. else {
  566. printf("Base Address = %x \n", map_base);
  567. }
  568. #if DEBUG
  569. printf("Dumping header data \n");
  570. i = 0;
  571. j = 0;
  572. for(i = 0; i < (PRU1_START_OFFSET + 256); i+= (8 * BYTES_PER_SAMPLE)){
  573. for (j = 0; j < 8; j++) {
  574. virt_addr = map_base + (addr & MAP_MASK);
  575. read_result = *((uint32_t *) virt_addr);
  576. printf( "0x%08x ", read_result);
  577. addr += BYTES_PER_SAMPLE;
  578. }
  579. printf("\n");
  580. }
  581. #endif
  582. pru1_conf_addr = conf->addr;
  583. addr = conf->addr + PRU1_START_OFFSET;
  584. pru1_wr_flag_addr = map_base + ((pru1_conf_addr + PRU1_WR_FLAG) & MAP_MASK);
  585. pru1_wr_flag = *((uint32_t *) pru1_wr_flag_addr);
  586. pru1_buff_count_addr = map_base + ((pru1_conf_addr + PRU1_BUFF_COUNT) & MAP_MASK);
  587. pru1_buff_count = *((uint32_t *) pru1_buff_count_addr);
  588. pru1_head_addr = map_base + ((pru1_conf_addr + PRU1_HEAD) & MAP_MASK);
  589. pru1_head = *((uint32_t *) pru1_head_addr);
  590. pru1_wrap_count_addr = map_base + ((pru1_conf_addr + PRU1_WRAP_COUNT) & MAP_MASK);
  591. pru1_wrap_count = *((uint32_t *) pru1_wrap_count_addr);
  592. tail = 0;
  593. while (num_buffs_processed < DAQ_FILE_SIZE)
  594. {
  595. virt_addr = map_base + ((pru1_conf_addr + PRU1_WR_FLAG) & MAP_MASK);
  596. pru1_wr_flag = *((uint32_t *) pru1_wr_flag_addr);
  597. pru1_buff_count_addr = map_base + ((pru1_conf_addr + PRU1_BUFF_COUNT) & MAP_MASK);
  598. pru1_buff_count = *((uint32_t *) pru1_buff_count_addr);
  599. pru1_head_addr = map_base + ((pru1_conf_addr + PRU1_HEAD) & MAP_MASK);
  600. pru1_head = *((uint32_t *) pru1_head_addr);
  601. pru1_wrap_count_addr = map_base + ((pru1_conf_addr + PRU1_WRAP_COUNT) & MAP_MASK);
  602. pru1_wrap_count = *((uint32_t *) pru1_wrap_count_addr);
  603. if (pru1_wr_flag == 1)
  604. {
  605. num_buffs = pru1_buff_count - last_count;
  606. if (num_buffs > 0)
  607. {
  608. // printf("h = %d, t = %d, num_buffs = %d ", pru1_head, tail, num_buffs);
  609. }
  610. if (num_buffs <= QUEUE_SIZE)
  611. {
  612. if (tail < pru1_head)
  613. {
  614. num_buffs_to_write = pru1_head - tail;
  615. virt_addr = map_base + (addr & MAP_MASK);
  616. process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send);
  617. num_buffs_processed += num_buffs_to_write;
  618. addr += num_buffs_to_write * BUFSIZE;
  619. tail = tail_increment(tail, num_buffs_to_write);
  620. pru1_wr_flag = 0;
  621. }
  622. else if (tail > pru1_head)
  623. {
  624. // Write the buffers from the tail to the end of the queue.
  625. virt_addr = map_base + (addr & MAP_MASK);
  626. num_buffs_to_write = QUEUE_SIZE - tail;
  627. process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send);
  628. //addr += num_buffs_to_write * BUFSIZE;
  629. tail = tail_increment(tail, num_buffs_to_write);
  630. num_buffs_processed += num_buffs_to_write;
  631. // Write the buffers from the beginning of the queue (zeroth element) to the head
  632. // We have to remember to set the pointer back to the beginning of shared memory
  633. addr = conf->addr + PRU1_START_OFFSET;
  634. virt_addr = map_base + (addr & MAP_MASK);
  635. num_buffs_to_write = pru1_head;
  636. process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send);
  637. addr += num_buffs_to_write * BUFSIZE;
  638. num_buffs_processed += num_buffs_to_write;
  639. tail = tail_increment(tail, num_buffs_to_write);
  640. }
  641. else if ((tail == pru1_head) && (num_buffs == QUEUE_SIZE))
  642. {
  643. // Write the buffers from the tail to the end of the queue.
  644. virt_addr = map_base + (addr & MAP_MASK);
  645. num_buffs_to_write += QUEUE_SIZE - tail;
  646. process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send);
  647. num_buffs_processed += num_buffs_to_write;
  648. addr += num_buffs_to_write * BUFSIZE;
  649. tail = tail_increment(tail, num_buffs_to_write);
  650. // Write the buffers from the beginning of the queue to the head
  651. addr = conf->addr + PRU1_START_OFFSET;
  652. virt_addr = map_base + (addr & MAP_MASK);
  653. num_buffs_to_write = pru1_head;
  654. process_buffers(virt_addr, num_buffs_to_write, client_sock_fd, write_fd, flash_record, network_send);
  655. addr += num_buffs_to_write * BUFSIZE;
  656. num_buffs_processed += num_buffs_to_write;
  657. tail = tail_increment(tail, num_buffs_to_write); // This may look funny, but we are incrementing tail by tail.
  658. }
  659. pru1_wr_flag = 0;
  660. if (num_buffs > 0)
  661. {
  662. count += num_buffs;
  663. if (count >= 30)
  664. {
  665. printf("h = %d, t = %d, num_buffs = %d ", pru1_head, tail, num_buffs);
  666. printf("num_procd = %d, addr = %x \n", num_buffs_processed, addr);
  667. count = 0;
  668. }
  669. // if (num_buffs_processed >= 180)
  670. // {
  671. // printf("num_procd = %d, addr = %x \n", num_buffs_processed, addr);
  672. // // this is a place to set a breakpoint
  673. // }
  674. }
  675. last_count = pru1_buff_count;
  676. usleep(100);
  677. }
  678. else if (num_buffs > QUEUE_SIZE)
  679. {
  680. // We have detected an overflow condition, likely due to some linux related activity.
  681. // For now we throw out the buffers that have accumulated. Later we can explore saving
  682. // those buffers.
  683. printf("Queue overflow %d \n", num_buffs);
  684. last_count = pru1_buff_count;
  685. num_buffs_processed += num_buffs;
  686. usleep(100);
  687. }
  688. }
  689. }
  690. printf("TOTAL num_buffs_processed = %d \n", num_buffs_processed);
  691. fclose ((FILE *)write_fd);
  692. return (OK);
  693. }
  694. generate_cal_data( ) {
  695. FILE *read_5v_fd;
  696. FILE *read_0v_fd;
  697. FILE *write_fd;
  698. uint32_t average_5v[8];
  699. uint32_t average_0v[8];
  700. float ma[8];
  701. uint32_t b[8];
  702. int i;
  703. uint32_t temp;
  704. read_5v_fd = fopen("/home/erps/caldata/board1_5v_golden_063018.dat", "r");
  705. if( read_5v_fd == NULL){
  706. printf("Failed to open 5v cal data file \n");
  707. return (ERR);
  708. }
  709. else
  710. printf("Cal File Opened \n");
  711. read_and_average_cal_data(read_5v_fd, &average_5v[0]);
  712. printf("5V Averages %x %x %x %x %x %x %x %x \n\n",average_5v[0], average_5v[1],
  713. average_5v[2], average_5v[3], average_5v[4], average_5v[5], average_5v[6], average_5v[7]);
  714. read_0v_fd = fopen("/home/erps/caldata/board1_0v_golden_063018.dat", "r");
  715. if( read_0v_fd == NULL){
  716. printf("Failed to open 0v cal data file \n");
  717. return (ERR);
  718. }
  719. else
  720. printf("Cal File Opened \n");
  721. write_fd = fopen("/home/erps/caldata/board1_cal_golden_063018.dat", "w");
  722. if( write_fd == NULL){
  723. printf("Failed to open cal result file \n");
  724. return (ERR);
  725. }
  726. else
  727. printf("Cal Result File Opened \n");
  728. read_and_average_cal_data(read_0v_fd, &average_0v[0]);
  729. printf("0V Averages %x %x %x %x %x %x %x %x \n\n",average_0v[0], average_0v[1],
  730. average_0v[2], average_0v[3], average_0v[4], average_0v[5], average_0v[6], average_0v[7]);
  731. for (i = 0; i < 8; i++)
  732. {
  733. // y = mx + b
  734. //ma = (yH - yL) / (xH - xL)
  735. if (average_0v[i] & 0x800000)
  736. {
  737. temp = ~average_0v[i] & 0x00FFFFFF;
  738. ma[i] = (float)(average_5v[i] + temp) / 0x7FFFFF ;
  739. b[i] = temp * ma[i];
  740. }
  741. else
  742. {
  743. ma[i] = (float)(average_5v[i] - average_0v[i]) / 0x7FFFFF ;
  744. b[i] = average_0v[i] * ma[i];
  745. }
  746. }
  747. printf("\n\n");
  748. printf(" ma:%f %f %f %f %f %f %f %f \n", ma[0], ma[1], ma[2], ma[3], ma[4], ma[5], ma[6], ma[7]);
  749. printf(" b :%x %x %x %x %x %x %x %x \n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
  750. fprintf(write_fd, "%f %f %f %f %f %f %f %f \n", ma[0], ma[1], ma[2], ma[3], ma[4], ma[5], ma[6], ma[7]);
  751. fprintf(write_fd, "%x %x %x %x %x %x %x %x \n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
  752. fclose ((FILE *)read_5v_fd);
  753. fclose ((FILE *)read_0v_fd);
  754. fclose ((FILE *)write_fd);
  755. }
  756. read_and_average_cal_data(FILE *read_fd, uint32_t *average[]) {
  757. int i = 0;
  758. int j = 0;
  759. uint32_t s[8];
  760. uint64_t total[8];
  761. int64_t tot[8];
  762. for (i = 0; i < 9; i ++){
  763. fscanf(read_fd, "%x %x %x %x %x %x %x %x \n", &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7]);
  764. // printf("%x %x %x %x %x %x %x %x \n", s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
  765. }
  766. for (i = 0; i < 8; i ++) {
  767. total[i] = 0;
  768. s[i] = 0;
  769. average[i] = 0;
  770. }
  771. for (i = 0; i < 8; i ++) {
  772. for (j = 0; j < 8; j++) {
  773. fscanf(read_fd, "%x", &s[j]);
  774. s[j] &= s[j] & 0x0FFFFFF;
  775. if (s[j] & 0x800000)
  776. {
  777. s[j] = ~s[j] & 0xFFFFFF;
  778. tot[j] -= s[j];
  779. }
  780. tot[j] += s[j];
  781. total[j] += s[j];
  782. }
  783. fscanf(read_fd, "\n");
  784. }
  785. printf("Totals %x %x %x %x %x %x %x %x \n \n",total[0], total[1], total[2], total[3], total[4], total[5], total[6], total[7]);
  786. printf("Totals %x %x %x %x %x %x %x %x \n \n",(uint32_t)tot[0], (uint32_t) tot[1], (uint32_t) tot[2], (uint32_t) tot[3],
  787. (uint32_t) tot[4], (uint32_t) tot[5], (uint32_t)tot[6], (uint32_t)tot[7]);
  788. for (i = 0; i < 8; i ++)
  789. {
  790. average[i] = total[i] / 8;
  791. }
  792. }