From adf10fafd87ac58b7ac6e899992305dba91563c1 Mon Sep 17 00:00:00 2001 From: lharnaldi <lharnaldi@gmail.com> Date: Fri, 5 Aug 2022 16:40:28 -0300 Subject: [PATCH] Agrgeo los proyectos de test --- projects/adc_recorder/adc-recorder.c | 81 +++ projects/adc_recorder/block_design.tcl | 241 +++++++++ projects/adc_recorder/src/Makefile | 16 + projects/adc_recorder/src/adc_recorder.c | 103 ++++ projects/adc_recorder/src/zynq_io.c | 470 +++++++++++++++++ projects/adc_recorder/src/zynq_io.h | 154 ++++++ projects/adc_recorder_uio/adc-recorder.c | 81 +++ projects/adc_recorder_uio/block_design.tcl | 241 +++++++++ projects/adc_recorder_uio/uio_src/Makefile | 16 + .../adc_recorder_uio/uio_src/adc_recorder.c | 103 ++++ projects/adc_recorder_uio/uio_src/zynq_io.c | 473 +++++++++++++++++ projects/adc_recorder_uio/uio_src/zynq_io.h | 155 ++++++ projects/adc_test/block_design.tcl | 299 +++++++++++ projects/adc_test/client/Makefile | 11 + projects/adc_test/client/adc-test-client_lnx | Bin 0 -> 17336 bytes .../adc_test/client/adc-test-client_lnx.c | 102 ++++ .../adc_test/client/adc-test-client_win.c | 44 ++ projects/adc_test/server/adc-test-server.c | 164 ++++++ projects/adc_test/server/gen.c | 56 +++ projects/counter_test/block_design.tcl | 162 ++++++ projects/counter_test/uio_src/Makefile | 16 + projects/counter_test/uio_src/counter_test.c | 92 ++++ projects/counter_test/uio_src/zynq_io.c | 475 ++++++++++++++++++ projects/counter_test/uio_src/zynq_io.h | 156 ++++++ projects/led_blinker/app/index.html | 24 + projects/led_blinker/app/start.sh | 7 + projects/ramp_test/block_design.tcl | 47 ++ projects/ramp_test/ramp_test.c | 58 +++ projects/xadc_test/block_design.tcl | 49 ++ projects/xadc_test/xadc_test.c | 119 +++++ projects/xadc_test/xadc_uio.c | 266 ++++++++++ 31 files changed, 4281 insertions(+) create mode 100644 projects/adc_recorder/adc-recorder.c create mode 100644 projects/adc_recorder/block_design.tcl create mode 100644 projects/adc_recorder/src/Makefile create mode 100644 projects/adc_recorder/src/adc_recorder.c create mode 100644 projects/adc_recorder/src/zynq_io.c create mode 100644 projects/adc_recorder/src/zynq_io.h create mode 100644 projects/adc_recorder_uio/adc-recorder.c create mode 100644 projects/adc_recorder_uio/block_design.tcl create mode 100644 projects/adc_recorder_uio/uio_src/Makefile create mode 100644 projects/adc_recorder_uio/uio_src/adc_recorder.c create mode 100644 projects/adc_recorder_uio/uio_src/zynq_io.c create mode 100644 projects/adc_recorder_uio/uio_src/zynq_io.h create mode 100644 projects/adc_test/block_design.tcl create mode 100644 projects/adc_test/client/Makefile create mode 100755 projects/adc_test/client/adc-test-client_lnx create mode 100644 projects/adc_test/client/adc-test-client_lnx.c create mode 100644 projects/adc_test/client/adc-test-client_win.c create mode 100644 projects/adc_test/server/adc-test-server.c create mode 100644 projects/adc_test/server/gen.c create mode 100644 projects/counter_test/block_design.tcl create mode 100644 projects/counter_test/uio_src/Makefile create mode 100644 projects/counter_test/uio_src/counter_test.c create mode 100644 projects/counter_test/uio_src/zynq_io.c create mode 100644 projects/counter_test/uio_src/zynq_io.h create mode 100644 projects/led_blinker/app/index.html create mode 100755 projects/led_blinker/app/start.sh create mode 100644 projects/ramp_test/block_design.tcl create mode 100644 projects/ramp_test/ramp_test.c create mode 100644 projects/xadc_test/block_design.tcl create mode 100644 projects/xadc_test/xadc_test.c create mode 100644 projects/xadc_test/xadc_uio.c diff --git a/projects/adc_recorder/adc-recorder.c b/projects/adc_recorder/adc-recorder.c new file mode 100644 index 0000000..388d582 --- /dev/null +++ b/projects/adc_recorder/adc-recorder.c @@ -0,0 +1,81 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/ioctl.h> + +#define CMA_ALLOC _IOWR('Z', 0, uint32_t) + +int main() +{ + int fd, i; + volatile uint8_t *rst; + volatile void *cfg; + volatile int16_t *ram; + uint32_t size; + int16_t value[2]; + + if((fd = open("/dev/mem", O_RDWR)) < 0) + { + perror("open"); + return EXIT_FAILURE; + } + + cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40000000); + + close(fd); + + if((fd = open("/dev/cma", O_RDWR)) < 0) + { + perror("open"); + return EXIT_FAILURE; + } + + size = 1024*sysconf(_SC_PAGESIZE); + + if(ioctl(fd, CMA_ALLOC, &size) < 0) + { + perror("ioctl"); + return EXIT_FAILURE; + } + + ram = mmap(NULL, 1024*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + + rst = (uint8_t *)(cfg + 0); + + // set writer address + *(uint32_t *)(cfg + 4) = size; + + // set number of samples + *(uint32_t *)(cfg + 8) = 1024 * 1024 - 1; + + // reset writer + *rst &= ~4; + *rst |= 4; + + // reset fifo and filters + *rst &= ~1; + *rst |= 1; + + // wait 1 second + sleep(1); + + // reset packetizer + *rst &= ~2; + *rst |= 2; + + // wait 1 second + sleep(1); + + // print IN1 and IN2 samples + for(i = 0; i < 1024 * 1024; ++i) + { + value[0] = ram[2 * i + 0]; + value[1] = ram[2 * i + 1]; + printf("%5d %5d\n", value[0], value[1]); + } + + return EXIT_SUCCESS; +} diff --git a/projects/adc_recorder/block_design.tcl b/projects/adc_recorder/block_design.tcl new file mode 100644 index 0000000..083ce73 --- /dev/null +++ b/projects/adc_recorder/block_design.tcl @@ -0,0 +1,241 @@ +# Create clk_wiz +cell xilinx.com:ip:clk_wiz pll_0 { + PRIMITIVE PLL + PRIM_IN_FREQ.VALUE_SRC USER + PRIM_IN_FREQ 125.0 + PRIM_SOURCE Differential_clock_capable_pin + CLKOUT1_USED true + CLKOUT1_REQUESTED_OUT_FREQ 125.0 + USE_RESET false +} { + clk_in1_p adc_clk_p_i + clk_in1_n adc_clk_n_i +} + +# Create processing_system7 +cell xilinx.com:ip:processing_system7 ps_0 { + PCW_IMPORT_BOARD_PRESET cfg/red_pitaya.xml + PCW_USE_S_AXI_ACP 1 + PCW_USE_DEFAULT_ACP_USER_VAL 1 +} { + M_AXI_GP0_ACLK pll_0/clk_out1 + S_AXI_ACP_ACLK pll_0/clk_out1 +} + +# Create all required interconnections +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config { + make_external {FIXED_IO, DDR} + Master Disable + Slave Disable +} [get_bd_cells ps_0] + +# Create xlconstant +cell xilinx.com:ip:xlconstant const_0 + +# Create proc_sys_reset +cell xilinx.com:ip:proc_sys_reset rst_0 {} { + ext_reset_in const_0/dout +} + +# GPIO + +# Delete input/output port +delete_bd_objs [get_bd_ports exp_p_tri_io] + +# Create output port +create_bd_port -dir O -from 7 -to 0 exp_p_tri_io + +# ADC + +# Create axis_red_pitaya_adc +cell labdpr:user:axis_rp_adc adc_0 { + ADC_DATA_WIDTH 14 +} { + aclk pll_0/clk_out1 + adc_dat_a adc_dat_a_i + adc_dat_b adc_dat_b_i + adc_csn adc_csn_o +} + +# Create axi_cfg_register +cell labdpr:user:axi_cfg_register cfg_0 { + CFG_DATA_WIDTH 96 + AXI_ADDR_WIDTH 32 + AXI_DATA_WIDTH 32 +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_0 { + DIN_WIDTH 96 DIN_FROM 0 DIN_TO 0 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_1 { + DIN_WIDTH 96 DIN_FROM 1 DIN_TO 1 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_2 { + DIN_WIDTH 96 DIN_FROM 2 DIN_TO 2 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_3 { + DIN_WIDTH 96 DIN_FROM 63 DIN_TO 32 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_4 { + DIN_WIDTH 96 DIN_FROM 95 DIN_TO 64 +} { + din cfg_0/cfg_data +} + +# Create util_vector_logic +cell xilinx.com:ip:util_vector_logic not_0 { + C_SIZE 1 + C_OPERATION not +} { + Op1 slice_1/dout +} + +# Create xlconcat +cell xilinx.com:ip:xlconcat concat_0 { + NUM_PORTS 2 + IN0_WIDTH 1 + IN1_WIDTH 7 +} { + In0 not_0/Res + dout exp_p_tri_io +} + +# Create axis_broadcaster +cell xilinx.com:ip:axis_broadcaster bcast_0 { + S_TDATA_NUM_BYTES.VALUE_SRC USER + M_TDATA_NUM_BYTES.VALUE_SRC USER + S_TDATA_NUM_BYTES 4 + M_TDATA_NUM_BYTES 2 + M00_TDATA_REMAP {tdata[15:0]} + M01_TDATA_REMAP {tdata[31:16]} +} { + S_AXIS adc_0/M_AXIS + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +# Create cic_compiler +cell xilinx.com:ip:cic_compiler cic_0 { + INPUT_DATA_WIDTH.VALUE_SRC USER + FILTER_TYPE Decimation + NUMBER_OF_STAGES 6 + FIXED_OR_INITIAL_RATE 32 + INPUT_SAMPLE_FREQUENCY 125 + CLOCK_FREQUENCY 125 + INPUT_DATA_WIDTH 14 + QUANTIZATION Truncation + OUTPUT_DATA_WIDTH 16 + USE_XTREME_DSP_SLICE true + HAS_ARESETN true +} { + S_AXIS_DATA bcast_0/M00_AXIS + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# Create cic_compiler +cell xilinx.com:ip:cic_compiler cic_1 { + INPUT_DATA_WIDTH.VALUE_SRC USER + FILTER_TYPE Decimation + NUMBER_OF_STAGES 6 + FIXED_OR_INITIAL_RATE 32 + INPUT_SAMPLE_FREQUENCY 125 + CLOCK_FREQUENCY 125 + INPUT_DATA_WIDTH 14 + QUANTIZATION Truncation + OUTPUT_DATA_WIDTH 16 + USE_XTREME_DSP_SLICE true + HAS_ARESETN true +} { + S_AXIS_DATA bcast_0/M01_AXIS + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# Create axis_combiner +cell xilinx.com:ip:axis_combiner comb_0 { + TDATA_NUM_BYTES.VALUE_SRC USER + TDATA_NUM_BYTES 2 +} { + S00_AXIS cic_0/M_AXIS_DATA + S01_AXIS cic_1/M_AXIS_DATA + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +# Create fir_compiler +cell xilinx.com:ip:fir_compiler fir_0 { + DATA_WIDTH.VALUE_SRC USER + DATA_WIDTH 16 + COEFFICIENTVECTOR {-1.64753028794138e-08, -4.72969860103254e-08, -7.81983994864729e-10, 3.09179315378013e-08, 1.8600476137934e-08, 3.27300695910419e-08, -6.27121813377163e-09, -1.52196115352429e-07, -8.30377969926702e-08, 3.14361841397898e-07, 3.05515872274853e-07, -4.73906648324436e-07, -7.13188274738437e-07, 5.47004771774003e-07, 1.33401100809314e-06, -4.13867548024707e-07, -2.14949555259695e-06, -6.77977800948474e-08, 3.07398932714553e-06, 1.0366230107463e-06, -3.94245232963009e-06, -2.59076839821521e-06, 4.51317323767107e-06, 4.74563996488482e-06, -4.49064349142054e-06, -7.3947777960083e-06, 3.57041197419745e-06, 1.02846684426837e-05, -1.50308472093842e-06, -1.30146997163052e-05, -1.8311731233767e-06, 1.50710364353895e-05, 6.3515248701083e-06, -1.58982472678568e-05, -1.17267343142635e-05, 1.50041199296265e-05, 1.73635115814309e-05, -1.20890304109726e-05, -2.24560062957254e-05, 7.16700059796055e-06, 2.60907689345942e-05, -6.64193032293714e-07, -2.74163749798938e-05, -6.54632074532538e-06, 2.5852558776971e-05, 1.31966582845397e-05, -2.13079073598636e-05, -1.77801135294917e-05, 1.43611952054032e-05, 1.88093817512436e-05, -6.35698021047062e-06, -1.51543007857966e-05, -6.31269475321274e-07, 6.41236246473726e-06, 4.00235076480002e-06, 6.75384652715119e-06, -1.00102812372645e-06, -2.23907547607786e-05, -1.07614170164429e-05, 3.72128949266483e-05, 3.26888314865614e-05, -4.68343172264928e-05, -6.46247522446593e-05, 4.62331324663801e-05, 0.000104353987875991, -3.05204178369922e-05, -0.000147387572103254, -4.12376672483791e-06, 0.000187096070793206, 5.94492160104715e-05, -0.000215270553995213, -0.000134242574203586, 0.000223115373945588, 0.000223732063932204, -0.000202601585158347, -0.000319473722277179, 0.000148023831554525, 0.000409856470754451, -5.75319241913947e-05, -0.00048128691789378, -6.56435551088113e-05, 0.000520005389882914, 0.000212559310978688, -0.000514378040456993, -0.000368824791639381, 0.000457257636791032, 0.00051572189965271, -0.000348325111720936, -0.000632574861580132, 0.000195575644936742, 0.000699853643923955, -1.5816811333843e-05, -0.000702875004558909, -0.000166267212059945, 0.000635554670416145, 0.000320646045613507, -0.000503596369030625, -0.000416023690327203, 0.000326453158345306, 0.00042516016658693, -0.000137454215410763, -0.000330867755122004, -1.83577770104995e-05, 0.000131884375290827, 8.88732824246191e-05, 0.000152320700965935, -2.19145324792827e-05, -0.000478845867687744, -0.000226130995959082, 0.000781165284659716, 0.000680083599509367, -0.000973297239795462, -0.00133684955123469, 0.000956951103249511, 0.00215724393391554, -0.000632647805407322, -0.00306094569410801, -8.63474252426424e-05, 0.00392560461099799, 0.00125840455441931, -0.00459097537930345, -0.00289777037472875, 0.00486843895178868, 0.00496041688761007, -0.00455566278421732, -0.0073332195556104, 0.00345548961533671, 0.00982788076765724, -0.0013975392826423, -0.0121803938743171, -0.00173944634676796, 0.0140556603140014, 0.00600554245501628, -0.0150585666700821, -0.0113645359721422, 0.0147416608531572, 0.0176785888467245, -0.0126130926725902, -0.0247012339350495, 0.00812796467212303, 0.0320712315374266, -0.000646259298618774, -0.0392988478933562, -0.0106852885932714, 0.0457163887873562, 0.0272344645510023, -0.0503010855018923, -0.0516879242105393, 0.0510032995068897, 0.0905252892059647, -0.0416077244968566, -0.163677972614864, -0.0107434888500177, 0.356350050991766, 0.554721342376512, 0.356350050991766, -0.0107434888500177, -0.163677972614864, -0.0416077244968565, 0.0905252892059646, 0.0510032995068897, -0.0516879242105392, -0.0503010855018923, 0.0272344645510023, 0.0457163887873562, -0.0106852885932714, -0.0392988478933562, -0.000646259298618766, 0.0320712315374266, 0.008127964672123, -0.0247012339350495, -0.0126130926725902, 0.0176785888467245, 0.0147416608531572, -0.0113645359721422, -0.0150585666700821, 0.00600554245501627, 0.0140556603140014, -0.00173944634676796, -0.0121803938743171, -0.0013975392826423, 0.00982788076765723, 0.00345548961533672, -0.0073332195556104, -0.00455566278421732, 0.00496041688761004, 0.00486843895178868, -0.00289777037472874, -0.00459097537930345, 0.00125840455441931, 0.003925604610998, -8.6347425242651e-05, -0.00306094569410801, -0.000632647805407327, 0.00215724393391554, 0.000956951103249513, -0.00133684955123469, -0.000973297239795458, 0.00068008359950937, 0.000781165284659718, -0.000226130995959085, -0.000478845867687734, -2.19145324792814e-05, 0.000152320700965923, 8.88732824246168e-05, 0.000131884375290828, -1.83577770104952e-05, -0.000330867755122008, -0.000137454215410769, 0.000425160166586931, 0.000326453158345309, -0.000416023690327193, -0.000503596369030629, 0.000320646045613497, 0.000635554670416148, -0.000166267212059939, -0.000702875004558908, -1.58168113338674e-05, 0.000699853643923955, 0.000195575644936758, -0.000632574861580132, -0.000348325111720941, 0.000515721899652708, 0.000457257636791035, -0.000368824791639379, -0.000514378040456997, 0.000212559310978687, 0.000520005389882915, -6.56435551088096e-05, -0.000481286917893776, -5.7531924191395e-05, 0.000409856470754451, 0.000148023831554525, -0.000319473722277176, -0.000202601585158348, 0.000223732063932204, 0.000223115373945587, -0.000134242574203588, -0.000215270553995212, 5.944921601047e-05, 0.000187096070793206, -4.12376672483805e-06, -0.000147387572103254, -3.05204178369924e-05, 0.000104353987875991, 4.62331324663777e-05, -6.46247522446589e-05, -4.68343172264921e-05, 3.26888314865612e-05, 3.72128949266458e-05, -1.07614170164428e-05, -2.23907547607785e-05, -1.0010281237264e-06, 6.7538465271515e-06, 4.00235076480007e-06, 6.41236246473652e-06, -6.31269475321259e-07, -1.5154300785797e-05, -6.35698021047036e-06, 1.88093817512439e-05, 1.43611952054029e-05, -1.77801135294911e-05, -2.13079073598635e-05, 1.31966582845395e-05, 2.58525587769708e-05, -6.54632074532428e-06, -2.74163749798938e-05, -6.64193032294061e-07, 2.60907689345942e-05, 7.16700059796085e-06, -2.24560062957254e-05, -1.20890304109726e-05, 1.7363511581431e-05, 1.50041199296266e-05, -1.17267343142635e-05, -1.58982472678571e-05, 6.3515248701082e-06, 1.50710364353894e-05, -1.83117312337678e-06, -1.30146997163053e-05, -1.50308472093845e-06, 1.02846684426836e-05, 3.57041197419745e-06, -7.39477779600816e-06, -4.49064349142055e-06, 4.74563996488478e-06, 4.51317323767109e-06, -2.59076839821518e-06, -3.94245232963005e-06, 1.03662301074629e-06, 3.07398932714552e-06, -6.77977800948646e-08, -2.14949555259695e-06, -4.13867548024735e-07, 1.33401100809314e-06, 5.47004771773993e-07, -7.13188274738437e-07, -4.73906648324394e-07, 3.05515872274853e-07, 3.14361841397861e-07, -8.30377969926656e-08, -1.5219611535243e-07, -6.27121813377245e-09, 3.27300695910341e-08, 1.86004761379317e-08, 3.0917931537805e-08, -7.81983994865244e-10, -4.72969860103212e-08, -1.64753028794135e-08} + COEFFICIENT_WIDTH 16 + QUANTIZATION Quantize_Only + BESTPRECISION true + FILTER_TYPE Decimation + DECIMATION_RATE 2 + NUMBER_PATHS 2 + RATESPECIFICATION Input_Sample_Period + SAMPLEPERIOD 32 + OUTPUT_ROUNDING_MODE Truncate_LSBs + OUTPUT_WIDTH 16 + HAS_ARESETN true +} { + S_AXIS_DATA comb_0/M_AXIS + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# Create axis_packetizer +cell labdpr:user:axis_packetizer pktzr_0 { + AXIS_TDATA_WIDTH 32 + CNTR_WIDTH 32 + CONTINUOUS FALSE +} { + S_AXIS fir_0/M_AXIS_DATA + cfg_data slice_4/dout + aclk pll_0/clk_out1 + aresetn slice_1/dout +} + +# Create axis_dwidth_converter +cell xilinx.com:ip:axis_dwidth_converter conv_0 { + S_TDATA_NUM_BYTES.VALUE_SRC USER + S_TDATA_NUM_BYTES 4 + M_TDATA_NUM_BYTES 8 +} { + S_AXIS pktzr_0/M_AXIS + aclk pll_0/clk_out1 + aresetn slice_2/dout +} + +# Create axis_ram_writer +cell labdpr:user:axis_ram_writer writer_0 { + ADDR_WIDTH 22 + AXI_ID_WIDTH 3 +} { + S_AXIS conv_0/M_AXIS + M_AXI ps_0/S_AXI_ACP + cfg_data slice_3/dout + aclk pll_0/clk_out1 + aresetn slice_2/dout +} + +addr 0x40000000 4K cfg_0/S_AXI /ps_0/M_AXI_GP0 + diff --git a/projects/adc_recorder/src/Makefile b/projects/adc_recorder/src/Makefile new file mode 100644 index 0000000..858880d --- /dev/null +++ b/projects/adc_recorder/src/Makefile @@ -0,0 +1,16 @@ +CC=gcc +FLAGS=-Wall -O3 +ARCH=arm +CROSS_COMPILE=arm-xilinx-linux-gnueabi- + +#### +PROG=adc_recorder +EXTRA= zynq_io.c + +all: $(PROG) + +$(PROG): $(PROG).c $(EXTRA) + $(CC) $(FLAGS) -o $(PROG) $(PROG).c $(EXTRA) -lm -lpthread + +clean: + rm -f $(PROG) diff --git a/projects/adc_recorder/src/adc_recorder.c b/projects/adc_recorder/src/adc_recorder.c new file mode 100644 index 0000000..ffe2730 --- /dev/null +++ b/projects/adc_recorder/src/adc_recorder.c @@ -0,0 +1,103 @@ +#include "zynq_io.h" + +int main(int argc, char *argv[]) +{ + //int fd; + //unsigned int size; + uint32_t i,val=0; + uint32_t wo; + int16_t ch[2]; + + printf("ADC RECORDER test\n"); + + //initialize devices. TODO: add error checking + //intc_init(); + cfg_init(); + cma_init(); + //sts_init(); + //xadc_init(); + + // set writer address + // *(uint32_t *)(cfg + 4) = size; + // + printf("Set writer address...\n"); + val=rd_reg_value(1, CFG_WR_ADDR_OFFSET); + printf("dev_size es: %d ...\n",dev_size); + wr_reg_value(1, CFG_WR_ADDR_OFFSET, dev_size); + + // set number of samples + // *(uint32_t *)(cfg + 8) = 1024 * 1024 - 1; + // + printf("Set number of samples...\n"); + val=rd_reg_value(1, CFG_NSAMPLES_OFFSET); + wr_reg_value(1, CFG_NSAMPLES_OFFSET, 1024 * 1024 - 1); + + // reset writer + //*((uint32_t *)(cfg + 0)) &= ~4; + printf("Reseting writer...\n"); + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &= ~4); + //*((uint32_t *)(cfg + 0)) |= 4; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |= 4); +// printf("Reseting writer %d ...\n",val); + printf("Reseting fifo and filters...\n"); +// // reset fifo and filters + //*((uint32_t *)(cfg + 0)) &= ~1; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &=~1); +// //*((uint32_t *)(cfg + 0)) |= 1; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |=1); +// printf("Reseting fifo and filters %d ...\n",val); +// +// // wait 1 second + sleep(1); +// + printf("Reseting packetizer...\n"); + // enter reset mode for packetizer + //*((uint32_t *)(cfg + 0)) &= ~2; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &=~2); + + // set number of samples + //*((uint32_t *)(cfg + 4)) = 1024 * 1024 - 1; +// wr_reg_value(1, CFG_NSAMPLES_OFFSET, 1024 * 1024 - 1); + + // enter normal mode +// //*((uint32_t *)(cfg + 0)) |= 2; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |=2); +// printf("Reseting packetizer %d ...\n",val); +// +// // wait 1 second + sleep(1); + + // print IN1 and IN2 samples + for(i = 0; i < 1024 * 1024; ++i){ + ch[0] = *((int16_t *)(cma_ptr + 2*i + 0)); + ch[1] = *((int16_t *)(cma_ptr + 2*i + 2)); + wo = *((uint32_t *)(cma_ptr + i)); + printf("%5d %5d %10d\n", ch[0], ch[1], wo); +// ch[0] = cma_ptr[2 * i + 0]; +// ch[1] = cma_ptr[2 * i + 1]; +// //wo = cma_ptr[i] +// printf("%5d %5d\n", ch[0], ch[1]); + } + + // unmap and close the devices + //munmap(intc_ptr, sysconf(_SC_PAGESIZE)); +// munmap(cfg_ptr, sysconf(_SC_PAGESIZE)); +// //munmap(sts_ptr, sysconf(_SC_PAGESIZE)); +// //munmap(xadc_ptr, sysconf(_SC_PAGESIZE)); +// munmap(cma_ptr, sysconf(_SC_PAGESIZE)); + + //close(intc_fd); + close(cfg_fd); + //close(sts_fd); + //close(xadc_fd); + printf("Saliendo ...\n"); + + return 0; + +} diff --git a/projects/adc_recorder/src/zynq_io.c b/projects/adc_recorder/src/zynq_io.c new file mode 100644 index 0000000..35d23c6 --- /dev/null +++ b/projects/adc_recorder/src/zynq_io.c @@ -0,0 +1,470 @@ +#include "zynq_io.h" + +int intc_fd, cfg_fd, sts_fd, xadc_fd, mem_fd, cma_fd; +void *intc_ptr, *cfg_ptr, *sts_ptr, *xadc_ptr, *mem_ptr, *cma_ptr; +uint32_t dev_size; + +void dev_write(void *dev_base, uint32_t offset, int32_t value) +{ + *((volatile unsigned *)(dev_base + offset)) = value; +} + +uint32_t dev_read(void *dev_base, uint32_t offset) +{ + return *((volatile unsigned *)(dev_base + offset)); +} + +/*int dev_init(int n_dev) + { + char *uiod; = "/dev/uio1"; + + printf("Initializing device...\n"); + +// open the UIO device file to allow access to the device in user space +cfg_fd = open(uiod, O_RDWR); +if (cfg_fd < 1) { +printf("cfg_init: Invalid UIO device file:%s.\n", uiod); +return -1; +} + +dev_size = get_memory_size("/sys/class/uio/uio1/maps/map0/size"); + +// mmap the cfgC device into user space +cfg_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, cfg_fd, 0); +if (cfg_ptr == MAP_FAILED) { +printf("cfg_init: mmap call failure.\n"); +return -1; +} + +return 0; +}*/ + +int32_t rd_reg_value(int n_dev, uint32_t reg_off) +{ + int32_t reg_val; + switch(n_dev) + { + case 0: + reg_val = dev_read(intc_ptr, reg_off); + break; + case 1: + reg_val = dev_read(cfg_ptr, reg_off); + break; + case 2: + reg_val = dev_read(sts_ptr, reg_off); + break; + case 3: + reg_val = dev_read(xadc_ptr, reg_off); + break; + default: + printf("Invalid option: %d\n", n_dev); + return -1; + } + printf("Complete. Received data 0x%08x\n", reg_val); + //printf("Complete. Received data %d\n", reg_val); + + return reg_val; +} + +int32_t wr_reg_value(int n_dev, uint32_t reg_off, int32_t reg_val) +{ + switch(n_dev) + { + case 0: + dev_write(intc_ptr, reg_off, reg_val); + break; + case 1: + dev_write(cfg_ptr, reg_off, reg_val); + break; + case 2: + dev_write(sts_ptr, reg_off, reg_val); + break; + case 3: + dev_write(xadc_ptr, reg_off, reg_val); + break; + default: + printf("Invalid option: %d\n", n_dev); + return -1; + } + printf("Complete. Data written: 0x%08x\n", reg_val); + //printf("Complete. Data written: %d\n", reg_val); + + return 0; +} + +int32_t rd_cfg_status(void) +{ + //float a = 0.0382061, b = 4.11435; // For gain = 1.45 + float a = 0.0882006, b = 7.73516; // For gain = 3.2 + + printf("#Trigger Level Ch1 = %d\n", dev_read(cfg_ptr, CFG_TRLVL_1_OFFSET)); + printf("#Trigger Level Ch2 = %d\n", dev_read(cfg_ptr, CFG_TRLVL_2_OFFSET)); + //printf("#Subtrigger Ch1 = %d\n", dev_read(cfg_ptr, CFG_STRLVL_1_OFFSET)); + //printf("#Subtrigger Ch2 = %d\n", dev_read(cfg_ptr, CFG_STRLVL_2_OFFSET)); + printf("#High Voltage 1 = %.1f mV\n", a*dev_read(cfg_ptr, CFG_HV1_OFFSET)+b); + printf("#High Voltage 2 = %.1f mV\n", a*dev_read(cfg_ptr, CFG_HV2_OFFSET)+b); + printf("#Trigger Scaler 1 = %d\n", dev_read(cfg_ptr, CFG_TR_SCAL_A_OFFSET)); + printf("#Trigger Scaler 2 = %d\n", dev_read(cfg_ptr, CFG_TR_SCAL_B_OFFSET)); + if (((dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET)>>4) & 0x1) == 1) { // No GPS is present + printf("#No GPS device is present or enabled\n"); + }else{ + printf("#Using GPS data\n"); + } + if (((dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET)>>5) & 0x1) == 0) //Slave + { + printf("#Working mode is SLAVE\n"); + }else{ + printf("#Working mode is MASTER\n"); + } + printf("\n"); + printf("Status from registers complete!\n"); + return 0; +} + +static uint32_t get_memory_size(char *sysfs_path_file) +{ + FILE *size_fp; + uint32_t size; + + // open the file that describes the memory range size that is based on + // the reg property of the node in the device tree + size_fp = fopen(sysfs_path_file, "r"); + + if (!size_fp) { + printf("unable to open the uio size file\n"); + exit(-1); + } + + // get the size which is an ASCII string such as 0xXXXXXXXX and then be + // stop using the file + if(fscanf(size_fp, "0x%08X", &size) == EOF){ + printf("unable to get the size of the uio size file\n"); + exit(-1); + } + fclose(size_fp); + + return size; +} + +int intc_init(void) +{ + char *uiod = "/dev/uio0"; + + //printf("Initializing INTC device...\n"); + + // open the UIO device file to allow access to the device in user space + intc_fd = open(uiod, O_RDWR); + if (intc_fd < 1) { + printf("intc_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio0/maps/map0/size"); + + // mmap the INTC device into user space + intc_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, intc_fd, 0); + if (intc_ptr == MAP_FAILED) { + printf("intc_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int cfg_init(void) +{ + char *mem_name = "/dev/mem"; + + //printf("Initializing CFG device...\n"); + + // open the CFG device file to allow access to the device in user space + cfg_fd = open(mem_name, O_RDWR); + if (cfg_fd < 1) { + printf("cfg_init: Invalid memory device file:%s.\n", mem_name); + return -1; + } + + dev_size = sysconf(_SC_PAGESIZE); + + // mmap the cfg device into user space + cfg_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, cfg_fd, CFG_BASEADDR); + if (cfg_ptr == MAP_FAILED) { + printf("cfg_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int sts_init(void) +{ + char *uiod = "/dev/uio2"; + + //printf("Initializing STS device...\n"); + + // open the UIO device file to allow access to the device in user space + sts_fd = open(uiod, O_RDWR); + if (sts_fd < 1) { + printf("sts_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio2/maps/map0/size"); + + // mmap the STS device into user space + sts_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, sts_fd, 0); + if (sts_ptr == MAP_FAILED) { + printf("sts_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int xadc_init(void) +{ + char *uiod = "/dev/uio3"; + + //printf("Initializing XADC device...\n"); + + // open the UIO device file to allow access to the device in user space + xadc_fd = open(uiod, O_RDWR); + if (xadc_fd < 1) { + printf("xadc_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio3/maps/map0/size"); + + // mmap the XADC device into user space + xadc_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, xadc_fd, 0); + if (xadc_ptr == MAP_FAILED) { + printf("xadc_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int mem_init(void) +{ + char *mem_name = "/dev/mem"; + + //printf("Initializing mem device...\n"); + + // open the UIO device file to allow access to the device in user space + mem_fd = open(mem_name, O_RDWR); + if (mem_fd < 1) { + printf("mem_init: Invalid device file:%s.\n", mem_name); + return -1; + } + + dev_size = 2048*sysconf(_SC_PAGESIZE); + + // mmap the mem device into user space + mem_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0x1E000000); + if (mem_ptr == MAP_FAILED) { + printf("mem_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int cma_init(void) +{ + char *cma_name = "/dev/cma"; + + //printf("Initializing mem device...\n"); + + // open the UIO device file to allow access to the device in user space + cma_fd = open(cma_name, O_RDWR); + if (cma_fd < 1) { + printf("cma_init: Invalid device file:%s.\n", cma_name); + return -1; + } + + dev_size = 1024*sysconf(_SC_PAGESIZE); + + if(ioctl(cma_fd, CMA_ALLOC, &dev_size) < 0) { + perror("ioctl"); + return EXIT_FAILURE; + } + // mmap the mem device into user space + cma_ptr = mmap(NULL, 1024*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, cma_fd, 0); + if (cma_ptr == MAP_FAILED) { + printf("cma_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +float get_voltage(uint32_t offset) +{ + int16_t value; + value = (int16_t) dev_read(xadc_ptr, offset); + // printf("The Voltage is: %lf V\n", (value>>4)*XADC_CONV_VAL); + return ((value>>4)*XADC_CONV_VAL); +} + +/*void set_voltage(uint32_t offset, int32_t value) + { +//fit after calibration. See file data_calib.txt in /ramp_test directory +// y = a*x + b +//a = 0.0382061 +//b = 4.11435 +uint32_t dac_val; +float a = 0.0382061, b = 4.11435; + +dac_val = (uint32_t)(value - b)/a; + +dev_write(cfg_ptr, offset, dac_val); +printf("The Voltage is: %d mV\n", value); +printf("The DAC value is: %d DACs\n", dac_val); +} +*/ + +void set_voltage(uint32_t offset, int32_t value) +{ + //fit after calibration. See file data_calib2.txt in /ramp_test directory + // y = a*x + b + //a = 0.0882006 + //b = 7.73516 + uint32_t dac_val; + float a = 0.0882006, b = 7.73516; + + dac_val = (uint32_t)(value - b)/a; + + dev_write(cfg_ptr, offset, dac_val); + printf("The Voltage is: %d mV\n", value); + printf("The DAC value is: %d DACs\n", dac_val); +} + +float get_temp_AD592(uint32_t offset) +{ + float value; + value = get_voltage(offset); + return ((value*1000)-273.15); +} + +//System initialization +int init_system(void) +{ + uint32_t reg_val; + + //FIXME: replace hardcoded values for defines + // set trigger_lvl_1 + dev_write(cfg_ptr,CFG_TRLVL_1_OFFSET,8190); + + // set trigger_lvl_2 + dev_write(cfg_ptr,CFG_TRLVL_2_OFFSET,8190); + + // set subtrigger_lvl_1 + dev_write(cfg_ptr,CFG_STRLVL_1_OFFSET,8190); + + // set subtrigger_lvl_2 + dev_write(cfg_ptr,CFG_STRLVL_2_OFFSET,8190); + + // set hv1 and hv2 to zero + dev_write(cfg_ptr,CFG_HV1_OFFSET,0); + dev_write(cfg_ptr,CFG_HV2_OFFSET,0); + + // reset ramp generators + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~8); + + // reset pps_gen, fifo and trigger modules + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~1); + + /* reset data converter and writer */ + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~4); + + // enter reset mode for tlast_gen + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~2); + + // set number of samples + dev_write(cfg_ptr,CFG_NSAMPLES_OFFSET, 1024 * 1024); + + // set default value for trigger scalers a and b + dev_write(cfg_ptr,CFG_TR_SCAL_A_OFFSET, 1); + dev_write(cfg_ptr,CFG_TR_SCAL_B_OFFSET, 1); + + // enter normal mode for tlast_gen + /* reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 2); + //printf("written reg_val tlast : 0x%08x\n",reg_val | 2); + // enter normal mode for pps_gen, fifo and trigger modules + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 1); + //printf("written reg_val pps_gen, fifo : 0x%08x\n",reg_val | 1); + */ + // enable false GPS + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | FGPS_EN_MASK); + //printf("written reg_val : 0x%08x\n",reg_val | 16); + // disable + //dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~16); + //dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~FGPS_EN_MASK); + //printf("written reg_val : 0x%08x\n",reg_val & ~16); + + /* // enter normal mode for data converter and writer + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 4); + //printf("written reg_val : 0x%08hx\n",reg_val | 4); + */ + // enter normal mode for ramp generators + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 8); + // enter in MASTER mode (default) + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 0x20); + + return 0; +} + +int enable_interrupt(void) +{ + // steps to accept interrupts -> as pg. 26 of pg099-axi-intc.pdf + //1) Each bit in the IER corresponding to an interrupt must be set to 1. + dev_write(intc_ptr,XIL_AXI_INTC_IER_OFFSET, 1); + //2) There are two bits in the MER. The ME bit must be set to enable the + //interrupt request outputs. + dev_write(intc_ptr,XIL_AXI_INTC_MER_OFFSET, XIL_AXI_INTC_MER_ME_MASK | XIL_AXI_INTC_MER_HIE_MASK); + //dev_write(dev_ptr,XIL_AXI_INTC_MER_OFFSET, XIL_AXI_INTC_MER_ME_MASK); + + //The next block of code is to test interrupts by software + //3) Software testing can now proceed by writing a 1 to any bit position + //in the ISR that corresponds to an existing interrupt input. + /* dev_write(intc_ptr,XIL_AXI_INTC_IPR_OFFSET, 1); + + for(a=0; a<10; a++) + { + wait_for_interrupt(fd, dev_ptr); + dev_write(dev_ptr,XIL_AXI_INTC_ISR_OFFSET, 1); //regenerate interrupt + } + */ + return 0; + +} + +int disable_interrupt(void) +{ + uint32_t value; + //Disable interrupt INTC0 + dev_write(intc_ptr,XIL_AXI_INTC_IER_OFFSET, 0); + //disable IRQ + value = dev_read(intc_ptr, XIL_AXI_INTC_MER_OFFSET); + dev_write(intc_ptr,XIL_AXI_INTC_MER_OFFSET, value | ~1); + //Acknowledge any previous interrupt + dev_write(intc_ptr, XIL_AXI_INTC_IAR_OFFSET, 1); + + return 0; +} + diff --git a/projects/adc_recorder/src/zynq_io.h b/projects/adc_recorder/src/zynq_io.h new file mode 100644 index 0000000..b430eb3 --- /dev/null +++ b/projects/adc_recorder/src/zynq_io.h @@ -0,0 +1,154 @@ +#ifndef _ZYNQ_IO_H_ +#define _ZYNQ_IO_H_ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/ioctl.h> + +#define CMA_ALLOC _IOWR('Z', 0, uint32_t) +#define INTC_BASEADDR 0x40000000 +#define INTC_HIGHADDR 0x40000FFF + +#define CFG_BASEADDR 0x40000000 +#define CFG_HIGHADDR 0x40000FFF + +#define STS_BASEADDR 0x40002000 +#define STS_HIGHADDR 0x40002FFF + +#define XADC_BASEADDR 0x40003000 +#define XADC_HIGHADDR 0x40003FFF + +#define XIL_AXI_INTC_ISR_OFFSET 0x0 +#define XIL_AXI_INTC_IPR_OFFSET 0x4 +#define XIL_AXI_INTC_IER_OFFSET 0x8 +#define XIL_AXI_INTC_IAR_OFFSET 0xC +#define XIL_AXI_INTC_SIE_OFFSET 0x10 +#define XIL_AXI_INTC_CIE_OFFSET 0x14 +#define XIL_AXI_INTC_IVR_OFFSET 0x18 +#define XIL_AXI_INTC_MER_OFFSET 0x1C +#define XIL_AXI_INTC_IMR_OFFSET 0x20 +#define XIL_AXI_INTC_ILR_OFFSET 0x24 +#define XIL_AXI_INTC_IVAR_OFFSET 0x100 + +#define XIL_AXI_INTC_MER_ME_MASK 0x00000001 +#define XIL_AXI_INTC_MER_HIE_MASK 0x00000002 + +//CFG +#define CFG_RESET_GRAL_OFFSET 0x0 +#define CFG_WR_ADDR_OFFSET 0x4 +#define CFG_NSAMPLES_OFFSET 0x8 +#define CFG_TRLVL_1_OFFSET 0x8 +#define CFG_TRLVL_2_OFFSET 0xC +#define CFG_STRLVL_1_OFFSET 0x10 +#define CFG_STRLVL_2_OFFSET 0x14 +#define CFG_TEMPERATURE_OFFSET 0x18 +#define CFG_PRESSURE_OFFSET 0x1C +#define CFG_TIME_OFFSET 0x20 +#define CFG_DATE_OFFSET 0x24 +#define CFG_LATITUDE_OFFSET 0x28 +#define CFG_LONGITUDE_OFFSET 0x2C +#define CFG_ALTITUDE_OFFSET 0x30 +#define CFG_SATELLITE_OFFSET 0x34 +#define CFG_TR_SCAL_A_OFFSET 0x38 +#define CFG_TR_SCAL_B_OFFSET 0x3C +#define CFG_HV1_OFFSET 0x4C //DAC_PWM3 +#define CFG_HV2_OFFSET 0x48 //DAC_PWM2 +#define CFG_HV3_OFFSET 0x40 //DAC_PWM0 +#define CFG_HV4_OFFSET 0x44 //DAC_PWM1 + +//CFG Slow DAC +#define CFG_DAC_PWM0_OFFSET 0x40 +#define CFG_DAC_PWM1_OFFSET 0x44 +#define CFG_DAC_PWM2_OFFSET 0x48 +#define CFG_DAC_PWM3_OFFSET 0x4C + +#define ENBL_ALL_MASK 0xFFFFFFFF +#define RST_ALL_MASK 0x00000000 +#define RST_PPS_TRG_FIFO_MASK 0x00000001 +#define RST_TLAST_GEN_MASK 0x00000002 +#define RST_WRITER_MASK 0x00000004 +#define RST_AO_MASK 0x00000008 +#define FGPS_EN_MASK 0x00000010 + +//STS +#define STS_STATUS_OFFSET 0x0 + +//XADC +//See page 17 of PG091 +#define XADC_SRR_OFFSET 0x00 //Software reset register +#define XADC_SR_OFFSET 0x04 //Status Register +#define XADC_AOSR_OFFSET 0x08 //Alarm Out Status Register +#define XADC_CONVSTR_OFFSET 0x0C //CONVST Register +#define XADC_SYSMONRR_OFFSET 0x10 //XADC Reset Register +#define XADC_GIER_OFFSET 0x5C //Global Interrupt Enable Register +#define XADC_IPISR_OFFSET 0x60 //IP Interrupt Status Register +#define XADC_IPIER_OFFSET 0x68 //IP Interrupt Enable Register +#define XADC_TEMPERATURE_OFFSET 0x200 //Temperature +#define XADC_VCCINT_OFFSET 0x204 //VCCINT +#define XADC_VCCAUX_OFFSET 0x208 //VCCAUX +#define XADC_VPVN_OFFSET 0x20C //VP/VN +#define XADC_VREFP_OFFSET 0x210 //VREFP +#define XADC_VREFN_OFFSET 0x214 //VREFN +#define XADC_VBRAM_OFFSET 0x218 //VBRAM +#define XADC_UNDEF_OFFSET 0x21C //Undefined +#define XADC_SPLYOFF_OFFSET 0x220 //Supply Offset +#define XADC_ADCOFF_OFFSET 0x224 //ADC Offset +#define XADC_GAIN_ERR_OFFSET 0x228 //Gain Error +#define XADC_ZDC_SPLY_OFFSET 0x234 //Zynq-7000 Device Core Supply +#define XADC_ZDC_AUX_SPLY_OFFSET 0x238 //Zynq-7000 Device Core Aux Supply +#define XADC_ZDC_MEM_SPLY_OFFSET 0x23C //Zynq-7000 Device Core Memory Supply +#define XADC_VAUX_PN_0_OFFSET 0x240 //VAUXP[0]/VAUXN[0] +#define XADC_VAUX_PN_1_OFFSET 0x244 //VAUXP[1]/VAUXN[1] +#define XADC_VAUX_PN_2_OFFSET 0x248 //VAUXP[2]/VAUXN[2] +#define XADC_VAUX_PN_3_OFFSET 0x24C //VAUXP[3]/VAUXN[3] +#define XADC_VAUX_PN_4_OFFSET 0x250 //VAUXP[4]/VAUXN[4] +#define XADC_VAUX_PN_5_OFFSET 0x254 //VAUXP[5]/VAUXN[5] +#define XADC_VAUX_PN_6_OFFSET 0x258 //VAUXP[6]/VAUXN[6] +#define XADC_VAUX_PN_7_OFFSET 0x25C //VAUXP[7]/VAUXN[7] +#define XADC_VAUX_PN_8_OFFSET 0x260 //VAUXP[8]/VAUXN[8] +#define XADC_VAUX_PN_9_OFFSET 0x264 //VAUXP[9]/VAUXN[9] +#define XADC_VAUX_PN_10_OFFSET 0x268 //VAUXP[10]/VAUXN[10] +#define XADC_VAUX_PN_11_OFFSET 0x26C //VAUXP[11]/VAUXN[11] +#define XADC_VAUX_PN_12_OFFSET 0x270 //VAUXP[12]/VAUXN[12] +#define XADC_VAUX_PN_13_OFFSET 0x274 //VAUXP[13]/VAUXN[13] +#define XADC_VAUX_PN_14_OFFSET 0x278 //VAUXP[14]/VAUXN[14] +#define XADC_VAUX_PN_15_OFFSET 0x27C //VAUXP[15]/VAUXN[15] + +#define XADC_AI0_OFFSET XADC_VAUX_PN_8_OFFSET +#define XADC_AI1_OFFSET XADC_VAUX_PN_0_OFFSET +#define XADC_AI2_OFFSET XADC_VAUX_PN_1_OFFSET +#define XADC_AI3_OFFSET XADC_VAUX_PN_9_OFFSET + +#define XADC_CONV_VAL 0.00171191993362 //(A_ip/2^12)*(34.99/4.99) +#define XADC_RDIV_VAL 1.883236177 //voltage divisor in board (15k+16.983k)/16.983k = 1.88 +#define XADC_BASE_HVDIV 0.00294088 //voltage divisor in HV base board (100k/31.3Meg) = 3.194888179. The value I put here is the measured one. + +extern int intc_fd, cfg_fd, sts_fd, xadc_fd, mem_fd, cma_fd; +extern void *intc_ptr, *cfg_ptr, *sts_ptr, *xadc_ptr, *mem_ptr, *cma_ptr; +extern uint32_t dev_size; + +void dev_write(void *dev_base, uint32_t offset, int32_t value); +uint32_t dev_read(void *dev_base, uint32_t offset); +//int dev_init(int n_dev); +int32_t rd_reg_value(int n_dev, uint32_t reg_off); +int32_t wr_reg_value(int n_dev, uint32_t reg_off, int32_t reg_val); +int32_t rd_cfg_status(void); +int intc_init(void); +int cfg_init(void); +int sts_init(void); +int xadc_init(void); +int mem_init(void); +int cma_init(void); +float get_voltage(uint32_t offset); +void set_voltage(uint32_t offset, int32_t value); +float get_temp_AD592(uint32_t offset); +int init_system(void); +int enable_interrupt(void); +int disable_interrupt(void); + +#endif + diff --git a/projects/adc_recorder_uio/adc-recorder.c b/projects/adc_recorder_uio/adc-recorder.c new file mode 100644 index 0000000..e409e86 --- /dev/null +++ b/projects/adc_recorder_uio/adc-recorder.c @@ -0,0 +1,81 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/ioctl.h> + +#define CMA_ALLOC _IOWR('Z', 0, uint32_t) + +int main() +{ + int fd, i; + volatile uint8_t *rst; + volatile void *cfg; + volatile int16_t *ram; + uint32_t size; + int16_t value[2]; + + if((fd = open("/dev/mem", O_RDWR)) < 0) + { + perror("open"); + return EXIT_FAILURE; + } + + cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40001000); + + close(fd); + + if((fd = open("/dev/cma", O_RDWR)) < 0) + { + perror("open"); + return EXIT_FAILURE; + } + + size = 1024*sysconf(_SC_PAGESIZE); + + if(ioctl(fd, CMA_ALLOC, &size) < 0) + { + perror("ioctl"); + return EXIT_FAILURE; + } + + ram = mmap(NULL, 1024*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + + rst = (uint8_t *)(cfg + 0); + + // set writer address + *(uint32_t *)(cfg + 4) = size; + + // set number of samples + *(uint32_t *)(cfg + 8) = 1024 * 1024 - 1; + + // reset writer + *rst &= ~4; + *rst |= 4; + + // reset fifo and filters + *rst &= ~1; + *rst |= 1; + + // wait 1 second + sleep(1); + + // reset packetizer + *rst &= ~2; + *rst |= 2; + + // wait 1 second + sleep(1); + + // print IN1 and IN2 samples + for(i = 0; i < 1024 * 1024; ++i) + { + value[0] = ram[2 * i + 0]; + value[1] = ram[2 * i + 1]; + printf("%5d %5d\n", value[0], value[1]); + } + + return EXIT_SUCCESS; +} diff --git a/projects/adc_recorder_uio/block_design.tcl b/projects/adc_recorder_uio/block_design.tcl new file mode 100644 index 0000000..55c74e0 --- /dev/null +++ b/projects/adc_recorder_uio/block_design.tcl @@ -0,0 +1,241 @@ +# Create clk_wiz +cell xilinx.com:ip:clk_wiz pll_0 { + PRIMITIVE PLL + PRIM_IN_FREQ.VALUE_SRC USER + PRIM_IN_FREQ 125.0 + PRIM_SOURCE Differential_clock_capable_pin + CLKOUT1_USED true + CLKOUT1_REQUESTED_OUT_FREQ 125.0 + USE_RESET false +} { + clk_in1_p adc_clk_p_i + clk_in1_n adc_clk_n_i +} + +# Create processing_system7 +cell xilinx.com:ip:processing_system7 ps_0 { + PCW_IMPORT_BOARD_PRESET cfg/red_pitaya.xml + PCW_USE_S_AXI_ACP 1 + PCW_USE_DEFAULT_ACP_USER_VAL 1 +} { + M_AXI_GP0_ACLK pll_0/clk_out1 + S_AXI_ACP_ACLK pll_0/clk_out1 +} + +# Create all required interconnections +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config { + make_external {FIXED_IO, DDR} + Master Disable + Slave Disable +} [get_bd_cells ps_0] + +# Create xlconstant +cell xilinx.com:ip:xlconstant const_0 + +# Create proc_sys_reset +cell xilinx.com:ip:proc_sys_reset rst_0 {} { + ext_reset_in const_0/dout +} + +# GPIO + +# Delete input/output port +delete_bd_objs [get_bd_ports exp_p_tri_io] + +# Create output port +create_bd_port -dir O -from 7 -to 0 exp_p_tri_io + +# ADC + +# Create axis_red_pitaya_adc +cell labdpr:user:axis_rp_adc adc_0 { + ADC_DATA_WIDTH 14 +} { + aclk pll_0/clk_out1 + adc_dat_a adc_dat_a_i + adc_dat_b adc_dat_b_i + adc_csn adc_csn_o +} + +# Create axi_cfg_register +cell labdpr:user:axi_cfg_register cfg_0 { + CFG_DATA_WIDTH 96 + AXI_ADDR_WIDTH 32 + AXI_DATA_WIDTH 32 +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_0 { + DIN_WIDTH 96 DIN_FROM 0 DIN_TO 0 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_1 { + DIN_WIDTH 96 DIN_FROM 1 DIN_TO 1 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_2 { + DIN_WIDTH 96 DIN_FROM 2 DIN_TO 2 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_3 { + DIN_WIDTH 96 DIN_FROM 63 DIN_TO 32 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_4 { + DIN_WIDTH 96 DIN_FROM 95 DIN_TO 64 +} { + din cfg_0/cfg_data +} + +# Create util_vector_logic +cell xilinx.com:ip:util_vector_logic not_0 { + C_SIZE 1 + C_OPERATION not +} { + Op1 slice_1/dout +} + +# Create xlconcat +cell xilinx.com:ip:xlconcat concat_0 { + NUM_PORTS 2 + IN0_WIDTH 1 + IN1_WIDTH 7 +} { + In0 not_0/Res + dout exp_p_tri_io +} + +# Create axis_broadcaster +cell xilinx.com:ip:axis_broadcaster bcast_0 { + S_TDATA_NUM_BYTES.VALUE_SRC USER + M_TDATA_NUM_BYTES.VALUE_SRC USER + S_TDATA_NUM_BYTES 4 + M_TDATA_NUM_BYTES 2 + M00_TDATA_REMAP {tdata[15:0]} + M01_TDATA_REMAP {tdata[31:16]} +} { + S_AXIS adc_0/M_AXIS + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +# Create cic_compiler +cell xilinx.com:ip:cic_compiler cic_0 { + INPUT_DATA_WIDTH.VALUE_SRC USER + FILTER_TYPE Decimation + NUMBER_OF_STAGES 6 + FIXED_OR_INITIAL_RATE 32 + INPUT_SAMPLE_FREQUENCY 125 + CLOCK_FREQUENCY 125 + INPUT_DATA_WIDTH 14 + QUANTIZATION Truncation + OUTPUT_DATA_WIDTH 16 + USE_XTREME_DSP_SLICE true + HAS_ARESETN true +} { + S_AXIS_DATA bcast_0/M00_AXIS + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# Create cic_compiler +cell xilinx.com:ip:cic_compiler cic_1 { + INPUT_DATA_WIDTH.VALUE_SRC USER + FILTER_TYPE Decimation + NUMBER_OF_STAGES 6 + FIXED_OR_INITIAL_RATE 32 + INPUT_SAMPLE_FREQUENCY 125 + CLOCK_FREQUENCY 125 + INPUT_DATA_WIDTH 14 + QUANTIZATION Truncation + OUTPUT_DATA_WIDTH 16 + USE_XTREME_DSP_SLICE true + HAS_ARESETN true +} { + S_AXIS_DATA bcast_0/M01_AXIS + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# Create axis_combiner +cell xilinx.com:ip:axis_combiner comb_0 { + TDATA_NUM_BYTES.VALUE_SRC USER + TDATA_NUM_BYTES 2 +} { + S00_AXIS cic_0/M_AXIS_DATA + S01_AXIS cic_1/M_AXIS_DATA + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +# Create fir_compiler +cell xilinx.com:ip:fir_compiler fir_0 { + DATA_WIDTH.VALUE_SRC USER + DATA_WIDTH 16 + COEFFICIENTVECTOR {-1.64753028794138e-08, -4.72969860103254e-08, -7.81983994864729e-10, 3.09179315378013e-08, 1.8600476137934e-08, 3.27300695910419e-08, -6.27121813377163e-09, -1.52196115352429e-07, -8.30377969926702e-08, 3.14361841397898e-07, 3.05515872274853e-07, -4.73906648324436e-07, -7.13188274738437e-07, 5.47004771774003e-07, 1.33401100809314e-06, -4.13867548024707e-07, -2.14949555259695e-06, -6.77977800948474e-08, 3.07398932714553e-06, 1.0366230107463e-06, -3.94245232963009e-06, -2.59076839821521e-06, 4.51317323767107e-06, 4.74563996488482e-06, -4.49064349142054e-06, -7.3947777960083e-06, 3.57041197419745e-06, 1.02846684426837e-05, -1.50308472093842e-06, -1.30146997163052e-05, -1.8311731233767e-06, 1.50710364353895e-05, 6.3515248701083e-06, -1.58982472678568e-05, -1.17267343142635e-05, 1.50041199296265e-05, 1.73635115814309e-05, -1.20890304109726e-05, -2.24560062957254e-05, 7.16700059796055e-06, 2.60907689345942e-05, -6.64193032293714e-07, -2.74163749798938e-05, -6.54632074532538e-06, 2.5852558776971e-05, 1.31966582845397e-05, -2.13079073598636e-05, -1.77801135294917e-05, 1.43611952054032e-05, 1.88093817512436e-05, -6.35698021047062e-06, -1.51543007857966e-05, -6.31269475321274e-07, 6.41236246473726e-06, 4.00235076480002e-06, 6.75384652715119e-06, -1.00102812372645e-06, -2.23907547607786e-05, -1.07614170164429e-05, 3.72128949266483e-05, 3.26888314865614e-05, -4.68343172264928e-05, -6.46247522446593e-05, 4.62331324663801e-05, 0.000104353987875991, -3.05204178369922e-05, -0.000147387572103254, -4.12376672483791e-06, 0.000187096070793206, 5.94492160104715e-05, -0.000215270553995213, -0.000134242574203586, 0.000223115373945588, 0.000223732063932204, -0.000202601585158347, -0.000319473722277179, 0.000148023831554525, 0.000409856470754451, -5.75319241913947e-05, -0.00048128691789378, -6.56435551088113e-05, 0.000520005389882914, 0.000212559310978688, -0.000514378040456993, -0.000368824791639381, 0.000457257636791032, 0.00051572189965271, -0.000348325111720936, -0.000632574861580132, 0.000195575644936742, 0.000699853643923955, -1.5816811333843e-05, -0.000702875004558909, -0.000166267212059945, 0.000635554670416145, 0.000320646045613507, -0.000503596369030625, -0.000416023690327203, 0.000326453158345306, 0.00042516016658693, -0.000137454215410763, -0.000330867755122004, -1.83577770104995e-05, 0.000131884375290827, 8.88732824246191e-05, 0.000152320700965935, -2.19145324792827e-05, -0.000478845867687744, -0.000226130995959082, 0.000781165284659716, 0.000680083599509367, -0.000973297239795462, -0.00133684955123469, 0.000956951103249511, 0.00215724393391554, -0.000632647805407322, -0.00306094569410801, -8.63474252426424e-05, 0.00392560461099799, 0.00125840455441931, -0.00459097537930345, -0.00289777037472875, 0.00486843895178868, 0.00496041688761007, -0.00455566278421732, -0.0073332195556104, 0.00345548961533671, 0.00982788076765724, -0.0013975392826423, -0.0121803938743171, -0.00173944634676796, 0.0140556603140014, 0.00600554245501628, -0.0150585666700821, -0.0113645359721422, 0.0147416608531572, 0.0176785888467245, -0.0126130926725902, -0.0247012339350495, 0.00812796467212303, 0.0320712315374266, -0.000646259298618774, -0.0392988478933562, -0.0106852885932714, 0.0457163887873562, 0.0272344645510023, -0.0503010855018923, -0.0516879242105393, 0.0510032995068897, 0.0905252892059647, -0.0416077244968566, -0.163677972614864, -0.0107434888500177, 0.356350050991766, 0.554721342376512, 0.356350050991766, -0.0107434888500177, -0.163677972614864, -0.0416077244968565, 0.0905252892059646, 0.0510032995068897, -0.0516879242105392, -0.0503010855018923, 0.0272344645510023, 0.0457163887873562, -0.0106852885932714, -0.0392988478933562, -0.000646259298618766, 0.0320712315374266, 0.008127964672123, -0.0247012339350495, -0.0126130926725902, 0.0176785888467245, 0.0147416608531572, -0.0113645359721422, -0.0150585666700821, 0.00600554245501627, 0.0140556603140014, -0.00173944634676796, -0.0121803938743171, -0.0013975392826423, 0.00982788076765723, 0.00345548961533672, -0.0073332195556104, -0.00455566278421732, 0.00496041688761004, 0.00486843895178868, -0.00289777037472874, -0.00459097537930345, 0.00125840455441931, 0.003925604610998, -8.6347425242651e-05, -0.00306094569410801, -0.000632647805407327, 0.00215724393391554, 0.000956951103249513, -0.00133684955123469, -0.000973297239795458, 0.00068008359950937, 0.000781165284659718, -0.000226130995959085, -0.000478845867687734, -2.19145324792814e-05, 0.000152320700965923, 8.88732824246168e-05, 0.000131884375290828, -1.83577770104952e-05, -0.000330867755122008, -0.000137454215410769, 0.000425160166586931, 0.000326453158345309, -0.000416023690327193, -0.000503596369030629, 0.000320646045613497, 0.000635554670416148, -0.000166267212059939, -0.000702875004558908, -1.58168113338674e-05, 0.000699853643923955, 0.000195575644936758, -0.000632574861580132, -0.000348325111720941, 0.000515721899652708, 0.000457257636791035, -0.000368824791639379, -0.000514378040456997, 0.000212559310978687, 0.000520005389882915, -6.56435551088096e-05, -0.000481286917893776, -5.7531924191395e-05, 0.000409856470754451, 0.000148023831554525, -0.000319473722277176, -0.000202601585158348, 0.000223732063932204, 0.000223115373945587, -0.000134242574203588, -0.000215270553995212, 5.944921601047e-05, 0.000187096070793206, -4.12376672483805e-06, -0.000147387572103254, -3.05204178369924e-05, 0.000104353987875991, 4.62331324663777e-05, -6.46247522446589e-05, -4.68343172264921e-05, 3.26888314865612e-05, 3.72128949266458e-05, -1.07614170164428e-05, -2.23907547607785e-05, -1.0010281237264e-06, 6.7538465271515e-06, 4.00235076480007e-06, 6.41236246473652e-06, -6.31269475321259e-07, -1.5154300785797e-05, -6.35698021047036e-06, 1.88093817512439e-05, 1.43611952054029e-05, -1.77801135294911e-05, -2.13079073598635e-05, 1.31966582845395e-05, 2.58525587769708e-05, -6.54632074532428e-06, -2.74163749798938e-05, -6.64193032294061e-07, 2.60907689345942e-05, 7.16700059796085e-06, -2.24560062957254e-05, -1.20890304109726e-05, 1.7363511581431e-05, 1.50041199296266e-05, -1.17267343142635e-05, -1.58982472678571e-05, 6.3515248701082e-06, 1.50710364353894e-05, -1.83117312337678e-06, -1.30146997163053e-05, -1.50308472093845e-06, 1.02846684426836e-05, 3.57041197419745e-06, -7.39477779600816e-06, -4.49064349142055e-06, 4.74563996488478e-06, 4.51317323767109e-06, -2.59076839821518e-06, -3.94245232963005e-06, 1.03662301074629e-06, 3.07398932714552e-06, -6.77977800948646e-08, -2.14949555259695e-06, -4.13867548024735e-07, 1.33401100809314e-06, 5.47004771773993e-07, -7.13188274738437e-07, -4.73906648324394e-07, 3.05515872274853e-07, 3.14361841397861e-07, -8.30377969926656e-08, -1.5219611535243e-07, -6.27121813377245e-09, 3.27300695910341e-08, 1.86004761379317e-08, 3.0917931537805e-08, -7.81983994865244e-10, -4.72969860103212e-08, -1.64753028794135e-08} + COEFFICIENT_WIDTH 16 + QUANTIZATION Quantize_Only + BESTPRECISION true + FILTER_TYPE Decimation + DECIMATION_RATE 2 + NUMBER_PATHS 2 + RATESPECIFICATION Input_Sample_Period + SAMPLEPERIOD 32 + OUTPUT_ROUNDING_MODE Truncate_LSBs + OUTPUT_WIDTH 16 + HAS_ARESETN true +} { + S_AXIS_DATA comb_0/M_AXIS + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# Create axis_packetizer +cell labdpr:user:axis_packetizer pktzr_0 { + AXIS_TDATA_WIDTH 32 + CNTR_WIDTH 32 + CONTINUOUS FALSE +} { + S_AXIS fir_0/M_AXIS_DATA + cfg_data slice_4/dout + aclk pll_0/clk_out1 + aresetn slice_1/dout +} + +# Create axis_dwidth_converter +cell xilinx.com:ip:axis_dwidth_converter conv_0 { + S_TDATA_NUM_BYTES.VALUE_SRC USER + S_TDATA_NUM_BYTES 4 + M_TDATA_NUM_BYTES 8 +} { + S_AXIS pktzr_0/M_AXIS + aclk pll_0/clk_out1 + aresetn slice_2/dout +} + +# Create axis_ram_writer +cell labdpr:user:axis_ram_writer writer_0 { + ADDR_WIDTH 22 + AXI_ID_WIDTH 3 +} { + S_AXIS conv_0/M_AXIS + M_AXI ps_0/S_AXI_ACP + cfg_data slice_3/dout + aclk pll_0/clk_out1 + aresetn slice_2/dout +} + +addr 0x40001000 4K cfg_0/S_AXI /ps_0/M_AXI_GP0 + diff --git a/projects/adc_recorder_uio/uio_src/Makefile b/projects/adc_recorder_uio/uio_src/Makefile new file mode 100644 index 0000000..858880d --- /dev/null +++ b/projects/adc_recorder_uio/uio_src/Makefile @@ -0,0 +1,16 @@ +CC=gcc +FLAGS=-Wall -O3 +ARCH=arm +CROSS_COMPILE=arm-xilinx-linux-gnueabi- + +#### +PROG=adc_recorder +EXTRA= zynq_io.c + +all: $(PROG) + +$(PROG): $(PROG).c $(EXTRA) + $(CC) $(FLAGS) -o $(PROG) $(PROG).c $(EXTRA) -lm -lpthread + +clean: + rm -f $(PROG) diff --git a/projects/adc_recorder_uio/uio_src/adc_recorder.c b/projects/adc_recorder_uio/uio_src/adc_recorder.c new file mode 100644 index 0000000..fb87b1a --- /dev/null +++ b/projects/adc_recorder_uio/uio_src/adc_recorder.c @@ -0,0 +1,103 @@ +#include "zynq_io.h" + +int main(int argc, char *argv[]) +{ + //int fd; + //unsigned int size; + uint32_t i,val=0; + uint32_t wo; + int16_t ch[2]; + + printf("ADC RECORDER test\n"); + + //initialize devices. TODO: add error checking + //intc_init(); + cfg_init(); + cma_init(); + //sts_init(); + //xadc_init(); + + // set writer address + // *(uint32_t *)(cfg + 4) = size; + // + printf("Set writer address...\n"); + val=rd_reg_value(1, CFG_WR_ADDR_OFFSET); + printf("dev_size es: %d ...\n",dev_size); + wr_reg_value(1, CFG_WR_ADDR_OFFSET, dev_size); + + // set number of samples + // *(uint32_t *)(cfg + 8) = 1024 * 1024 - 1; + // + printf("Set number of samples...\n"); + val=rd_reg_value(1, CFG_NSAMPLES_OFFSET); + wr_reg_value(1, CFG_NSAMPLES_OFFSET, 1024 * 1024 - 1); + + // reset writer + //*((uint32_t *)(cfg + 0)) &= ~4; + printf("Reseting writer...\n"); + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &= ~4); + //*((uint32_t *)(cfg + 0)) |= 4; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |= 4); +// printf("Reseting writer %d ...\n",val); + printf("Reseting fifo and filters...\n"); +// // reset fifo and filters + //*((uint32_t *)(cfg + 0)) &= ~1; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &=~1); +// //*((uint32_t *)(cfg + 0)) |= 1; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |=1); +// printf("Reseting fifo and filters %d ...\n",val); +// +// // wait 1 second + sleep(1); +// + printf("Reseting packetizer...\n"); + // enter reset mode for packetizer + //*((uint32_t *)(cfg + 0)) &= ~2; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &=~2); + + // set number of samples + //*((uint32_t *)(cfg + 4)) = 1024 * 1024 - 1; +// wr_reg_value(1, CFG_NSAMPLES_OFFSET, 1024 * 1024 - 1); + + // enter normal mode +// //*((uint32_t *)(cfg + 0)) |= 2; + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |=2); +// printf("Reseting packetizer %d ...\n",val); +// +// // wait 1 second + sleep(1); + + // print IN1 and IN2 samples + for(i = 0; i < 1024 * 1024; ++i){ + ch[0] = *((int16_t *)(cma_ptr + 2*i + 0)); + ch[1] = *((int16_t *)(cma_ptr + 2*i + 1)); + wo = *((uint32_t *)(cma_ptr + i)); + printf("%5d %5d %10d\n", ch[0], ch[1], wo); +// ch[0] = cma_ptr[2 * i + 0]; +// ch[1] = cma_ptr[2 * i + 1]; +// //wo = cma_ptr[i] +// printf("%5d %5d\n", ch[0], ch[1]); + } + + // unmap and close the devices + //munmap(intc_ptr, sysconf(_SC_PAGESIZE)); +// munmap(cfg_ptr, sysconf(_SC_PAGESIZE)); +// //munmap(sts_ptr, sysconf(_SC_PAGESIZE)); +// //munmap(xadc_ptr, sysconf(_SC_PAGESIZE)); +// munmap(cma_ptr, sysconf(_SC_PAGESIZE)); + + //close(intc_fd); + close(cfg_fd); + //close(sts_fd); + //close(xadc_fd); + printf("Saliendo ...\n"); + + return 0; + +} diff --git a/projects/adc_recorder_uio/uio_src/zynq_io.c b/projects/adc_recorder_uio/uio_src/zynq_io.c new file mode 100644 index 0000000..9ab308c --- /dev/null +++ b/projects/adc_recorder_uio/uio_src/zynq_io.c @@ -0,0 +1,473 @@ +#include "zynq_io.h" + +int intc_fd, cfg_fd, sts_fd, xadc_fd, mem_fd, hst0_fd, hst1_fd, cma_fd; +void *intc_ptr, *cfg_ptr, *sts_ptr, *xadc_ptr, *mem_ptr, *hst0_ptr, *hst1_ptr; +volatile int16_t *cma_ptr; +uint32_t dev_size; + +void dev_write(void *dev_base, uint32_t offset, int32_t value) +{ + *((volatile unsigned *)(dev_base + offset)) = value; +} + +uint32_t dev_read(void *dev_base, uint32_t offset) +{ + return *((volatile unsigned *)(dev_base + offset)); +} + +/*int dev_init(int n_dev) + { + char *uiod; = "/dev/uio1"; + + printf("Initializing device...\n"); + +// open the UIO device file to allow access to the device in user space +cfg_fd = open(uiod, O_RDWR); +if (cfg_fd < 1) { +printf("cfg_init: Invalid UIO device file:%s.\n", uiod); +return -1; +} + +dev_size = get_memory_size("/sys/class/uio/uio1/maps/map0/size"); + +// mmap the cfgC device into user space +cfg_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, cfg_fd, 0); +if (cfg_ptr == MAP_FAILED) { +printf("cfg_init: mmap call failure.\n"); +return -1; +} + +return 0; +}*/ + +int32_t rd_reg_value(int n_dev, uint32_t reg_off, uint8_t debug) +{ + int32_t reg_val; + switch(n_dev) + { + case 0: + reg_val = dev_read(intc_ptr, reg_off); + break; + case 1: + reg_val = dev_read(cfg_ptr, reg_off); + break; + case 2: + reg_val = dev_read(sts_ptr, reg_off); + break; + case 3: + reg_val = dev_read(xadc_ptr, reg_off); + break; + default: + printf("Invalid option: %d\n", n_dev); + return -1; + } + if(debug) + printf("Complete. Received data 0x%08x\n", reg_val); + //printf("Complete. Received data %d\n", reg_val); + + return reg_val; +} + +int32_t wr_reg_value(int n_dev, uint32_t reg_off, int32_t reg_val, uint8_t debug) +{ + switch(n_dev) + { + case 0: + dev_write(intc_ptr, reg_off, reg_val); + break; + case 1: + dev_write(cfg_ptr, reg_off, reg_val); + break; + case 2: + dev_write(sts_ptr, reg_off, reg_val); + break; + case 3: + dev_write(xadc_ptr, reg_off, reg_val); + break; + default: + printf("Invalid option: %d\n", n_dev); + return -1; + } + if(debug) + printf("Complete. Data written: 0x%08x\n", reg_val); + //printf("Complete. Data written: %d\n", reg_val); + + return 0; +} + +int32_t rd_cfg_status(void) +{ + //float a = 0.0382061, b = 4.11435; // For gain = 1.45 + float a = 0.0882006, b = 7.73516; // For gain = 3.2 + + printf("#Trigger Level Ch1 = %d\n", dev_read(cfg_ptr, CFG_TRLVL_1_OFFSET)); + printf("#Trigger Level Ch2 = %d\n", dev_read(cfg_ptr, CFG_TRLVL_2_OFFSET)); + //printf("#Subtrigger Ch1 = %d\n", dev_read(cfg_ptr, CFG_STRLVL_1_OFFSET)); + //printf("#Subtrigger Ch2 = %d\n", dev_read(cfg_ptr, CFG_STRLVL_2_OFFSET)); + printf("#High Voltage 1 = %.1f mV\n", a*dev_read(cfg_ptr, CFG_HV1_OFFSET)+b); + printf("#High Voltage 2 = %.1f mV\n", a*dev_read(cfg_ptr, CFG_HV2_OFFSET)+b); + printf("#Trigger Scaler 1 = %d\n", dev_read(cfg_ptr, CFG_TR_SCAL_A_OFFSET)); + printf("#Trigger Scaler 2 = %d\n", dev_read(cfg_ptr, CFG_TR_SCAL_B_OFFSET)); + if (((dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET)>>4) & 0x1) == 1) { // No GPS is present + printf("#No GPS device is present or enabled\n"); + }else{ + printf("#Using GPS data\n"); + } + if (((dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET)>>5) & 0x1) == 0) //Slave + { + printf("#Working mode is SLAVE\n"); + }else{ + printf("#Working mode is MASTER\n"); + } + printf("\n"); + printf("Status from registers complete!\n"); + return 0; +} + +static uint32_t get_memory_size(char *sysfs_path_file) +{ + FILE *size_fp; + uint32_t size; + + // open the file that describes the memory range size that is based on + // the reg property of the node in the device tree + size_fp = fopen(sysfs_path_file, "r"); + + if (!size_fp) { + printf("unable to open the uio size file\n"); + exit(-1); + } + + // get the size which is an ASCII string such as 0xXXXXXXXX and then be + // stop using the file + if(fscanf(size_fp, "0x%08X", &size) == EOF){ + printf("unable to get the size of the uio size file\n"); + exit(-1); + } + fclose(size_fp); + + return size; +} + +int intc_init(void) +{ + char *uiod = "/dev/uio0"; + + //printf("Initializing INTC device...\n"); + + // open the UIO device file to allow access to the device in user space + intc_fd = open(uiod, O_RDWR); + if (intc_fd < 1) { + printf("intc_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio0/maps/map0/size"); + + // mmap the INTC device into user space + intc_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, intc_fd, 0); + if (intc_ptr == MAP_FAILED) { + printf("intc_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int cfg_init(void) +{ + char *uiod = "/dev/uio1"; + + //printf("Initializing CFG device...\n"); + + // open the UIO device file to allow access to the device in user space + cfg_fd = open(uiod, O_RDWR); + if (cfg_fd < 1) { + printf("cfg_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio1/maps/map0/size"); + + // mmap the cfgC device into user space + cfg_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, cfg_fd, 0); + if (cfg_ptr == MAP_FAILED) { + printf("cfg_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int sts_init(void) +{ + char *uiod = "/dev/uio4"; + + //printf("Initializing STS device...\n"); + + // open the UIO device file to allow access to the device in user space + sts_fd = open(uiod, O_RDWR); + if (sts_fd < 1) { + printf("sts_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio4/maps/map0/size"); + + // mmap the STS device into user space + sts_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, sts_fd, 0); + if (sts_ptr == MAP_FAILED) { + printf("sts_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int xadc_init(void) +{ + char *uiod = "/dev/uio5"; + + //printf("Initializing XADC device...\n"); + + // open the UIO device file to allow access to the device in user space + xadc_fd = open(uiod, O_RDWR); + if (xadc_fd < 1) { + printf("xadc_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio5/maps/map0/size"); + + // mmap the XADC device into user space + xadc_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, xadc_fd, 0); + if (xadc_ptr == MAP_FAILED) { + printf("xadc_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int mem_init(void) +{ + char *mem_name = "/dev/mem"; + + //printf("Initializing mem device...\n"); + + // open the UIO device file to allow access to the device in user space + mem_fd = open(mem_name, O_RDWR); + if (mem_fd < 1) { + printf("mem_init: Invalid device file:%s.\n", mem_name); + return -1; + } + + dev_size = 2048*sysconf(_SC_PAGESIZE); + + // mmap the mem device into user space + mem_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0x1E000000); + if (mem_ptr == MAP_FAILED) { + printf("mem_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int cma_init(void) +{ + char *cma_name = "/dev/cma"; + + //printf("Initializing mem device...\n"); + + // open the UIO device file to allow access to the device in user space + cma_fd = open(cma_name, O_RDWR); + if (cma_fd < 1) { + printf("cma_init: Invalid device file:%s.\n", cma_name); + return -1; + } + + dev_size = 1024*sysconf(_SC_PAGESIZE); + + if(ioctl(cma_fd, CMA_ALLOC, &dev_size) < 0) { + perror("ioctl"); + return EXIT_FAILURE; + } + // mmap the mem device into user space + cma_ptr = mmap(NULL, 1024*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, cma_fd, 0); + if (cma_ptr == MAP_FAILED) { + printf("cma_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +float get_voltage(uint32_t offset) +{ + int16_t value; + value = (int16_t) dev_read(xadc_ptr, offset); + // printf("The Voltage is: %lf V\n", (value>>4)*XADC_CONV_VAL); + return ((value>>4)*XADC_CONV_VAL); +} + +/*void set_voltage(uint32_t offset, int32_t value) + { +//fit after calibration. See file data_calib.txt in /ramp_test directory +// y = a*x + b +//a = 0.0382061 +//b = 4.11435 +uint32_t dac_val; +float a = 0.0382061, b = 4.11435; + +dac_val = (uint32_t)(value - b)/a; + +dev_write(cfg_ptr, offset, dac_val); +printf("The Voltage is: %d mV\n", value); +printf("The DAC value is: %d DACs\n", dac_val); +} +*/ + +void set_voltage(uint32_t offset, int32_t value) +{ + //fit after calibration. See file data_calib2.txt in /ramp_test directory + // y = a*x + b + //a = 0.0882006 + //b = 7.73516 + uint32_t dac_val; + float a = 0.0882006, b = 7.73516; + + dac_val = (uint32_t)(value - b)/a; + + dev_write(cfg_ptr, offset, dac_val); + printf("The Voltage is: %d mV\n", value); + printf("The DAC value is: %d DACs\n", dac_val); +} + +float get_temp_AD592(uint32_t offset) +{ + float value; + value = get_voltage(offset); + return ((value*1000)-273.15); +} + +//System initialization +int init_system(void) +{ + uint32_t reg_val; + + //FIXME: replace hardcoded values for defines + // set trigger_lvl_1 + dev_write(cfg_ptr,CFG_TRLVL_1_OFFSET,8190); + + // set trigger_lvl_2 + dev_write(cfg_ptr,CFG_TRLVL_2_OFFSET,8190); + + // set subtrigger_lvl_1 + dev_write(cfg_ptr,CFG_STRLVL_1_OFFSET,8190); + + // set subtrigger_lvl_2 + dev_write(cfg_ptr,CFG_STRLVL_2_OFFSET,8190); + + // set hv1 and hv2 to zero + dev_write(cfg_ptr,CFG_HV1_OFFSET,0); + dev_write(cfg_ptr,CFG_HV2_OFFSET,0); + + // reset ramp generators + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~8); + + // reset pps_gen, fifo and trigger modules + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~1); + + /* reset data converter and writer */ + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~4); + + // enter reset mode for tlast_gen + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~2); + + // set number of samples + dev_write(cfg_ptr,CFG_NSAMPLES_OFFSET, 1024 * 1024); + + // set default value for trigger scalers a and b + dev_write(cfg_ptr,CFG_TR_SCAL_A_OFFSET, 1); + dev_write(cfg_ptr,CFG_TR_SCAL_B_OFFSET, 1); + + // enter normal mode for tlast_gen + /* reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 2); + //printf("written reg_val tlast : 0x%08x\n",reg_val | 2); + // enter normal mode for pps_gen, fifo and trigger modules + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 1); + //printf("written reg_val pps_gen, fifo : 0x%08x\n",reg_val | 1); + */ + // enable false GPS + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | FGPS_EN_MASK); + //printf("written reg_val : 0x%08x\n",reg_val | 16); + // disable + //dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~16); + //dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~FGPS_EN_MASK); + //printf("written reg_val : 0x%08x\n",reg_val & ~16); + + /* // enter normal mode for data converter and writer + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 4); + //printf("written reg_val : 0x%08hx\n",reg_val | 4); + */ + // enter normal mode for ramp generators + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 8); + // enter in MASTER mode (default) + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 0x20); + + return 0; +} + +int enable_interrupt(void) +{ + // steps to accept interrupts -> as pg. 26 of pg099-axi-intc.pdf + //1) Each bit in the IER corresponding to an interrupt must be set to 1. + dev_write(intc_ptr,XIL_AXI_INTC_IER_OFFSET, 1); + //2) There are two bits in the MER. The ME bit must be set to enable the + //interrupt request outputs. + dev_write(intc_ptr,XIL_AXI_INTC_MER_OFFSET, XIL_AXI_INTC_MER_ME_MASK | XIL_AXI_INTC_MER_HIE_MASK); + //dev_write(dev_ptr,XIL_AXI_INTC_MER_OFFSET, XIL_AXI_INTC_MER_ME_MASK); + + //The next block of code is to test interrupts by software + //3) Software testing can now proceed by writing a 1 to any bit position + //in the ISR that corresponds to an existing interrupt input. + /* dev_write(intc_ptr,XIL_AXI_INTC_IPR_OFFSET, 1); + + for(a=0; a<10; a++) + { + wait_for_interrupt(fd, dev_ptr); + dev_write(dev_ptr,XIL_AXI_INTC_ISR_OFFSET, 1); //regenerate interrupt + } + */ + return 0; + +} + +int disable_interrupt(void) +{ + uint32_t value; + //Disable interrupt INTC0 + dev_write(intc_ptr,XIL_AXI_INTC_IER_OFFSET, 0); + //disable IRQ + value = dev_read(intc_ptr, XIL_AXI_INTC_MER_OFFSET); + dev_write(intc_ptr,XIL_AXI_INTC_MER_OFFSET, value | ~1); + //Acknowledge any previous interrupt + dev_write(intc_ptr, XIL_AXI_INTC_IAR_OFFSET, 1); + + return 0; +} + diff --git a/projects/adc_recorder_uio/uio_src/zynq_io.h b/projects/adc_recorder_uio/uio_src/zynq_io.h new file mode 100644 index 0000000..e691292 --- /dev/null +++ b/projects/adc_recorder_uio/uio_src/zynq_io.h @@ -0,0 +1,155 @@ +#ifndef _ZYNQ_IO_H_ +#define _ZYNQ_IO_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> +#include <sys/ioctl.h> + +#define CMA_ALLOC _IOWR('Z', 0, uint32_t) +#define INTC_BASEADDR 0x40000000 +#define INTC_HIGHADDR 0x40000FFF + +#define CFG_BASEADDR 0x40001000 +#define CFG_HIGHADDR 0x40001FFF + +#define STS_BASEADDR 0x40002000 +#define STS_HIGHADDR 0x40002FFF + +#define XADC_BASEADDR 0x40003000 +#define XADC_HIGHADDR 0x40003FFF + +#define XIL_AXI_INTC_ISR_OFFSET 0x0 +#define XIL_AXI_INTC_IPR_OFFSET 0x4 +#define XIL_AXI_INTC_IER_OFFSET 0x8 +#define XIL_AXI_INTC_IAR_OFFSET 0xC +#define XIL_AXI_INTC_SIE_OFFSET 0x10 +#define XIL_AXI_INTC_CIE_OFFSET 0x14 +#define XIL_AXI_INTC_IVR_OFFSET 0x18 +#define XIL_AXI_INTC_MER_OFFSET 0x1C +#define XIL_AXI_INTC_IMR_OFFSET 0x20 +#define XIL_AXI_INTC_ILR_OFFSET 0x24 +#define XIL_AXI_INTC_IVAR_OFFSET 0x100 + +#define XIL_AXI_INTC_MER_ME_MASK 0x00000001 +#define XIL_AXI_INTC_MER_HIE_MASK 0x00000002 + +//CFG +#define CFG_RESET_GRAL_OFFSET 0x0 +#define CFG_WR_ADDR_OFFSET 0x4 +#define CFG_NSAMPLES_OFFSET 0x8 +#define CFG_TRLVL_1_OFFSET 0x8 +#define CFG_TRLVL_2_OFFSET 0xC +#define CFG_STRLVL_1_OFFSET 0x10 +#define CFG_STRLVL_2_OFFSET 0x14 +#define CFG_TEMPERATURE_OFFSET 0x18 +#define CFG_PRESSURE_OFFSET 0x1C +#define CFG_TIME_OFFSET 0x20 +#define CFG_DATE_OFFSET 0x24 +#define CFG_LATITUDE_OFFSET 0x28 +#define CFG_LONGITUDE_OFFSET 0x2C +#define CFG_ALTITUDE_OFFSET 0x30 +#define CFG_SATELLITE_OFFSET 0x34 +#define CFG_TR_SCAL_A_OFFSET 0x38 +#define CFG_TR_SCAL_B_OFFSET 0x3C +#define CFG_HV1_OFFSET 0x4C //DAC_PWM3 +#define CFG_HV2_OFFSET 0x48 //DAC_PWM2 +#define CFG_HV3_OFFSET 0x40 //DAC_PWM0 +#define CFG_HV4_OFFSET 0x44 //DAC_PWM1 + +//CFG Slow DAC +#define CFG_DAC_PWM0_OFFSET 0x40 +#define CFG_DAC_PWM1_OFFSET 0x44 +#define CFG_DAC_PWM2_OFFSET 0x48 +#define CFG_DAC_PWM3_OFFSET 0x4C + +#define ENBL_ALL_MASK 0xFFFFFFFF +#define RST_ALL_MASK 0x00000000 +#define RST_PPS_TRG_FIFO_MASK 0x00000001 +#define RST_TLAST_GEN_MASK 0x00000002 +#define RST_WRITER_MASK 0x00000004 +#define RST_AO_MASK 0x00000008 +#define FGPS_EN_MASK 0x00000010 + +//STS +#define STS_STATUS_OFFSET 0x0 + +//XADC +//See page 17 of PG091 +#define XADC_SRR_OFFSET 0x00 //Software reset register +#define XADC_SR_OFFSET 0x04 //Status Register +#define XADC_AOSR_OFFSET 0x08 //Alarm Out Status Register +#define XADC_CONVSTR_OFFSET 0x0C //CONVST Register +#define XADC_SYSMONRR_OFFSET 0x10 //XADC Reset Register +#define XADC_GIER_OFFSET 0x5C //Global Interrupt Enable Register +#define XADC_IPISR_OFFSET 0x60 //IP Interrupt Status Register +#define XADC_IPIER_OFFSET 0x68 //IP Interrupt Enable Register +#define XADC_TEMPERATURE_OFFSET 0x200 //Temperature +#define XADC_VCCINT_OFFSET 0x204 //VCCINT +#define XADC_VCCAUX_OFFSET 0x208 //VCCAUX +#define XADC_VPVN_OFFSET 0x20C //VP/VN +#define XADC_VREFP_OFFSET 0x210 //VREFP +#define XADC_VREFN_OFFSET 0x214 //VREFN +#define XADC_VBRAM_OFFSET 0x218 //VBRAM +#define XADC_UNDEF_OFFSET 0x21C //Undefined +#define XADC_SPLYOFF_OFFSET 0x220 //Supply Offset +#define XADC_ADCOFF_OFFSET 0x224 //ADC Offset +#define XADC_GAIN_ERR_OFFSET 0x228 //Gain Error +#define XADC_ZDC_SPLY_OFFSET 0x234 //Zynq-7000 Device Core Supply +#define XADC_ZDC_AUX_SPLY_OFFSET 0x238 //Zynq-7000 Device Core Aux Supply +#define XADC_ZDC_MEM_SPLY_OFFSET 0x23C //Zynq-7000 Device Core Memory Supply +#define XADC_VAUX_PN_0_OFFSET 0x240 //VAUXP[0]/VAUXN[0] +#define XADC_VAUX_PN_1_OFFSET 0x244 //VAUXP[1]/VAUXN[1] +#define XADC_VAUX_PN_2_OFFSET 0x248 //VAUXP[2]/VAUXN[2] +#define XADC_VAUX_PN_3_OFFSET 0x24C //VAUXP[3]/VAUXN[3] +#define XADC_VAUX_PN_4_OFFSET 0x250 //VAUXP[4]/VAUXN[4] +#define XADC_VAUX_PN_5_OFFSET 0x254 //VAUXP[5]/VAUXN[5] +#define XADC_VAUX_PN_6_OFFSET 0x258 //VAUXP[6]/VAUXN[6] +#define XADC_VAUX_PN_7_OFFSET 0x25C //VAUXP[7]/VAUXN[7] +#define XADC_VAUX_PN_8_OFFSET 0x260 //VAUXP[8]/VAUXN[8] +#define XADC_VAUX_PN_9_OFFSET 0x264 //VAUXP[9]/VAUXN[9] +#define XADC_VAUX_PN_10_OFFSET 0x268 //VAUXP[10]/VAUXN[10] +#define XADC_VAUX_PN_11_OFFSET 0x26C //VAUXP[11]/VAUXN[11] +#define XADC_VAUX_PN_12_OFFSET 0x270 //VAUXP[12]/VAUXN[12] +#define XADC_VAUX_PN_13_OFFSET 0x274 //VAUXP[13]/VAUXN[13] +#define XADC_VAUX_PN_14_OFFSET 0x278 //VAUXP[14]/VAUXN[14] +#define XADC_VAUX_PN_15_OFFSET 0x27C //VAUXP[15]/VAUXN[15] + +#define XADC_AI0_OFFSET XADC_VAUX_PN_8_OFFSET +#define XADC_AI1_OFFSET XADC_VAUX_PN_0_OFFSET +#define XADC_AI2_OFFSET XADC_VAUX_PN_1_OFFSET +#define XADC_AI3_OFFSET XADC_VAUX_PN_9_OFFSET + +#define XADC_CONV_VAL 0.00171191993362 //(A_ip/2^12)*(34.99/4.99) +#define XADC_RDIV_VAL 1.883236177 //voltage divisor in board (15k+16.983k)/16.983k = 1.88 +#define XADC_BASE_HVDIV 0.00294088 //voltage divisor in HV base board (100k/31.3Meg) = 3.194888179. The value I put here is the measured one. + +extern int intc_fd, cfg_fd, sts_fd, xadc_fd, mem_fd, hst0_fd, hst1_fd, cma_fd; +extern void *intc_ptr, *cfg_ptr, *sts_ptr, *xadc_ptr, *mem_ptr, *hst0_ptr, *hst1_ptr; +extern int16_t *cma_ptr; +extern uint32_t dev_size; + +void dev_write(void *dev_base, uint32_t offset, int32_t value); +uint32_t dev_read(void *dev_base, uint32_t offset); +//int dev_init(int n_dev); +int32_t rd_reg_value(int n_dev, uint32_t reg_off, uint8_t degug); +int32_t wr_reg_value(int n_dev, uint32_t reg_off, int32_t reg_val, uint8_t debug); +int32_t rd_cfg_status(void); +int intc_init(void); +int cfg_init(void); +int sts_init(void); +int xadc_init(void); +int mem_init(void); +int cma_init(void); +float get_voltage(uint32_t offset); +void set_voltage(uint32_t offset, int32_t value); +float get_temp_AD592(uint32_t offset); +int init_system(void); +int enable_interrupt(void); +int disable_interrupt(void); + +#endif + diff --git a/projects/adc_test/block_design.tcl b/projects/adc_test/block_design.tcl new file mode 100644 index 0000000..4eddd18 --- /dev/null +++ b/projects/adc_test/block_design.tcl @@ -0,0 +1,299 @@ +# Create clk_wiz +cell xilinx.com:ip:clk_wiz pll_0 { + PRIMITIVE PLL + PRIM_IN_FREQ.VALUE_SRC USER + PRIM_IN_FREQ 125.0 + PRIM_SOURCE Differential_clock_capable_pin + CLKOUT1_USED true + CLKOUT1_REQUESTED_OUT_FREQ 125.0 + CLKOUT2_USED true + CLKOUT2_REQUESTED_OUT_FREQ 250.0 + CLKOUT2_REQUESTED_PHASE 157.5 + CLKOUT3_USED true + CLKOUT3_REQUESTED_OUT_FREQ 250.0 + CLKOUT3_REQUESTED_PHASE 202.5 + USE_RESET false +} { + clk_in1_p adc_clk_p_i + clk_in1_n adc_clk_n_i +} + +# Create processing_system7 +cell xilinx.com:ip:processing_system7 ps_0 { + PCW_IMPORT_BOARD_PRESET cfg/red_pitaya.xml + PCW_USE_S_AXI_ACP 1 + PCW_USE_DEFAULT_ACP_USER_VAL 1 +} { + M_AXI_GP0_ACLK pll_0/clk_out1 + S_AXI_ACP_ACLK pll_0/clk_out1 +} + +# Create all required interconnections +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config { + make_external {FIXED_IO, DDR} + Master Disable + Slave Disable +} [get_bd_cells ps_0] + +# Create xlconstant +cell xilinx.com:ip:xlconstant const_0 + +# Create proc_sys_reset +cell xilinx.com:ip:proc_sys_reset rst_0 {} { + ext_reset_in const_0/dout +} + +# ADC + +# Create axis_rp_adc +cell labdpr:user:axis_rp_adc adc_0 { + ADC_DATA_WIDTH 14 +} { + aclk pll_0/clk_out1 + adc_dat_a adc_dat_a_i + adc_dat_b adc_dat_b_i + adc_csn adc_csn_o +} + +# DAC + +# Create axis_rp_dac +cell labdpr:user:axis_rp_dac dac_0 { + DAC_DATA_WIDTH 14 +} { + aclk pll_0/clk_out1 + ddr_clk pll_0/clk_out2 + wrt_clk pll_0/clk_out3 + locked pll_0/locked + dac_clk dac_clk_o + dac_rst dac_rst_o + dac_sel dac_sel_o + dac_wrt dac_wrt_o + dac_dat dac_dat_o + s_axis_tvalid const_0/dout +} + +# CFG + +# Create axi_cfg_register +cell labdpr:user:axi_cfg_register cfg_0 { + CFG_DATA_WIDTH 160 + AXI_ADDR_WIDTH 32 + AXI_DATA_WIDTH 32 +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_0 { + DIN_WIDTH 160 DIN_FROM 0 DIN_TO 0 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_1 { + DIN_WIDTH 160 DIN_FROM 1 DIN_TO 1 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_2 { + DIN_WIDTH 160 DIN_FROM 31 DIN_TO 16 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_3 { + DIN_WIDTH 160 DIN_FROM 63 DIN_TO 32 +} { + din cfg_0/cfg_data +} + +# RX + +# Create axis_subset_converter +cell xilinx.com:ip:axis_subset_converter subset_0 { + S_TDATA_NUM_BYTES.VALUE_SRC USER + M_TDATA_NUM_BYTES.VALUE_SRC USER + S_TDATA_NUM_BYTES 4 + M_TDATA_NUM_BYTES 2 + TDATA_REMAP {tdata[15:0]} +} { + S_AXIS adc_0/M_AXIS + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +# Create axis_constant +cell labdpr:user:axis_variable rate_0 { + AXIS_TDATA_WIDTH 16 +} { + cfg_data slice_2/dout + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +# Create cic_compiler +cell xilinx.com:ip:cic_compiler cic_0 { + INPUT_DATA_WIDTH.VALUE_SRC USER + FILTER_TYPE Decimation + NUMBER_OF_STAGES 6 + SAMPLE_RATE_CHANGES Programmable + MINIMUM_RATE 4 + MAXIMUM_RATE 6250 + FIXED_OR_INITIAL_RATE 4 + INPUT_SAMPLE_FREQUENCY 125 + CLOCK_FREQUENCY 125 + INPUT_DATA_WIDTH 16 + QUANTIZATION Truncation + OUTPUT_DATA_WIDTH 16 + USE_XTREME_DSP_SLICE false + HAS_ARESETN true +} { + S_AXIS_DATA subset_0/M_AXIS + S_AXIS_CONFIG rate_0/M_AXIS + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +# Create axis_dwidth_converter +cell xilinx.com:ip:axis_dwidth_converter conv_0 { + S_TDATA_NUM_BYTES.VALUE_SRC USER + S_TDATA_NUM_BYTES 2 + M_TDATA_NUM_BYTES 8 +} { + S_AXIS cic_0/M_AXIS_DATA + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# DMA + +# Create axis_ram_writer +cell labdpr:user:axis_ram_writer writer_0 { + ADDR_WIDTH 16 + AXI_ID_WIDTH 3 +} { + S_AXIS conv_0/M_AXIS + M_AXI ps_0/S_AXI_ACP + cfg_data slice_3/dout + aclk pll_0/clk_out1 + aresetn slice_1/dout +} + +# GEN + +# Create axis_lfsr +cell labdpr:user:axis_lfsr lfsr_0 {} { + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +for {set i 0} {$i <= 1} {incr i} { + + # Create port_slicer + cell labdpr:user:port_slicer slice_[expr $i + 4] { + DIN_WIDTH 160 DIN_FROM [expr 32 * $i + 95] DIN_TO [expr 32 * $i + 64] + } { + din cfg_0/cfg_data + } + + # Create port_slicer + cell labdpr:user:port_slicer slice_[expr $i + 6] { + DIN_WIDTH 160 DIN_FROM [expr 16 * $i + 143] DIN_TO [expr 16 * $i + 128] + } { + din cfg_0/cfg_data + } + + # Create axis_constant + cell labdpr:user:axis_constant phase_$i { + AXIS_TDATA_WIDTH 32 + } { + cfg_data slice_[expr $i + 4]/dout + aclk pll_0/clk_out1 + } + + # Create dds_compiler + cell xilinx.com:ip:dds_compiler dds_$i { + DDS_CLOCK_RATE 125 + SPURIOUS_FREE_DYNAMIC_RANGE 138 + FREQUENCY_RESOLUTION 0.2 + PHASE_INCREMENT Streaming + HAS_PHASE_OUT false + PHASE_WIDTH 30 + OUTPUT_WIDTH 24 + DSP48_USE Minimal + NEGATIVE_SINE true + } { + S_AXIS_PHASE phase_$i/M_AXIS + aclk pll_0/clk_out1 + } + + # Create xbip_dsp48_macro + cell xilinx.com:ip:xbip_dsp48_macro mult_$i { + INSTRUCTION1 RNDSIMPLE(A*B+CARRYIN) + A_WIDTH.VALUE_SRC USER + B_WIDTH.VALUE_SRC USER + OUTPUT_PROPERTIES User_Defined + A_WIDTH 24 + B_WIDTH 16 + P_WIDTH 15 + } { + A dds_$i/m_axis_data_tdata + B slice_[expr $i + 6]/dout + CARRYIN lfsr_0/m_axis_tdata + CLK pll_0/clk_out1 + } + +} + +# Create xlconcat +cell xilinx.com:ip:xlconcat concat_0 { + NUM_PORTS 2 + IN0_WIDTH 16 + IN1_WIDTH 16 +} { + In0 mult_0/P + In1 mult_1/P + dout dac_0/s_axis_tdata +} + +# STS + +# Create dna_reader +cell labdpr:user:dna_reader dna_0 {} { + aclk pll_0/clk_out1 + aresetn rst_0/peripheral_aresetn +} + +# Create xlconcat +cell xilinx.com:ip:xlconcat concat_1 { + NUM_PORTS 3 + IN0_WIDTH 32 + IN1_WIDTH 64 + IN2_WIDTH 32 +} { + In0 const_0/dout + In1 dna_0/dna_data + In2 writer_0/sts_data +} + +# Create axi_sts_register +cell labdpr:user:axi_sts_register sts_0 { + STS_DATA_WIDTH 128 + AXI_ADDR_WIDTH 32 + AXI_DATA_WIDTH 32 +} { + sts_data concat_1/dout +} + +addr 0x40000000 4K sts_0/S_AXI /ps_0/M_AXI_GP0 + +addr 0x40001000 4K cfg_0/S_AXI /ps_0/M_AXI_GP0 + +assign_bd_address [get_bd_addr_segs ps_0/S_AXI_ACP/ACP_DDR_LOWOCM] + +group_bd_cells PS7 [get_bd_cells rst_0] [get_bd_cells pll_0] [get_bd_cells const_0] [get_bd_cells ps_0] [get_bd_cells ps_0_axi_periph] +group_bd_cells ACQ [get_bd_cells rate_0] [get_bd_cells adc_0] [get_bd_cells subset_0] [get_bd_cells slice_0] [get_bd_cells slice_1] [get_bd_cells conv_0] [get_bd_cells slice_2] [get_bd_cells cic_0] [get_bd_cells writer_0] [get_bd_cells slice_3] +group_bd_cells CMPLX_GEN [get_bd_cells phase_1] [get_bd_cells mult_0] [get_bd_cells dds_0] [get_bd_cells dds_1] [get_bd_cells mult_1] [get_bd_cells dac_0] [get_bd_cells slice_4] [get_bd_cells slice_5] [get_bd_cells concat_0] [get_bd_cells slice_6] [get_bd_cells phase_0] [get_bd_cells lfsr_0] diff --git a/projects/adc_test/client/Makefile b/projects/adc_test/client/Makefile new file mode 100644 index 0000000..7743a46 --- /dev/null +++ b/projects/adc_test/client/Makefile @@ -0,0 +1,11 @@ +CC=gcc +CFLAGS =-Wall -O3 + +all: adc-test-client_lnx + +sdr-transceiver: adc-test-client_lnx.c + $(CC) $(CFLAGS) -o $@ $^ -lm -lpthread + +clean: + rm -f adc-test-client_lnx + diff --git a/projects/adc_test/client/adc-test-client_lnx b/projects/adc_test/client/adc-test-client_lnx new file mode 100755 index 0000000000000000000000000000000000000000..9e083c1bc5e2f7f114602e5b2b331d7c353386d3 GIT binary patch literal 17336 zcmeHPZ){uD6~DHVHf>YKWhtbEwT~{HQXp>nm$W6rPLuX!bKB4+G%(s1$9_qyI(D$1 zOUe+WO1ohNL#JsP9~dfZVwDhEktVH_2~w4Id;z5(p&}S$3^r#4n!3O`*48`c-Fu#& zUu?0VN!thC$UgV{?m6e)ckX@H_q=y+9%}V%vfFHol7oGRAvgXFj(9}Dr41qj#KRid zT=-th7O@$?m+2TU_izHGJe{@Y(+Yt*fTCUvW(v?7ILwGr3z4E;vD7t-mk?zx&ZAyA zW(9Ahs$R$#Q7Sj;lTaCwq<<UKC9aRCSr2{FRnO(Sn)2x}i(g0&Vbtpvdi_F==oB^x z5>fIe`UF3X!k<<uK^Z1V|7Ogp*Cq6<v_;4h#X2zU_(%(Wo%-5^Ubm#1VOHwnFe6I! z-2r;&mwz`=H*Xj973+s1q92F~_p;^TP|w=c%frF?a43=(svl}xTfcU-J05kf)SH0q z!a8u+Y~I?*z|0t8!i{=gR0|%<pSgJa+qX5{y{PY{r+X&OKmObLH&46C2G)r(m{4Cd z$>6Vn9LnJJ58L*`7qcUVw<y+eMtyx?U1s!#^EU>nfGwEr0u*(u=?nmp6$E}2d<w}w zTm=7l5j<W5-(3X%1aJvH*3<$(q4pqF2(K-IFD`=LTm%Pi7qtJqBKT#%CHPp=8~_Tn z^HIQ;ScQQP!)G2_$RrOhr2BO#u-CxI8^ex=bS)>K5b6ow@LbE{(ZC*6V~R2u3q`bE zCD6ZzsY4-+4XUwNG{yqaNJI^wKwR?&_F%cv>koxlT#ISZFyOr=&6pb43($Z%Fc96V z>c-+)5G=7iRqKz&wVr(u|A5MR?~8>rl?B4lxC-)tA-~caiul8!`;o=gVRbQ08SsZ9 zY_qSed84w@y~@4X$men^-D{ZA*0Du_depv9TvKBmTQ-KH5w*kL6GnS|1JQ`Er*P4N zg8W``z#WBuc)#H{=ZHtn27eCt<bEEs1tIt)DPzA8Sam2g7w^s&1)o@m<#u)ocuX|E zQ$HOQ{nIVxZ^8!!Ug6QzjCq*&v$t~`?{)J$Fk!;QPn9m1HsMqU7EGCNnhO!XWWvqk zk;WO?7C-$c&IX12Ovs~uC=Ho#n)9%1*o33MDLrh$&GYyn6OMIIdfbGIpLD(GunC_{ z!a$FhaJ<(j9W~*V1Oh!~!l7f0G-kq`2Flp0Cfq#9j+^j#Cizmf<bje0N**YApyYx7 zXAfMgTJ)tn@^OVcTK@KO#^i%znms!%kGxWGQg3#4&3b?{*`*tRR4ryG-;X7k$v<VY z*+V*y3xmw$8H2}#OJ?$f!Q%oUGx@y1<H8^_`IN!qq9Zf;V}r*9LS}Nm!Q;XpGkLGU z<3cAh={I;>AY>-*FnC-TWG1}^j|+m#<O+kwg+ONVM&jY>K5^sKwJ`nqfbX>MTP%F5 zg>SO(Yb<=dg<opnziHv;Tll#azTCoJfyV{r_J3~Xy*s^kdON)xojZJ~Cu$*3&C2^f z#^_ZZsjOwbb?+w5!w{$o%A;jV>%cW~@<443^RN|Ta`NIx*8b2EdDJP7Hcf$1IW_+^ zSTDVVU7mgjJh&p8mVwBl54w({-&cH*u0Z$=UF2mP3UcyPItZ9IdHUd3)x#S=S04RA zMSAQi=mBydgF=D!YI)RC(_3|ZtS$Lr)v~f$IrTto*$dcNy(dn=2yN*7Ls_kz`BLFp zSNbQQd>mJ{zT{t8l7H__hHLHV*8#*Ta8>RD?P_0YX+Jc#*Il*v0AP&0fUDT!xX$+_ zKLx$?98gJ~JUI5??IUTMFL|ylb<2-noMSV<^2>Og^2o`ui&ZymynGC~i&b}zWvX_U zF9f^kdc1^n=Mv-Ro=N-?&AodCeZl<~lvi<wCU(mEU#SC+CeMC<m-im;F7Ixya#9|h z`{XUq7>o#XXUVCiC*f+-HDDCndI3$Pnhpc>B37Ip2jJY(00mIW4p@2@K)H((_veaF z+LC8>%gGPqkq@WZJAA3~UXYbjbI;?&q?*#8l%4;<&5V6^2-sQB2su@5N3!mcHXo*f zm!J%%f?3&#s>Q>g#ZC$e@^52dYRwx+mR*&TQ}T&VZ<kM8a>%yR@|mj|bYuBXg@KCf zM6W(BNgwBn;il)Hm?duRlt-Fkn3a<sX_YX-_5za*UCw6p@p8KSAn>+bplj5R`jhuT z`$c<@Z|}kxEd4y_f!mG)$+-l}y*quWradsSy?3@H-|}|0B|rCec$1eq<y8GW0PpZE zyP{h-|0Q_*#1)6Oc*Q%yzAu^42g+Z)+3NRUAlT$}e@y%h=SNdd_U6}zGbh%o&#T5v z3ScRfJW%pL$pa-1lsr)KK*<9o50pIcKlXqP-ZCWO{ytS&8kg{O4!+Eh2BR@;Hf!C! zecN^^I;ciMkv>VhR?@*+q)1eXCj$Mt%53A6($e1CGx;%Cq`&XAUGLc7gKNZ)ee8TT zI}G&jR5p7A=ux0!K!-16v!4MSyqL}Q1MU7Sn>~v-&~}Jirhq<<5fCKt`h?l;-_C49 zF5C5$Gb;{38RGh00k8p2Di~{-slWDsaF?xyPb1Vl0hBpio18V@t(tRR#W1^l;rg3a z)h<C8_3wet6v&z1mmsdeCk^;GP)aqBc?3SgP@nz|uGQ)CIxAY7pxgyGUf%(@zCUBT zH#uF8*_)j;k2;#2QmU-kS@%e}*V*vH8D3}O$V|C%&avTP`yF#<wm2ss;|SPhI~zAT z8@$dskO#eHr>ogn;hh7f;1LBY1DkbFuL^l?yA5r(qU~0+-Ga7dw7uEsi8vdfE{iSw z-L((ww1XXd{8CCK50pGm@<7Q0B@dK5Q1U>@10@fXJn;2BK>NRFzZZr9n21(#*4S_c zFO&4tHJ{T3#Ebo7*9#uwC`=1EVYI)D_DNIu=U1~)6gez5XVDt}Rgs}RSmUCc;<jr= z12NXXgmDfg(Jaouw@_nUV*eAq=fl(}^f7M2M0>if<1CXz0|}Q!hT45r$kCoJs(+Ed zN$#Inetl4#4#6uk{dy~eJqSK^p8O4=n9jc^F8m*Yr|S^r|7(QyYg-LAh~UyAXuF`@ zf({BgEa)LY4-0x!&@n;B1)UIdN>FRPU&U8=xWwj-8`n#9ojr+&mXOxL{>+B@6%7fU zUAc?{Uu6o$hRxX5Zx+UVn6xiFA9pa?cb<=zu?GrtkOOvI)40x;pTTH6=i@UOjr)AO zg3)-$$7eAbNBQ_{M&mUfpJR;cd>rob0{!8D(-Trb+=-ihrzHogVy=R?i%k^7=P{Z` z%*GtJ16eX7Jnw)VpWOxVYId|BKHu2yYPRNp-N-Z_<>S|}Lid9MW*3@2^5tRn^OzBy zcbN7=n@b&xX2%?g_k9_=kj)`Hhx1S&93KMNv9oC65{mfz2=N9BeyhM~ei!0w3uJ82 z&N>fAX#T-xOSS_3837#a)9(e>V(c+pe!8EFwg1<;d^M}opJtI2P77V{@Aabj)B5W* z-Olv>dP~UDK4)&3u}M8Mef(V3?M(0ATj7Vo&ZgfN*MOsNUwgawp`qWaB|1*E<>+d_ zr5tPIp40K^;|HH3y4V8d@))9eW+&i<_S4^hxPAJ4v`d%Iw}ITgBKRXk@Mi(X_E^U` zZZR?M%ch#%EP{UuxI{uGdZmc`Jn;WK`vOMuJ*g~09BUTF%0xju;OL(TG5%G7zY5d^ z<GjHm070JD>vb9D$CeAc3GAS})&Ff|U(93r^HR{+s^j^#k?SvlKTrgJv<Uu-BKYqB zNB>ycd9sN7dw@&Ro5?N#zN7$N4ZmlF&UMrQ4&I-h{J}uIrpC4UKscmEG$kAvatBx- zrp2`c>^ljt+!+Z)8&Kf<MMRCm35j4-=?h1D{9z@iMPqTrpBRG2^aF!oRa1lR#)dWP z3Jc+>jgaDx#r*pes4upU^~T_pfD%j$4D16H6Q_WrmM5wxo3?wmv?{GzTNF5#kuMNr zO3Phay<6Hg=9lQlLI8pzP)e&TEXXa}nX=ipt=a2Swr$$9qqRfn@HYEe(W-u!BoI&N zO=WmM#p9s^C0}`TL=E~iKjSB1tS4Y{W>)iqEIB~8YdywdEk@J)R7(Eg7^|G=Fioxq zkHT0Ew(tWvIT7B7U_7ey`y)X-2-CI=>I;S<N+Pa;e{-(Et^vL$9v2PLkKLHh1m(<P z&HQXo4#TSO&`>@ijt=F6{NztQrYLY=#~22t^F%o@{d)0`Pr;Kr`6q~STG%dr{>Xyq zho15==8o?h(EL3>;bfCe`zZ$}qtw_Sb4Q|@>h6mq+=DTA(G}D7nV_CT2+se7f&%h3 zx7BO@KBkNJ`{Vu09o!dzDmc|*ykxH$i-)3-JVt@Cm>Tw@g2)YqHRjfP$qiX|Uldr( z#MJ<EYw8fNcqf8%R3EW!wO`zO{Xwus9Jj%5Lasr1sLDSO0%KeqMgnug1TX+M_4HZh zKSprH1yeozmh)62*6Bnk9u>v9Eaj1Y3qBaCkv_!*L?tLQCyM(BTMHSpewV19D6ZSg ziGI%rYlDngpW+On5(x@w)!zyD7Z5{I`zanF+932O&bGGS59JtRlRm{QL@%LpAz>Ra zOZpTKhXBJ%CVh%;h*BI6B6<?$h-LRe4r64}r#Oh{O+u2|PjW;bgmR3ziKlpps7L5q z+b>|2f(-hU^eL_)O3wkPe(UxBOz1ZYgY;a1C_RTjee{`C|0%%GCuAQMCp-yijVP@B z|Aa+f5_&`@ggGJ>^Xyj^eIxD@>mZUZrhn9;Pw^qqaZ(hN>=AvzqEB%o(S*34$PDQb z|FT7&;!UFTJd5P5{yQb~ssEWIBn9mjED`EI;(45s8$aC=FCpq9K|!tczXLe-Kh;lh zF41l*G$m{OA3+&J>-s&2ViXtAIdiK#@kB3xPL)ZY;^yvpw3ZvMoXhc~e+3F~>{2&T zd`<s1fc`%K-hY@#kNWXh!0-}DpW^T?v0y)fN~T2mL}!4qS)X}?a091Q51Al6;wwQJ zF{)qk@Df)MeTf$v-}6NMLfpVfzt%u_2HT3sOsVgA3IA>s2K$BMz6mg#wJ`ig^DjQ1 jq_%TS{(Tr93_!ZgQb_gkQj7r#>%Y66ODwb~SXlNiW4M%! literal 0 HcmV?d00001 diff --git a/projects/adc_test/client/adc-test-client_lnx.c b/projects/adc_test/client/adc-test-client_lnx.c new file mode 100644 index 0000000..23d0ff6 --- /dev/null +++ b/projects/adc_test/client/adc-test-client_lnx.c @@ -0,0 +1,102 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> + +void error(const char *msg) +{ + perror(msg); + exit(0); +} + +int main(int argc, char *argv[]) +{ + int sockfd, portno, n, i; + struct sockaddr_in serv_addr; + struct hostent *server; + int bytesReceived=0; + + //char buffer[256]; + int32_t buffer[256*4096]; + //int32_t bufferIn[256]; + float bufferOut[256*4096]; + + if (argc < 3) { + fprintf(stderr,"usage %s hostname port\n", argv[0]); + exit(0); + } + portno = atoi(argv[2]); + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + error("ERROR opening socket"); + server = gethostbyname(argv[1]); + if (server == NULL) { + fprintf(stderr,"ERROR, no such host\n"); + exit(0); + } + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + bcopy((char *)server->h_addr, + (char *)&serv_addr.sin_addr.s_addr, + server->h_length); + serv_addr.sin_port = htons(portno); + if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) + { + perror("connect"); + return 1; + } + +// while(1) +// { +// bytesReceived=recv(sockfd, buffer, 256*4096, MSG_WAITALL); +// for(i = 0; i < bytesReceived; ++i) +// { +// bufferOut[i] = ((float)buffer[i]) / 2147483647.0; +// } +// //printf("%f\n",*bufferOut); +// //printf(bufferOut); +// +// fwrite(bufferOut, 1, 256*4096, stdout); +// fflush(stdout); +// } + + do + { + bytesReceived = recv( + sockfd, + buffer, + 256*4096, + MSG_WAITALL); + + for (i = 0; i < bytesReceived; ++i) + printf("%f\n", (float)buffer[i]/2147483647.0); + } + while(bytesReceived); + + //while(1) + //{ + //recv(sockfd, buffer, 256*4096, MSG_WAITALL); + // n=read(sockfd,buffer,256*4096); + // printf("%s\n",buffer); + //} + + // if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) + // error("ERROR connecting"); + // printf("Please enter the message: "); + // bzero(buffer,256); + // fgets(buffer,255,stdin); + // n = write(sockfd,buffer,strlen(buffer)); + // if (n < 0) + // error("ERROR writing to socket"); + // bzero(buffer,256); + // n = read(sockfd,buffer,255); + // if (n < 0) + // error("ERROR reading from socket"); + // printf("%s\n",buffer); + close(sockfd); + return 0; +} diff --git a/projects/adc_test/client/adc-test-client_win.c b/projects/adc_test/client/adc-test-client_win.c new file mode 100644 index 0000000..5219897 --- /dev/null +++ b/projects/adc_test/client/adc-test-client_win.c @@ -0,0 +1,44 @@ +/* +command to compile: +gcc adc-test-client.c -o adc-test-client -lws2_32 +*/ + +#include <winsock2.h> +#include <ws2tcpip.h> +#include <windows.h> + +#define TCP_ADDR "192.168.137.111" +#define TCP_PORT 1001 + +int main(int argc, char**argv) +{ + SOCKET sock; + struct sockaddr_in addr; + char buffer[256*4096]; + + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 2), &wsaData); + + if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + perror("socket"); + return 1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(TCP_ADDR); + addr.sin_port = htons(TCP_PORT); + + if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + perror("connect"); + return 1; + } + + while(1) + { + recv(sock, buffer, 256*4096, MSG_WAITALL); + } +} + diff --git a/projects/adc_test/server/adc-test-server.c b/projects/adc_test/server/adc-test-server.c new file mode 100644 index 0000000..ee727d9 --- /dev/null +++ b/projects/adc_test/server/adc-test-server.c @@ -0,0 +1,164 @@ +/* +command to compile: +gcc -O3 -D_GNU_SOURCE adc-test-server.c -o adc-test-server +*/ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <sched.h> +#include <fcntl.h> +#include <math.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#define TCP_PORT 1001 + +#define CMA_ALLOC _IOWR('Z', 0, uint32_t) + +int interrupted = 0; + +void signal_handler(int sig) +{ + interrupted = 1; +} + +int main () +{ + int fd, sock_server, sock_client; + int position, limit, offset; + volatile uint32_t *rx_addr, *rx_cntr; + volatile uint16_t *rx_rate; + volatile uint8_t *rx_rst; + volatile void *cfg, *sts, *ram; + cpu_set_t mask; + struct sched_param param; + struct sockaddr_in addr; + uint32_t size; + int yes = 1; + + memset(¶m, 0, sizeof(param)); + param.sched_priority = sched_get_priority_max(SCHED_FIFO); + sched_setscheduler(0, SCHED_FIFO, ¶m); + + CPU_ZERO(&mask); + CPU_SET(1, &mask); + sched_setaffinity(0, sizeof(cpu_set_t), &mask); + + if((fd = open("/dev/mem", O_RDWR)) < 0) + { + perror("open"); + return EXIT_FAILURE; + } + + sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40000000); + cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40001000); + + close(fd); + + if((fd = open("/dev/cma", O_RDWR)) < 0) + { + perror("open"); + return EXIT_FAILURE; + } + + size = 128*sysconf(_SC_PAGESIZE); + + if(ioctl(fd, CMA_ALLOC, &size) < 0) + { + perror("ioctl"); + return EXIT_FAILURE; + } + + ram = mmap(NULL, 128*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + + rx_rst = (uint8_t *)(cfg + 0); + rx_rate = (uint16_t *)(cfg + 2); + rx_addr = (uint32_t *)(cfg + 4); + + rx_cntr = (uint32_t *)(sts + 12); + + *rx_addr = size; + + if((sock_server = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + perror("socket"); + return EXIT_FAILURE; + } + + setsockopt(sock_server, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)); + + /* setup listening address */ + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(TCP_PORT); + + if(bind(sock_server, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + perror("bind"); + return EXIT_FAILURE; + } + + listen(sock_server, 1024); + + while(!interrupted) + { + /* enter reset mode */ + *rx_rst &= ~1; + usleep(100); + *rx_rst &= ~2; + /* set default sample rate */ + *rx_rate = 4; + + if((sock_client = accept(sock_server, NULL, NULL)) < 0) + { + perror("accept"); + return EXIT_FAILURE; + } + + signal(SIGINT, signal_handler); + + /* enter normal operating mode */ + *rx_rst |= 3; + + limit = 32*1024; + + while(!interrupted) + { + /* read ram writer position */ + position = *rx_cntr; + + /* send 256 kB if ready, otherwise sleep 0.1 ms */ + if((limit > 0 && position > limit) || (limit == 0 && position < 32*1024)) + { + offset = limit > 0 ? 0 : 256*1024; + limit = limit > 0 ? 0 : 32*1024; + if(send(sock_client, ram + offset, 256*1024, MSG_NOSIGNAL) < 0) break; + } + else + { + usleep(100); + } + } + + signal(SIGINT, SIG_DFL); + close(sock_client); + } + + /* enter reset mode */ + *rx_rst &= ~1; + usleep(100); + *rx_rst &= ~2; + + close(sock_server); + + return EXIT_SUCCESS; +} diff --git a/projects/adc_test/server/gen.c b/projects/adc_test/server/gen.c new file mode 100644 index 0000000..b362ae4 --- /dev/null +++ b/projects/adc_test/server/gen.c @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <math.h> +#include <sys/mman.h> + +int main(int argc, char *argv[]) +{ + int fd, i; + char *end; + volatile void *cfg; + long number[3]; + + for(i = 0; i < 3; ++i) + { + errno = 0; + number[i] = (argc == 4) ? strtol(argv[i + 1], &end, 10) : -1; + if(errno != 0 || end == argv[i + 1]) + { + printf("Usage: gen [1-2] [0-32766] [0-61440000]\n"); + return EXIT_FAILURE; + } + } + + if(number[0] < 1 || number[0] > 2 || number[1] < 0 || number[1] > 32766 || number[2] < 0 || number[2] > 61440000) + { + printf("Usage: gen [1-2] [0-32766] [0-61440000]\n"); + return EXIT_FAILURE; + } + + if((fd = open("/dev/mem", O_RDWR)) < 0) + { + fprintf(stderr, "Cannot open /dev/mem.\n"); + return EXIT_FAILURE; + } + + cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40001000); + + switch(number[0]) + { + case 1: + *(uint32_t *)(cfg + 8) = (uint32_t)floor(number[2] / 125.0e6 * (1<<30) + 0.5); + *(uint16_t *)(cfg + 16) = (uint16_t)number[1]; + break; + case 2: + *(uint32_t *)(cfg + 12) = (uint32_t)floor(number[2] / 125.0e6 * (1<<30) + 0.5); + *(uint16_t *)(cfg + 18) = (uint16_t)number[1]; + break; + } + + return EXIT_SUCCESS; +} diff --git a/projects/counter_test/block_design.tcl b/projects/counter_test/block_design.tcl new file mode 100644 index 0000000..4a54b2a --- /dev/null +++ b/projects/counter_test/block_design.tcl @@ -0,0 +1,162 @@ +source projects/base_system/block_design.tcl + +# Create xlconstant +cell xilinx.com:ip:xlconstant const_0 + +# Create proc_sys_reset +cell xilinx.com:ip:proc_sys_reset rst_0 {} { + ext_reset_in const_0/dout +} + + +# ADC + +# Create axis_red_pitaya_adc +cell labdpr:user:axis_rp_adc adc_0 { + ADC_DATA_WIDTH 14 +} { + aclk pll_0/clk_out1 + adc_dat_a adc_dat_a_i + adc_dat_b adc_dat_b_i + adc_csn adc_csn_o +} + +# Create axi_cfg_register +cell labdpr:user:axi_cfg_register cfg_0 { + CFG_DATA_WIDTH 128 + AXI_ADDR_WIDTH 32 + AXI_DATA_WIDTH 32 +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_0 { + DIN_WIDTH 128 DIN_FROM 0 DIN_TO 0 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_1 { + DIN_WIDTH 128 DIN_FROM 1 DIN_TO 1 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_2 { + DIN_WIDTH 128 DIN_FROM 2 DIN_TO 2 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_3 { + DIN_WIDTH 128 DIN_FROM 63 DIN_TO 32 +} { + din cfg_0/cfg_data +} + +# Create port_slicer +cell labdpr:user:port_slicer slice_4 { + DIN_WIDTH 128 DIN_FROM 95 DIN_TO 64 +} { + din cfg_0/cfg_data +} + +# Create axis_clock_converter +cell xilinx.com:ip:axis_clock_converter fifo_0 {} { + S_AXIS adc_0/M_AXIS + s_axis_aclk pll_0/clk_out1 + s_axis_aresetn const_0/dout + m_axis_aclk ps_0/FCLK_CLK0 + m_axis_aresetn slice_0/Dout +} + +# Create counter +cell labdpr:user:axis_counter axis_counter_0 { + AXIS_TDATA_WIDTH 16 + CNTR_WIDTH 16 +} { + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# Create xlconstant +cell xilinx.com:ip:xlconstant const_2 { + CONST_VAL 65535 + CONST_WIDTH 16 +} { + dout axis_counter_0/cfg_data +} + +# Create counter +cell labdpr:user:axis_counter axis_counter_1 { + AXIS_TDATA_WIDTH 16 + CNTR_WIDTH 16 +} { + aclk pll_0/clk_out1 + aresetn slice_0/dout +} + +# Create xlconstant +cell xilinx.com:ip:xlconstant const_3 { + CONST_VAL 65535 + CONST_WIDTH 16 +} { + dout axis_counter_1/cfg_data +} + +#Create combiner +cell xilinx.com:ip:axis_combiner comb_0 {} { + aclk pll_0/clk_out1 + aresetn slice_1/Dout + S00_AXIS axis_counter_0/M_AXIS + S01_AXIS axis_counter_1/M_AXIS +} + +# Create the tlast generator +cell labdpr:user:axis_tlast_gen tlast_gen_0 { + AXIS_TDATA_WIDTH 32 + PKT_CNTR_BITS 32 +} { + S_AXIS comb_0/M_AXIS + pkt_length slice_4/dout + aclk pll_0/clk_out1 + aresetn slice_1/dout +} + +# Create axis_dwidth_converter +cell xilinx.com:ip:axis_dwidth_converter conv_0 { + S_TDATA_NUM_BYTES.VALUE_SRC USER + S_TDATA_NUM_BYTES 4 + M_TDATA_NUM_BYTES 8 +} { + S_AXIS tlast_gen_0/M_AXIS + aclk pll_0/clk_out1 + aresetn slice_2/dout +} + +# Create axis_ram_writer +cell labdpr:user:axis_ram_writer writer_0 { + ADDR_WIDTH 16 + AXI_ID_WIDTH 3 +} { + aclk pll_0/clk_out1 + aresetn slice_2/dout + S_AXIS conv_0/M_AXIS + M_AXI ps_0/S_AXI_ACP + cfg_data slice_3/dout +} + +# Create axi_sts_register +cell labdpr:user:axi_sts_register sts_0 { + STS_DATA_WIDTH 32 + AXI_ADDR_WIDTH 32 + AXI_DATA_WIDTH 32 +} { + sts_data writer_0/sts_data +} + +addr 0x40001000 4K cfg_0/S_AXI /ps_0/M_AXI_GP0 +addr 0x40002000 4K sts_0/S_AXI /ps_0/M_AXI_GP0 + diff --git a/projects/counter_test/uio_src/Makefile b/projects/counter_test/uio_src/Makefile new file mode 100644 index 0000000..ed776e2 --- /dev/null +++ b/projects/counter_test/uio_src/Makefile @@ -0,0 +1,16 @@ +CC=gcc +FLAGS=-Wall -O3 +ARCH=arm +CROSS_COMPILE=arm-xilinx-linux-gnueabi- + +#### +PROG=counter_test +EXTRA= zynq_io.c + +all: $(PROG) + +$(PROG): $(PROG).c $(EXTRA) + $(CC) $(FLAGS) -o $(PROG) $(PROG).c $(EXTRA) -lm -lpthread + +clean: + rm -f $(PROG) diff --git a/projects/counter_test/uio_src/counter_test.c b/projects/counter_test/uio_src/counter_test.c new file mode 100644 index 0000000..1310cc6 --- /dev/null +++ b/projects/counter_test/uio_src/counter_test.c @@ -0,0 +1,92 @@ +#include "zynq_io.h" + +int main(int argc, char *argv[]) +{ + //int fd; + //unsigned int size; + uint32_t i,val=0; + uint32_t wo,wo2; + int16_t ch[4]; + + printf("ADC RECORDER test\n"); + + //initialize devices. TODO: add error checking + cfg_init(); + sts_init(); + cma_init(); + + printf("Reseting counters...\n"); + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET,0); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &= ~1,0); + printf("Reseting tlast_gen core...\n"); + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET,0); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &=~4,0); + printf("Reseting writer...\n"); + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET,0); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &= ~2,0); + + printf("Set writer address...\n"); + val=rd_reg_value(1, CFG_WR_ADDR_OFFSET,0); + printf("dev_size es: %d ...\n",dev_size); + wr_reg_value(1, CFG_WR_ADDR_OFFSET, dev_size,0); + + printf("Set number of samples...\n"); + val=rd_reg_value(1, CFG_NSAMPLES_OFFSET,0); + wr_reg_value(1, CFG_NSAMPLES_OFFSET, 65536,0); + + // wait 1 second + //sleep(1); + + // enter normal mode + // tlast_gen + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET,0); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |= 2,0); + //writer + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET,0); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |=4,0); + //counters + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET,0); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val |= 1,0); + + //val=rd_reg_value(1, STS_STATUS_OFFSET,1); + //printf("%5d\n", val); + // wait 1 second + sleep(1); + + // print IN1 and IN2 samples + for(i = 0; i < 2*65536; ++i){ + //for(i = 0; i < 65536; i+=4){ + ch[0] = *(cma_ptr + 2*i + 0); + ch[1] = *(cma_ptr + 2*i + 1); + ch[2] = *((int16_t *)(cma_ptr2 + i)); + ch[3] = *((int16_t *)(cma_ptr2 + 2*i)); + wo = *((uint32_t *)(cma_ptr + 2*i)); + wo2 = *((uint32_t *)(cma_ptr2 + i)); + // printf("%5d %5d %10d\n", ch[0], ch[1], wo); + printf("%5d %5d %10d %5d %5d %10d\n", ch[1], ch[2], wo, (int16_t)(wo&0xFFFF), (int16_t)(wo>>16), wo2); + // printf("%5d %5d %10d %5d %5d %10d\n", ch[0], ch[1], wo, ch[2], ch[3], wo2); + //printf("%5d %5d %10d\n", ch[2], ch[3], wo2); + //val=rd_reg_value(1, STS_STATUS_OFFSET,1); + //printf("#%5d\n", val); +// ch[0] = cma_ptr[2 * i + 0]; +// ch[1] = cma_ptr[2 * i + 1]; +// //wo = cma_ptr[i] +// printf("%5d %5d\n", ch[0], ch[1]); + } + //val=rd_reg_value(1, STS_STATUS_OFFSET,1); + //printf("%5d\n", val); + + //reset counters again + val=rd_reg_value(1, CFG_RESET_GRAL_OFFSET,0); + wr_reg_value(1, CFG_RESET_GRAL_OFFSET, val &= ~1,0); + // unmap and close the devices + munmap(cfg_ptr, sysconf(_SC_PAGESIZE)); + munmap(sts_ptr, sysconf(_SC_PAGESIZE)); + + close(cfg_fd); + close(sts_fd); + //printf("Saliendo ...\n"); + + return 0; + +} diff --git a/projects/counter_test/uio_src/zynq_io.c b/projects/counter_test/uio_src/zynq_io.c new file mode 100644 index 0000000..23a86c8 --- /dev/null +++ b/projects/counter_test/uio_src/zynq_io.c @@ -0,0 +1,475 @@ +#include "zynq_io.h" + +int intc_fd, cfg_fd, sts_fd, xadc_fd, mem_fd, hst0_fd, hst1_fd, cma_fd; +void *intc_ptr, *cfg_ptr, *sts_ptr, *xadc_ptr, *mem_ptr, *hst0_ptr, *hst1_ptr; +volatile int16_t *cma_ptr; +volatile uint32_t *cma_ptr2; +uint32_t dev_size; + +void dev_write(void *dev_base, uint32_t offset, int32_t value) +{ + *((volatile unsigned *)(dev_base + offset)) = value; +} + +uint32_t dev_read(void *dev_base, uint32_t offset) +{ + return *((volatile unsigned *)(dev_base + offset)); +} + +/*int dev_init(int n_dev) + { + char *uiod; = "/dev/uio1"; + + printf("Initializing device...\n"); + +// open the UIO device file to allow access to the device in user space +cfg_fd = open(uiod, O_RDWR); +if (cfg_fd < 1) { +printf("cfg_init: Invalid UIO device file:%s.\n", uiod); +return -1; +} + +dev_size = get_memory_size("/sys/class/uio/uio1/maps/map0/size"); + +// mmap the cfgC device into user space +cfg_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, cfg_fd, 0); +if (cfg_ptr == MAP_FAILED) { +printf("cfg_init: mmap call failure.\n"); +return -1; +} + +return 0; +}*/ + +int32_t rd_reg_value(int n_dev, uint32_t reg_off, uint8_t debug) +{ + int32_t reg_val; + switch(n_dev) + { + case 0: + reg_val = dev_read(intc_ptr, reg_off); + break; + case 1: + reg_val = dev_read(cfg_ptr, reg_off); + break; + case 2: + reg_val = dev_read(sts_ptr, reg_off); + break; + case 3: + reg_val = dev_read(xadc_ptr, reg_off); + break; + default: + printf("Invalid option: %d\n", n_dev); + return -1; + } + if(debug) + printf("Complete. Received data 0x%08x\n", reg_val); + //printf("Complete. Received data %d\n", reg_val); + + return reg_val; +} + +int32_t wr_reg_value(int n_dev, uint32_t reg_off, int32_t reg_val, uint8_t debug) +{ + switch(n_dev) + { + case 0: + dev_write(intc_ptr, reg_off, reg_val); + break; + case 1: + dev_write(cfg_ptr, reg_off, reg_val); + break; + case 2: + dev_write(sts_ptr, reg_off, reg_val); + break; + case 3: + dev_write(xadc_ptr, reg_off, reg_val); + break; + default: + printf("Invalid option: %d\n", n_dev); + return -1; + } + if(debug) + printf("Complete. Data written: 0x%08x\n", reg_val); + //printf("Complete. Data written: %d\n", reg_val); + + return 0; +} + +int32_t rd_cfg_status(void) +{ + //float a = 0.0382061, b = 4.11435; // For gain = 1.45 + float a = 0.0882006, b = 7.73516; // For gain = 3.2 + + printf("#Trigger Level Ch1 = %d\n", dev_read(cfg_ptr, CFG_TRLVL_1_OFFSET)); + printf("#Trigger Level Ch2 = %d\n", dev_read(cfg_ptr, CFG_TRLVL_2_OFFSET)); + //printf("#Subtrigger Ch1 = %d\n", dev_read(cfg_ptr, CFG_STRLVL_1_OFFSET)); + //printf("#Subtrigger Ch2 = %d\n", dev_read(cfg_ptr, CFG_STRLVL_2_OFFSET)); + printf("#High Voltage 1 = %.1f mV\n", a*dev_read(cfg_ptr, CFG_HV1_OFFSET)+b); + printf("#High Voltage 2 = %.1f mV\n", a*dev_read(cfg_ptr, CFG_HV2_OFFSET)+b); + printf("#Trigger Scaler 1 = %d\n", dev_read(cfg_ptr, CFG_TR_SCAL_A_OFFSET)); + printf("#Trigger Scaler 2 = %d\n", dev_read(cfg_ptr, CFG_TR_SCAL_B_OFFSET)); + if (((dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET)>>4) & 0x1) == 1) { // No GPS is present + printf("#No GPS device is present or enabled\n"); + }else{ + printf("#Using GPS data\n"); + } + if (((dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET)>>5) & 0x1) == 0) //Slave + { + printf("#Working mode is SLAVE\n"); + }else{ + printf("#Working mode is MASTER\n"); + } + printf("\n"); + printf("Status from registers complete!\n"); + return 0; +} + +static uint32_t get_memory_size(char *sysfs_path_file) +{ + FILE *size_fp; + uint32_t size; + + // open the file that describes the memory range size that is based on + // the reg property of the node in the device tree + size_fp = fopen(sysfs_path_file, "r"); + + if (!size_fp) { + printf("unable to open the uio size file\n"); + exit(-1); + } + + // get the size which is an ASCII string such as 0xXXXXXXXX and then be + // stop using the file + if(fscanf(size_fp, "0x%08X", &size) == EOF){ + printf("unable to get the size of the uio size file\n"); + exit(-1); + } + fclose(size_fp); + + return size; +} + +int intc_init(void) +{ + char *uiod = "/dev/uio0"; + + //printf("Initializing INTC device...\n"); + + // open the UIO device file to allow access to the device in user space + intc_fd = open(uiod, O_RDWR); + if (intc_fd < 1) { + printf("intc_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio0/maps/map0/size"); + + // mmap the INTC device into user space + intc_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, intc_fd, 0); + if (intc_ptr == MAP_FAILED) { + printf("intc_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int cfg_init(void) +{ + char *uiod = "/dev/uio1"; + + //printf("Initializing CFG device...\n"); + + // open the UIO device file to allow access to the device in user space + cfg_fd = open(uiod, O_RDWR); + if (cfg_fd < 1) { + printf("cfg_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio1/maps/map0/size"); + + // mmap the cfgC device into user space + cfg_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, cfg_fd, 0); + if (cfg_ptr == MAP_FAILED) { + printf("cfg_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int sts_init(void) +{ + char *uiod = "/dev/uio4"; + + //printf("Initializing STS device...\n"); + + // open the UIO device file to allow access to the device in user space + sts_fd = open(uiod, O_RDWR); + if (sts_fd < 1) { + printf("sts_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio4/maps/map0/size"); + + // mmap the STS device into user space + sts_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, sts_fd, 0); + if (sts_ptr == MAP_FAILED) { + printf("sts_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int xadc_init(void) +{ + char *uiod = "/dev/uio5"; + + //printf("Initializing XADC device...\n"); + + // open the UIO device file to allow access to the device in user space + xadc_fd = open(uiod, O_RDWR); + if (xadc_fd < 1) { + printf("xadc_init: Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio5/maps/map0/size"); + + // mmap the XADC device into user space + xadc_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, xadc_fd, 0); + if (xadc_ptr == MAP_FAILED) { + printf("xadc_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int mem_init(void) +{ + char *mem_name = "/dev/mem"; + + //printf("Initializing mem device...\n"); + + // open the UIO device file to allow access to the device in user space + mem_fd = open(mem_name, O_RDWR); + if (mem_fd < 1) { + printf("mem_init: Invalid device file:%s.\n", mem_name); + return -1; + } + + dev_size = 2048*sysconf(_SC_PAGESIZE); + + // mmap the mem device into user space + mem_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0x1E000000); + if (mem_ptr == MAP_FAILED) { + printf("mem_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +int cma_init(void) +{ + char *cma_name = "/dev/cma"; + + //printf("Initializing mem device...\n"); + + // open the UIO device file to allow access to the device in user space + cma_fd = open(cma_name, O_RDWR); + if (cma_fd < 1) { + printf("cma_init: Invalid device file:%s.\n", cma_name); + return -1; + } + + dev_size = 1024*sysconf(_SC_PAGESIZE); + + if(ioctl(cma_fd, CMA_ALLOC, &dev_size) < 0) { + perror("ioctl"); + return EXIT_FAILURE; + } + // mmap the mem device into user space + cma_ptr = mmap(NULL, 1024*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, cma_fd, 0); + cma_ptr2 = mmap(NULL, 1024*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, cma_fd, 0); + if (cma_ptr == MAP_FAILED) { + printf("cma_init: mmap call failure.\n"); + return -1; + } + + return 0; +} + +float get_voltage(uint32_t offset) +{ + int16_t value; + value = (int16_t) dev_read(xadc_ptr, offset); + // printf("The Voltage is: %lf V\n", (value>>4)*XADC_CONV_VAL); + return ((value>>4)*XADC_CONV_VAL); +} + +/*void set_voltage(uint32_t offset, int32_t value) + { +//fit after calibration. See file data_calib.txt in /ramp_test directory +// y = a*x + b +//a = 0.0382061 +//b = 4.11435 +uint32_t dac_val; +float a = 0.0382061, b = 4.11435; + +dac_val = (uint32_t)(value - b)/a; + +dev_write(cfg_ptr, offset, dac_val); +printf("The Voltage is: %d mV\n", value); +printf("The DAC value is: %d DACs\n", dac_val); +} +*/ + +void set_voltage(uint32_t offset, int32_t value) +{ + //fit after calibration. See file data_calib2.txt in /ramp_test directory + // y = a*x + b + //a = 0.0882006 + //b = 7.73516 + uint32_t dac_val; + float a = 0.0882006, b = 7.73516; + + dac_val = (uint32_t)(value - b)/a; + + dev_write(cfg_ptr, offset, dac_val); + printf("The Voltage is: %d mV\n", value); + printf("The DAC value is: %d DACs\n", dac_val); +} + +float get_temp_AD592(uint32_t offset) +{ + float value; + value = get_voltage(offset); + return ((value*1000)-273.15); +} + +//System initialization +int init_system(void) +{ + uint32_t reg_val; + + //FIXME: replace hardcoded values for defines + // set trigger_lvl_1 + dev_write(cfg_ptr,CFG_TRLVL_1_OFFSET,8190); + + // set trigger_lvl_2 + dev_write(cfg_ptr,CFG_TRLVL_2_OFFSET,8190); + + // set subtrigger_lvl_1 + dev_write(cfg_ptr,CFG_STRLVL_1_OFFSET,8190); + + // set subtrigger_lvl_2 + dev_write(cfg_ptr,CFG_STRLVL_2_OFFSET,8190); + + // set hv1 and hv2 to zero + dev_write(cfg_ptr,CFG_HV1_OFFSET,0); + dev_write(cfg_ptr,CFG_HV2_OFFSET,0); + + // reset ramp generators + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~8); + + // reset pps_gen, fifo and trigger modules + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~1); + + /* reset data converter and writer */ + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~4); + + // enter reset mode for tlast_gen + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~2); + + // set number of samples + dev_write(cfg_ptr,CFG_NSAMPLES_OFFSET, 1024 * 1024); + + // set default value for trigger scalers a and b + dev_write(cfg_ptr,CFG_TR_SCAL_A_OFFSET, 1); + dev_write(cfg_ptr,CFG_TR_SCAL_B_OFFSET, 1); + + // enter normal mode for tlast_gen + /* reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 2); + //printf("written reg_val tlast : 0x%08x\n",reg_val | 2); + // enter normal mode for pps_gen, fifo and trigger modules + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 1); + //printf("written reg_val pps_gen, fifo : 0x%08x\n",reg_val | 1); + */ + // enable false GPS + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + //printf("reg_val : 0x%08x\n",reg_val); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | FGPS_EN_MASK); + //printf("written reg_val : 0x%08x\n",reg_val | 16); + // disable + //dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~16); + //dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val & ~FGPS_EN_MASK); + //printf("written reg_val : 0x%08x\n",reg_val & ~16); + + /* // enter normal mode for data converter and writer + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 4); + //printf("written reg_val : 0x%08hx\n",reg_val | 4); + */ + // enter normal mode for ramp generators + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 8); + // enter in MASTER mode (default) + reg_val = dev_read(cfg_ptr, CFG_RESET_GRAL_OFFSET); + dev_write(cfg_ptr,CFG_RESET_GRAL_OFFSET, reg_val | 0x20); + + return 0; +} + +int enable_interrupt(void) +{ + // steps to accept interrupts -> as pg. 26 of pg099-axi-intc.pdf + //1) Each bit in the IER corresponding to an interrupt must be set to 1. + dev_write(intc_ptr,XIL_AXI_INTC_IER_OFFSET, 1); + //2) There are two bits in the MER. The ME bit must be set to enable the + //interrupt request outputs. + dev_write(intc_ptr,XIL_AXI_INTC_MER_OFFSET, XIL_AXI_INTC_MER_ME_MASK | XIL_AXI_INTC_MER_HIE_MASK); + //dev_write(dev_ptr,XIL_AXI_INTC_MER_OFFSET, XIL_AXI_INTC_MER_ME_MASK); + + //The next block of code is to test interrupts by software + //3) Software testing can now proceed by writing a 1 to any bit position + //in the ISR that corresponds to an existing interrupt input. + /* dev_write(intc_ptr,XIL_AXI_INTC_IPR_OFFSET, 1); + + for(a=0; a<10; a++) + { + wait_for_interrupt(fd, dev_ptr); + dev_write(dev_ptr,XIL_AXI_INTC_ISR_OFFSET, 1); //regenerate interrupt + } + */ + return 0; + +} + +int disable_interrupt(void) +{ + uint32_t value; + //Disable interrupt INTC0 + dev_write(intc_ptr,XIL_AXI_INTC_IER_OFFSET, 0); + //disable IRQ + value = dev_read(intc_ptr, XIL_AXI_INTC_MER_OFFSET); + dev_write(intc_ptr,XIL_AXI_INTC_MER_OFFSET, value | ~1); + //Acknowledge any previous interrupt + dev_write(intc_ptr, XIL_AXI_INTC_IAR_OFFSET, 1); + + return 0; +} + diff --git a/projects/counter_test/uio_src/zynq_io.h b/projects/counter_test/uio_src/zynq_io.h new file mode 100644 index 0000000..f5b4428 --- /dev/null +++ b/projects/counter_test/uio_src/zynq_io.h @@ -0,0 +1,156 @@ +#ifndef _ZYNQ_IO_H_ +#define _ZYNQ_IO_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> +#include <sys/ioctl.h> + +#define CMA_ALLOC _IOWR('Z', 0, uint32_t) +#define INTC_BASEADDR 0x40000000 +#define INTC_HIGHADDR 0x40000FFF + +#define CFG_BASEADDR 0x40001000 +#define CFG_HIGHADDR 0x40001FFF + +#define STS_BASEADDR 0x40002000 +#define STS_HIGHADDR 0x40002FFF + +#define XADC_BASEADDR 0x40003000 +#define XADC_HIGHADDR 0x40003FFF + +#define XIL_AXI_INTC_ISR_OFFSET 0x0 +#define XIL_AXI_INTC_IPR_OFFSET 0x4 +#define XIL_AXI_INTC_IER_OFFSET 0x8 +#define XIL_AXI_INTC_IAR_OFFSET 0xC +#define XIL_AXI_INTC_SIE_OFFSET 0x10 +#define XIL_AXI_INTC_CIE_OFFSET 0x14 +#define XIL_AXI_INTC_IVR_OFFSET 0x18 +#define XIL_AXI_INTC_MER_OFFSET 0x1C +#define XIL_AXI_INTC_IMR_OFFSET 0x20 +#define XIL_AXI_INTC_ILR_OFFSET 0x24 +#define XIL_AXI_INTC_IVAR_OFFSET 0x100 + +#define XIL_AXI_INTC_MER_ME_MASK 0x00000001 +#define XIL_AXI_INTC_MER_HIE_MASK 0x00000002 + +//CFG +#define CFG_RESET_GRAL_OFFSET 0x0 +#define CFG_WR_ADDR_OFFSET 0x4 +#define CFG_NSAMPLES_OFFSET 0x8 +#define CFG_TRLVL_1_OFFSET 0x8 +#define CFG_TRLVL_2_OFFSET 0xC +#define CFG_STRLVL_1_OFFSET 0x10 +#define CFG_STRLVL_2_OFFSET 0x14 +#define CFG_TEMPERATURE_OFFSET 0x18 +#define CFG_PRESSURE_OFFSET 0x1C +#define CFG_TIME_OFFSET 0x20 +#define CFG_DATE_OFFSET 0x24 +#define CFG_LATITUDE_OFFSET 0x28 +#define CFG_LONGITUDE_OFFSET 0x2C +#define CFG_ALTITUDE_OFFSET 0x30 +#define CFG_SATELLITE_OFFSET 0x34 +#define CFG_TR_SCAL_A_OFFSET 0x38 +#define CFG_TR_SCAL_B_OFFSET 0x3C +#define CFG_HV1_OFFSET 0x4C //DAC_PWM3 +#define CFG_HV2_OFFSET 0x48 //DAC_PWM2 +#define CFG_HV3_OFFSET 0x40 //DAC_PWM0 +#define CFG_HV4_OFFSET 0x44 //DAC_PWM1 + +//CFG Slow DAC +#define CFG_DAC_PWM0_OFFSET 0x40 +#define CFG_DAC_PWM1_OFFSET 0x44 +#define CFG_DAC_PWM2_OFFSET 0x48 +#define CFG_DAC_PWM3_OFFSET 0x4C + +#define ENBL_ALL_MASK 0xFFFFFFFF +#define RST_ALL_MASK 0x00000000 +#define RST_PPS_TRG_FIFO_MASK 0x00000001 +#define RST_TLAST_GEN_MASK 0x00000002 +#define RST_WRITER_MASK 0x00000004 +#define RST_AO_MASK 0x00000008 +#define FGPS_EN_MASK 0x00000010 + +//STS +#define STS_STATUS_OFFSET 0x0 + +//XADC +//See page 17 of PG091 +#define XADC_SRR_OFFSET 0x00 //Software reset register +#define XADC_SR_OFFSET 0x04 //Status Register +#define XADC_AOSR_OFFSET 0x08 //Alarm Out Status Register +#define XADC_CONVSTR_OFFSET 0x0C //CONVST Register +#define XADC_SYSMONRR_OFFSET 0x10 //XADC Reset Register +#define XADC_GIER_OFFSET 0x5C //Global Interrupt Enable Register +#define XADC_IPISR_OFFSET 0x60 //IP Interrupt Status Register +#define XADC_IPIER_OFFSET 0x68 //IP Interrupt Enable Register +#define XADC_TEMPERATURE_OFFSET 0x200 //Temperature +#define XADC_VCCINT_OFFSET 0x204 //VCCINT +#define XADC_VCCAUX_OFFSET 0x208 //VCCAUX +#define XADC_VPVN_OFFSET 0x20C //VP/VN +#define XADC_VREFP_OFFSET 0x210 //VREFP +#define XADC_VREFN_OFFSET 0x214 //VREFN +#define XADC_VBRAM_OFFSET 0x218 //VBRAM +#define XADC_UNDEF_OFFSET 0x21C //Undefined +#define XADC_SPLYOFF_OFFSET 0x220 //Supply Offset +#define XADC_ADCOFF_OFFSET 0x224 //ADC Offset +#define XADC_GAIN_ERR_OFFSET 0x228 //Gain Error +#define XADC_ZDC_SPLY_OFFSET 0x234 //Zynq-7000 Device Core Supply +#define XADC_ZDC_AUX_SPLY_OFFSET 0x238 //Zynq-7000 Device Core Aux Supply +#define XADC_ZDC_MEM_SPLY_OFFSET 0x23C //Zynq-7000 Device Core Memory Supply +#define XADC_VAUX_PN_0_OFFSET 0x240 //VAUXP[0]/VAUXN[0] +#define XADC_VAUX_PN_1_OFFSET 0x244 //VAUXP[1]/VAUXN[1] +#define XADC_VAUX_PN_2_OFFSET 0x248 //VAUXP[2]/VAUXN[2] +#define XADC_VAUX_PN_3_OFFSET 0x24C //VAUXP[3]/VAUXN[3] +#define XADC_VAUX_PN_4_OFFSET 0x250 //VAUXP[4]/VAUXN[4] +#define XADC_VAUX_PN_5_OFFSET 0x254 //VAUXP[5]/VAUXN[5] +#define XADC_VAUX_PN_6_OFFSET 0x258 //VAUXP[6]/VAUXN[6] +#define XADC_VAUX_PN_7_OFFSET 0x25C //VAUXP[7]/VAUXN[7] +#define XADC_VAUX_PN_8_OFFSET 0x260 //VAUXP[8]/VAUXN[8] +#define XADC_VAUX_PN_9_OFFSET 0x264 //VAUXP[9]/VAUXN[9] +#define XADC_VAUX_PN_10_OFFSET 0x268 //VAUXP[10]/VAUXN[10] +#define XADC_VAUX_PN_11_OFFSET 0x26C //VAUXP[11]/VAUXN[11] +#define XADC_VAUX_PN_12_OFFSET 0x270 //VAUXP[12]/VAUXN[12] +#define XADC_VAUX_PN_13_OFFSET 0x274 //VAUXP[13]/VAUXN[13] +#define XADC_VAUX_PN_14_OFFSET 0x278 //VAUXP[14]/VAUXN[14] +#define XADC_VAUX_PN_15_OFFSET 0x27C //VAUXP[15]/VAUXN[15] + +#define XADC_AI0_OFFSET XADC_VAUX_PN_8_OFFSET +#define XADC_AI1_OFFSET XADC_VAUX_PN_0_OFFSET +#define XADC_AI2_OFFSET XADC_VAUX_PN_1_OFFSET +#define XADC_AI3_OFFSET XADC_VAUX_PN_9_OFFSET + +#define XADC_CONV_VAL 0.00171191993362 //(A_ip/2^12)*(34.99/4.99) +#define XADC_RDIV_VAL 1.883236177 //voltage divisor in board (15k+16.983k)/16.983k = 1.88 +#define XADC_BASE_HVDIV 0.00294088 //voltage divisor in HV base board (100k/31.3Meg) = 3.194888179. The value I put here is the measured one. + +extern int intc_fd, cfg_fd, sts_fd, xadc_fd, mem_fd, hst0_fd, hst1_fd, cma_fd; +extern void *intc_ptr, *cfg_ptr, *sts_ptr, *xadc_ptr, *mem_ptr, *hst0_ptr, *hst1_ptr; +extern volatile int16_t *cma_ptr; +extern volatile uint32_t *cma_ptr2; +extern uint32_t dev_size; + +void dev_write(void *dev_base, uint32_t offset, int32_t value); +uint32_t dev_read(void *dev_base, uint32_t offset); +//int dev_init(int n_dev); +int32_t rd_reg_value(int n_dev, uint32_t reg_off, uint8_t degug); +int32_t wr_reg_value(int n_dev, uint32_t reg_off, int32_t reg_val, uint8_t debug); +int32_t rd_cfg_status(void); +int intc_init(void); +int cfg_init(void); +int sts_init(void); +int xadc_init(void); +int mem_init(void); +int cma_init(void); +float get_voltage(uint32_t offset); +void set_voltage(uint32_t offset, int32_t value); +float get_temp_AD592(uint32_t offset); +int init_system(void); +int enable_interrupt(void); +int disable_interrupt(void); + +#endif + diff --git a/projects/led_blinker/app/index.html b/projects/led_blinker/app/index.html new file mode 100644 index 0000000..11f7dfe --- /dev/null +++ b/projects/led_blinker/app/index.html @@ -0,0 +1,24 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>LED blinker</title> +<link rel="stylesheet" href="/css/main.css"> +<link rel="stylesheet" href="/css/pygments.css"> +</head> +<body> +<div id="header"> +<div id="logo"> +<a href="/">Back to all apps</a> +</div> +<div id="menu"> +<a href="https://github.com/pavel-demin/red-pitaya-notes" target="_blank">Source</a> +<a href="https://github.com/pavel-demin/red-pitaya-notes/issues" target="_blank">Issues</a> +</div> +</div> +<div id="content"> +<h1>LED blinker</h1> +<p>The LED blinker application is ready.</p> +</div> +</body> +</html> diff --git a/projects/led_blinker/app/start.sh b/projects/led_blinker/app/start.sh new file mode 100755 index 0000000..c2cb31d --- /dev/null +++ b/projects/led_blinker/app/start.sh @@ -0,0 +1,7 @@ +#! /bin/sh + +apps_dir=/media/mmcblk0p1/apps + +source $apps_dir/stop.sh + +cat $apps_dir/led_blinker/led_blinker.bit > /dev/xdevcfg diff --git a/projects/ramp_test/block_design.tcl b/projects/ramp_test/block_design.tcl new file mode 100644 index 0000000..de9b64b --- /dev/null +++ b/projects/ramp_test/block_design.tcl @@ -0,0 +1,47 @@ +source projects/base_system/block_design.tcl + +# Create proc_sys_reset +cell xilinx.com:ip:proc_sys_reset:5.0 rst_0 + +# Create axi_cfg_register +cell labdpr:user:axi_cfg_register:1.0 cfg_0 { + CFG_DATA_WIDTH 96 + AXI_ADDR_WIDTH 32 + AXI_DATA_WIDTH 32 +} + +# Create xlslice +cell xilinx.com:ip:xlslice:1.0 slice_1 { + DIN_WIDTH 96 DIN_FROM 0 DIN_TO 0 DOUT_WIDTH 1 +} { + Din cfg_0/cfg_data +} + +# Create xlslice. Change the frequency +cell xilinx.com:ip:xlslice:1.0 slice_2 { + DIN_WIDTH 96 DIN_FROM 47 DIN_TO 32 DOUT_WIDTH 16 +} { + Din cfg_0/cfg_data +} + +#Create PWM generator +cell labdpr:user:ramp_gen:1.0 ramp_gen_0 { + COUNT_NBITS 20 + COUNT_MOD 5000 + DATA_BITS 16 +} { + aclk ps_0/FCLK_CLK0 + aresetn slice_1/Dout + data_i slice_2/Dout + pwm_o dac_pwm_o +} + +# Create all required interconnections +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { + Master /ps_0/M_AXI_GP0 + Clk Auto +} [get_bd_intf_pins cfg_0/S_AXI] + +set_property RANGE 4K [get_bd_addr_segs ps_0/Data/SEG_cfg_0_reg0] +set_property OFFSET 0x40000000 [get_bd_addr_segs ps_0/Data/SEG_cfg_0_reg0] + diff --git a/projects/ramp_test/ramp_test.c b/projects/ramp_test/ramp_test.c new file mode 100644 index 0000000..e4dc573 --- /dev/null +++ b/projects/ramp_test/ramp_test.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <sys/mman.h> +#include <fcntl.h> + +#define VERSION "0.1" +int main(int argc, char *argv[]) +{ + int mfd, i; + uint32_t wo; + int16_t ch[2]; + void *cfg, *ram; + char *name = "/dev/mem"; + int32_t mtd_dp = 0, mtd_cdp = 0, mtd_pulse_cnt = 0, mtd_pulse_pnt = 0; + + printf("%d\n",argc); + + if (argc<1) { + printf("%s version %s\n",argv[0],VERSION); + printf("The clock freq. is 143MHz and the PWM signal freq. is 1.06 Hz (T aprox. 0.93s)\n"); + printf("Syntax: %s [pwm value](from 0 to 2**27-1)\n ex: %s 10000 \n", argv[0], argv[0]); + printf("for ~ 70 us PWM signal in state '1' and the rest in state \n"); + printf("'0' up to ~0.94s)\n"); + exit(EXIT_FAILURE); + } + + if((mfd = open(name, O_RDWR)) < 0) + { + perror("open"); + return 1; + } + + cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, mfd, 0x40000000); + + // reset pwm_gen + *((uint32_t *)(cfg + 0)) &= ~1; + *((uint32_t *)(cfg + 0)) |= 1; + + + // set trigger_lvl_a + *((uint32_t *)(cfg + 4)) = atoi(argv[1]); + + + // print IN1 and IN2 samples +// for(i = 0; i < 64; ++i) +// { +// ch[0] = *((int16_t *)(cfg + i)); +// //ch[1] = *((int16_t *)(ram + 4*i + 2)); +// printf("%5d \n", (ch[0]>>4)); +// } + + + munmap(cfg, sysconf(_SC_PAGESIZE)); + + return 0; +} diff --git a/projects/xadc_test/block_design.tcl b/projects/xadc_test/block_design.tcl new file mode 100644 index 0000000..ecf3342 --- /dev/null +++ b/projects/xadc_test/block_design.tcl @@ -0,0 +1,49 @@ +source projects/base_system/block_design.tcl + +# Create proc_sys_reset +cell xilinx.com:ip:proc_sys_reset:5.0 rst_0 + +# Create xadc +cell xilinx.com:ip:xadc_wiz:3.3 xadc_wiz_0 { + XADC_STARUP_SELECTION channel_sequencer + OT_ALARM false + USER_TEMP_ALARM false + VCCINT_ALARM false + VCCAUX_ALARM false + ENABLE_VCCPINT_ALARM false + ENABLE_VCCPAUX_ALARM false + ENABLE_VCCDDRO_ALARM false + CHANNEL_ENABLE_CALIBRATION true + CHANNEL_ENABLE_TEMPERATURE true + CHANNEL_ENABLE_VCCINT true + CHANNEL_ENABLE_VP_VN true + CHANNEL_ENABLE_VAUXP0_VAUXN0 true + CHANNEL_ENABLE_VAUXP1_VAUXN1 true + CHANNEL_ENABLE_VAUXP8_VAUXN8 true + CHANNEL_ENABLE_VAUXP9_VAUXN9 true + AVERAGE_ENABLE_VP_VN true + AVERAGE_ENABLE_VAUXP0_VAUXN0 true + AVERAGE_ENABLE_VAUXP1_VAUXN1 true + AVERAGE_ENABLE_VAUXP8_VAUXN8 true + AVERAGE_ENABLE_VAUXP9_VAUXN9 true + AVERAGE_ENABLE_TEMPERATURE true + AVERAGE_ENABLE_VCCINT true + EXTERNAL_MUX_CHANNEL VP_VN + SINGLE_CHANNEL_SELECTION TEMPERATURE +} {} + +connect_bd_intf_net [get_bd_intf_ports Vp_Vn] [get_bd_intf_pins xadc_wiz_0/Vp_Vn] +connect_bd_intf_net [get_bd_intf_ports Vaux0] [get_bd_intf_pins xadc_wiz_0/Vaux0] +connect_bd_intf_net [get_bd_intf_ports Vaux1] [get_bd_intf_pins xadc_wiz_0/Vaux1] +connect_bd_intf_net [get_bd_intf_ports Vaux8] [get_bd_intf_pins xadc_wiz_0/Vaux8] +connect_bd_intf_net [get_bd_intf_ports Vaux9] [get_bd_intf_pins xadc_wiz_0/Vaux9] + +# Create all required interconnections +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { + Master /ps_0/M_AXI_GP0 + Clk Auto +} [get_bd_intf_pins xadc_wiz_0/s_axi_lite] + +set_property range 4K [get_bd_addr_segs {ps_0/Data/SEG_xadc_wiz_0_Reg}] +set_property offset 0x40001000 [get_bd_addr_segs {ps_0/Data/SEG_xadc_wiz_0_Reg}] + diff --git a/projects/xadc_test/xadc_test.c b/projects/xadc_test/xadc_test.c new file mode 100644 index 0000000..1bdbc6c --- /dev/null +++ b/projects/xadc_test/xadc_test.c @@ -0,0 +1,119 @@ +/* + * devmem2.c: Simple program to read/write from/to any location in memory. + * + * Copyright (C) 2000, Jan-Derk Bakker (jdb@lartmaker.nl) + * + * + * This software has been developed for the LART computing board + * (http://www.lart.tudelft.nl/). The development has been sponsored by + * the Mobile MultiMedia Communications (http://www.mmc.tudelft.nl/) + * and Ubiquitous Communications (http://www.ubicom.tudelft.nl/) + * projects. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <signal.h> +#include <fcntl.h> +#include <ctype.h> +#include <termios.h> +#include <sys/types.h> +#include <sys/mman.h> + +#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ + __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0) + +#define MAP_SIZE 4096UL +#define MAP_MASK (MAP_SIZE - 1) + +int main(int argc, char **argv) { + int fd; + void *map_base, *virt_addr; + unsigned long read_result, writeval; + off_t target; + int access_type = 'w'; + + if(argc < 2) { + fprintf(stderr, "\nUsage:\t%s { address } [ type [ data ] ]\n" + "\taddress : memory address to act upon\n" + "\ttype : access operation type : [b]yte, [h]alfword, [w]ord\n" + "\tdata : data to be written\n\n", + argv[0]); + exit(1); + } + target = strtoul(argv[1], 0, 0); + + if(argc > 2) + access_type = tolower(argv[2][0]); + + + if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL; + printf("/dev/mem opened.\n"); + fflush(stdout); + + /* Map one page */ + map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK); + if(map_base == (void *) -1) FATAL; + printf("Memory mapped at address %p.\n", map_base); + fflush(stdout); + + virt_addr = map_base + (target & MAP_MASK); + switch(access_type) { + case 'b': + read_result = *((unsigned char *) virt_addr); + break; + case 'h': + read_result = *((unsigned short *) virt_addr); + break; + case 'w': + read_result = *((unsigned long *) virt_addr); + break; + default: + fprintf(stderr, "Illegal data type '%c'.\n", access_type); + exit(2); + } + printf("Value at address 0x%X (%p): 0x%X\n", target, virt_addr, read_result); + fflush(stdout); + + if(argc > 3) { + writeval = strtoul(argv[3], 0, 0); + switch(access_type) { + case 'b': + *((unsigned char *) virt_addr) = writeval; + read_result = *((unsigned char *) virt_addr); + break; + case 'h': + *((unsigned short *) virt_addr) = writeval; + read_result = *((unsigned short *) virt_addr); + break; + case 'w': + *((unsigned long *) virt_addr) = writeval; + read_result = *((unsigned long *) virt_addr); + break; + } + printf("Written 0x%X; readback 0x%X\n", writeval, read_result); + fflush(stdout); + } + + if(munmap(map_base, MAP_SIZE) == -1) FATAL; + close(fd); + return 0; +} diff --git a/projects/xadc_test/xadc_uio.c b/projects/xadc_test/xadc_uio.c new file mode 100644 index 0000000..7d35b0c --- /dev/null +++ b/projects/xadc_test/xadc_uio.c @@ -0,0 +1,266 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <poll.h> +#include <signal.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> + +//See page 17 of PG091 +#define XADC_SRR_OFFSET 0x00 //Software reset register +#define XADC_SR_OFFSET 0x04 //Status Register +#define XADC_AOSR_OFFSET 0x08 //Alarm Out Status Register +#define XADC_CONVSTR_OFFSET 0x0C //CONVST Register +#define XADC_SYSMONRR_OFFSET 0x10 //XADC Reset Register +#define XADC_GIER_OFFSET 0x5C //Global Interrupt Enable Register +#define XADC_IPISR_OFFSET 0x60 //IP Interrupt Status Register +#define XADC_IPIER_OFFSET 0x68 //IP Interrupt Enable Register +#define XADC_TEMPERATURE_OFFSET 0x200 //Temperature +#define XADC_VCCINT_OFFSET 0x204 //VCCINT +#define XADC_VCCAUX_OFFSET 0x208 //VCCAUX +#define XADC_VPVN_OFFSET 0x20C //VP/VN +#define XADC_VREFP_OFFSET 0x210 //VREFP +#define XADC_VREFN_OFFSET 0x214 //VREFN +#define XADC_VBRAM_OFFSET 0x218 //VBRAM +#define XADC_UNDEF_OFFSET 0x21C //Undefined +#define XADC_SPLYOFF_OFFSET 0x220 //Supply Offset +#define XADC_ADCOFF_OFFSET 0x224 //ADC Offset +#define XADC_GAIN_ERR_OFFSET 0x228 //Gain Error +#define XADC_ZDC_SPLY_OFFSET 0x234 //Zynq-7000 Device Core Supply +#define XADC_ZDC_AUX_SPLY_OFFSET 0x238 //Zynq-7000 Device Core Aux Supply +#define XADC_ZDC_MEM_SPLY_OFFSET 0x23C //Zynq-7000 Device Core Memory Supply +#define XADC_VAUX_PN_0_OFFSET 0x240 //VAUXP[0]/VAUXN[0] +#define XADC_VAUX_PN_1_OFFSET 0x244 //VAUXP[1]/VAUXN[1] +#define XADC_VAUX_PN_2_OFFSET 0x248 //VAUXP[2]/VAUXN[2] +#define XADC_VAUX_PN_3_OFFSET 0x24C //VAUXP[3]/VAUXN[3] +#define XADC_VAUX_PN_4_OFFSET 0x250 //VAUXP[4]/VAUXN[4] +#define XADC_VAUX_PN_5_OFFSET 0x254 //VAUXP[5]/VAUXN[5] +#define XADC_VAUX_PN_6_OFFSET 0x258 //VAUXP[6]/VAUXN[6] +#define XADC_VAUX_PN_7_OFFSET 0x25C //VAUXP[7]/VAUXN[7] +#define XADC_VAUX_PN_8_OFFSET 0x260 //VAUXP[8]/VAUXN[8] +#define XADC_VAUX_PN_9_OFFSET 0x264 //VAUXP[9]/VAUXN[9] +#define XADC_VAUX_PN_10_OFFSET 0x268 //VAUXP[10]/VAUXN[10] +#define XADC_VAUX_PN_11_OFFSET 0x26C //VAUXP[11]/VAUXN[11] +#define XADC_VAUX_PN_12_OFFSET 0x270 //VAUXP[12]/VAUXN[12] +#define XADC_VAUX_PN_13_OFFSET 0x274 //VAUXP[13]/VAUXN[13] +#define XADC_VAUX_PN_14_OFFSET 0x278 //VAUXP[14]/VAUXN[14] +#define XADC_VAUX_PN_15_OFFSET 0x27C //VAUXP[15]/VAUXN[15] + +#define XADC_AI0_OFFSET XADC_VAUX_PN_8_OFFSET +#define XADC_AI1_OFFSET XADC_VAUX_PN_0_OFFSET +#define XADC_AI2_OFFSET XADC_VAUX_PN_1_OFFSET +#define XADC_AI3_OFFSET XADC_VAUX_PN_9_OFFSET + +#define XADC_CONV_VAL 0.00171191993362 +#define XADC_RDIV_VAL 1.798 //voltage divisor in board (15k+16.983k)/16.983k + +int interrupted = 0; + +void signal_handler(int sig) +{ + interrupted = 1; +} + +inline void dev_write(void *dev_base, unsigned int offset, unsigned int value) +{ + *((volatile unsigned *)(dev_base + offset)) = value; +} + +inline unsigned int dev_read(void *dev_base, unsigned int offset) +{ + return *((volatile unsigned *)(dev_base + offset)); +} + +/*int wait_for_interrupt(int fd_int, void *dev_ptr) + { + static unsigned int count = 0, bntd_flag = 0, bntu_flag = 0; + int flag_end=0; + int pending = 0; + int reenable = 1; + unsigned int reg; + unsigned int value; + uint32_t info = 1; // unmask + + ssize_t nb = write(fd_int, &info, sizeof(info)); + if (nb != (ssize_t)sizeof(info)) { + perror("write"); + close(fd_int); + exit(EXIT_FAILURE); + } + +// block (timeout for poll) on the file waiting for an interrupt +struct pollfd fds = { +.fd = fd_int, +.events = POLLIN, +}; + +int ret = poll(&fds, 1, 8000); +printf("ret is : %d\n", ret); +if (ret >= 1) { +nb = read(fd_int, &info, sizeof(info)); +if (nb == (ssize_t)sizeof(info)) { +// Do something in response to the interrupt. +value = dev_read(dev_ptr, XIL_AXI_INTC_IPR_OFFSET); +if ((value & 0x00000001) != 0) { +dev_write(dev_ptr, XIL_AXI_INTC_IAR_OFFSET, 1); +printf("Interrupt #%u!\n", info); +} +} else { +perror("poll()"); +close(fd_int); +exit(EXIT_FAILURE); +} +} + +return ret; +}*/ + +unsigned int get_memory_size(char *sysfs_path_file) +{ + FILE *size_fp; + unsigned int size; + + // open the file that describes the memory range size that is based on the + // reg property of the node in the device tree + + size_fp = fopen(sysfs_path_file, "r"); + + if (!size_fp) { + printf("unable to open the uio size file\n"); + exit(-1); + } + + // get the size which is an ASCII string such as 0xXXXXXXXX and then be stop + // using the file + + fscanf(size_fp, "0x%08X", &size); + fclose(size_fp); + + return size; +} + +/*void *thread_isr(void *p) + { + wait_for_interrupt(fd, dev_ptr); + + }*/ + +int main(int argc, char *argv[]) +{ + int fd; + char *uiod = "/dev/uio3"; + void *dev_ptr; + int dev_size; + int ocm_size; + int i, p=0,a; + unsigned int val; + int16_t value; + float rvalue; + pthread_t t1; + + + signal(SIGINT, signal_handler); + + printf("INTC UIO int test.\n"); + + // open the UIO device file to allow access to the device in user space + + fd = open(uiod, O_RDWR); + if (fd < 1) { + printf("Invalid UIO device file:%s.\n", uiod); + return -1; + } + + dev_size = get_memory_size("/sys/class/uio/uio3/maps/map0/size"); + + // mmap the INTC device into user space + + dev_ptr = mmap(NULL, dev_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (dev_ptr == MAP_FAILED) { + printf("mmap call failure.\n"); + return -1; + } + + value = (int16_t) dev_read(dev_ptr, XADC_AI0_OFFSET); + printf("The Voltage at pin AI0 is: %lf V\n", (value>>4)*XADC_CONV_VAL*XADC_RDIV_VAL); + value = (int16_t) dev_read(dev_ptr, XADC_AI1_OFFSET); + printf("The Voltage at pin AI1 is: %lf V\n", (value>>4)*XADC_CONV_VAL*XADC_RDIV_VAL); + value = (int16_t) dev_read(dev_ptr, XADC_AI2_OFFSET); + printf("The Voltage at pin AI2 is: %lf V\n", (value>>4)*XADC_CONV_VAL*XADC_RDIV_VAL); + value = (int16_t) dev_read(dev_ptr, XADC_AI3_OFFSET); + printf("The Voltage at pin AI3 is: %lf V\n", (value>>4)*XADC_CONV_VAL*XADC_RDIV_VAL); + + //Temperature read + value = (uint16_t) dev_read(dev_ptr, XADC_TEMPERATURE_OFFSET); + printf("The internal temperature is: %lf degC\n", (((value>>4)*503.975)/65536) - 273.15); + printf("The internal temperature is: %d degC\n", (value>>4)); + + //Supply coefficient offset + value = (int16_t) dev_read(dev_ptr, XADC_SPLYOFF_OFFSET); + printf("The supply coeff. offset is: %04x \n", value); + //VCCINT read + value = (int16_t) dev_read(dev_ptr, XADC_VPVN_OFFSET); + printf("The internal VCCINT is: %lf V\n", (((value>>4))/4096)*3.0); + // steps to accept interrupts -> as pg. 26 of pg099-axi-intc.pdf + //1) Each bit in the IER corresponding to an interrupt must be set to 1. + //dev_write(dev_ptr,XIL_AXI_INTC_IER_OFFSET, 1); + //2) There are two bits in the MER. The ME bit must be set to enable the + //interrupt request outputs. + //dev_write(dev_ptr,XIL_AXI_INTC_MER_OFFSET, XIL_AXI_INTC_MER_ME_MASK | XIL_AXI_INTC_MER_HIE_MASK); + // dev_write(dev_ptr,XIL_AXI_INTC_MER_OFFSET, XIL_AXI_INTC_MER_ME_MASK); + + //The next block of code is to test interrupts by software + //3) Software testing can now proceed by writing a 1 to any bit position + //in the ISR that corresponds to an existing interrupt input. + // dev_write(dev_ptr,XIL_AXI_INTC_ISR_OFFSET, 1); + + // for(a=0; a<10; a++) + // { + // wait_for_interrupt(fd, dev_ptr); + // dev_write(dev_ptr,XIL_AXI_INTC_ISR_OFFSET, 1); //regenerate interrupt + // } + // + // + + //while(!interrupted) wait_for_interrupt(fd, dev_ptr); + + // printf("\n\n\n"); + // printf("STS: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_ISR_OFFSET)); + // printf("IPR: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_IPR_OFFSET)); + // printf("IER: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_IER_OFFSET)); + // printf("IAR: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_IAR_OFFSET)); + // printf("SIE: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_SIE_OFFSET)); + // printf("CIE: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_CIE_OFFSET)); + // printf("IVR: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_IVR_OFFSET)); + // printf("MER: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_MER_OFFSET)); + // printf("IMR: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_IMR_OFFSET)); + // printf("ILR: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_ILR_OFFSET)); + // printf("IVAR: 0x%08d\n",dev_read(dev_ptr, XIL_AXI_INTC_IVAR_OFFSET)); + + // dev_write(dev_ptr, INTC_TRI_OFFSET, 0); + // dev_write(dev_ptr, INTC_TRI2_OFFSET, 0xF); + // + // // enable the interrupts from the INTC + // + // dev_write(dev_ptr, INTC_GLOBAL_IRQ, 0x80000000); + // dev_write(dev_ptr, INTC_IRQ_CONTROL, 2); + // + // pthread_create(&t1,NULL,thread_isr,NULL); + // // wait for interrupts from the INTC + // + // while (!interrupted) { + // + // } + // + // // unmap the INTC device + + munmap(dev_ptr, dev_size); + close(fd); + + return 0; +} -- GitLab