theAsker

Members
  • Content Count

    36
  • Joined

  • Last visited

Everything posted by theAsker

  1. theAsker

    read EOC bare-metal

    Hi @jpeyron thanks for your answer. both examples are looking very good. The problem is only, that the interrupt isn't working. Do I have to add the connection in the block diagram from eos_out to the zynq-block or from iip2intc_irpt? I also add my code at the bottom, maybe you can find my mistake! If it is correctly working at the end, I also will give you my project for other users. Because I think this is a very useful example at the end. #include <stdio.h> #include "platform.h" #include "xparameters.h" //#include "xgpio.h" #include "xadcps.h" #include "xscugic.h" #include "xil_exception.h" #include "xil_printf.h" // Parameter definitions #define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID #define XADC_DEVICE_ID XPAR_PS7_XADC_0_DEVICE_ID #define INTC_XADC_INTERRUPT_ID XPAR_FABRIC_XADC_WIZ_0_IP2INTC_IRPT_INTR u32 XAdc_INT = 0x000000030; //Bit Mask of enabled interrupts of XADC //EOS and EOC enabled u32 test; XAdcPs XAdcInst; XScuGic INTCInst; static int value; //----------------------------------------------------------------- // PROTOTYPE FUNCTIONS //----------------------------------------------------------------- static void XADC_Intr_Handler(void *baseaddr_p); static int InterruptSystemSetup(XScuGic *XScuGicInstancePtr); static int IntcInitFunction(u16 DeviceId, XAdcPs *XAdcInstancePtr); //----------------------------------------------------------------- // INTERRUPT HANDLER FUNCTIONS // - called by the XADC interrupt // - toggles the value //----------------------------------------------------------------- void XADC_Intr_Handler(void *InstancePtr) { // Disable XADC interrupts XAdcPs_IntrDisable(&XAdcInst, XAdc_INT); if ((XAdcPs_IntrGetStatus(&XAdcInst) & XAdc_INT) != XAdc_INT) { return; } // Increment counter based on button value // Reset if center button pressed if(value != 1) { value = value + 1; } else { value = 0; } printf("value is %i\n", value); (void)XAdcPs_IntrClear(&XAdcInst, XAdc_INT); // Enable XADC interrupts XAdcPs_IntrEnable(&XAdcInst, XAdc_INT); } //----------------------------------------------------------------- // INITIAL SETUP FUNCTIONS //----------------------------------------------------------------- int InterruptSystemSetup(XScuGic *XScuGicInstancePtr) { // Enable interrupt XAdcPs_IntrEnable(&XAdcInst, XAdc_INT); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, XScuGicInstancePtr); Xil_ExceptionEnable(); return XST_SUCCESS; } int IntcInitFunction(u16 DeviceId, XAdcPs *XAdcInstancePtr) { XScuGic_Config *IntcConfig; int status; // Interrupt controller initialization IntcConfig = XScuGic_LookupConfig(DeviceId); status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress); if (status != XST_SUCCESS) { return XST_FAILURE; } // Call to interrupt setup status = InterruptSystemSetup(&INTCInst); if (status != XST_SUCCESS) { return XST_FAILURE; } // Connect XADC interrupt to handler status = XScuGic_Connect(&INTCInst, INTC_XADC_INTERRUPT_ID, (Xil_ExceptionHandler)XADC_Intr_Handler, (void *)XAdcInstancePtr); if (status != XST_SUCCESS) { return XST_FAILURE; } // Enable XADC interrupts XAdcPs_IntrEnable(XAdcInstancePtr, XAdc_INT); // Enable XADC and timer interrupts in the controller XScuGic_Enable(&INTCInst, INTC_XADC_INTERRUPT_ID); return XST_SUCCESS; } int main() { init_platform(); int status; XAdcPs_Config *XADC_Config; //--------------------------------------------------------- // INITIALIZE THE PERIPHERALS & SET DIRECTION OF GPIO //--------------------------------------------------------- // Initialize Push Buttons XADC_Config = XAdcPs_LookupConfig(XPAR_PS7_XADC_0_DEVICE_ID); status = XAdcPs_CfgInitialize(&XAdcInst, XADC_Config, XADC_Config->BaseAddress); if (status != XST_SUCCESS) { return XST_FAILURE; } XAdcPs_SelfTest(&XAdcInst); test = XAdcPs_IntrGetStatus(&XAdcInst); // Initialize interrupt controller status = IntcInitFunction(INTC_DEVICE_ID, &XAdcInst); if (status != XST_SUCCESS) { return XST_FAILURE; } printf("%u\n", test); while(1) { ; } return 0; }
  2. theAsker

    reading XADC from user space

    I have to check this. Will there be problems, when the value always will change?
  3. theAsker

    Program code on PetaLinux

    Hello! Here is another newbie question from me! I am having a running hardware project from Vivado, and I also debugged bare metal code with SDK. Both was running perfectly. Now I also got a PetaLinux (v2017.4) run on my Zybo Z7-20. So far so good. First I thought, that I could only paste the c code on PetaLinux, compile it and let it run. But of course it didn't worked because I used bare metal code. I wrote already that I have to add drivers to the device tree. Here are my problems/questions: 1) I wrote something the following files: system-user.dtsi, zynq-7000.dtsi, system-top.dts and system-conf.dtsi As I wrote I am only allowed to change stuff in the system-user.dtsi file. But when I compare the driver code from your Zybo Z7-20 and the stuff I found in the internet. It looks completly different. So where and what do I have add? I wrote that I have to enable the kernel configuration (where and how)? Am I doing this with petalinux-config -c kernel, is it also possible that when I use my own hardwaretarget for PetaLinux creating , that the enabeling of the drivers happened already? 2) I want to send the voltage values over ethernet, so do I need one or two drivers (XADC-driver or XADC + ethernet-driver) for it and also a gpio driver, right? Is there code for Zybo Z7-20 somewhere existing, or where can I find some code that is fitting? I made more trys but never the petalinux-build was successfully. Thanks again for your help and time, it is always totally helpful! A+ for your job, helping a totally newbie ;-) greetings,
  4. theAsker

    Configuration: XADC

    Hello everyone! I bought the Zybo Z7-20 board, and my aim is to convert 2 analog signals to digital signals via XADC in an simultaneous wy. For this I want to use the bare-metal programming in bipolar-mode (I am using Vivado IDE & SDK 2017.4). In the library xadcps.h I found nothing about the configuration to bipolar mode. Can anyone help me, telling which functions I need and how do I have to configurate them? Is there an example existing? Thanks for all help!
  5. theAsker

    Configuration: XADC

    I found the mistake. It is really a mess that it took me arround 6 hours to figure out, that I am reading to the wrong channel. Does someone know if bipolar mode with simultaneous sampling is slower than unipolar mode with simultaneous sampling
  6. theAsker

    Configuration: XADC

    I enabled in the XADC Wizard Block for Vaux6 and Vaux14 (my channels) bipolar. -no configurations now, only initialisation is added in the bare-metal code- How if I let read the channels i get much smaller values. Raw value is arround 350 now. Before that, the value was arround 1250 (330mV DC is connected). (Update: If I let the two inputs open, I also measure the same) So I think there is something happening in the conversion. But surly not the right .... Also if I change the cables + to - and - to + so I should measure -330mV, i get the same raw-value. Does someone have an idea, why?
  7. theAsker

    Configuration: XADC

    I don't understand exactly what, I have to change? Could you help me here. There is for the XADC Wizard block the option to enable bipolar channels. But in the case, I am doing this, also nothing is happening... analog common mode is not interesting for me, cause I want my voltage +-0.5V arround 0V
  8. theAsker

    Configuration: XADC

    I added now all kind of configurations: XAdcPs_WriteInternalReg(xadc_ptr, XADCPS_CFR0_OFFSET, 0x8400); //bipolar mode XAdcPs_WriteInternalReg(xadc_ptr, XADCPS_CFR1_OFFSET, 0x4F0F); XAdcPs_WriteInternalReg(xadc_ptr, XADCPS_CFR2_OFFSET, 0x0400); In the first code line, the bipolar should be enabled. But if I change now the two cables of my input, the raw_values stays the same. Do you know, where my problem is?
  9. theAsker

    Program code on PetaLinux

    I want to map the XADC from user space. I use for this: #define START_ADDRESS_XADC 0x43C00000 int fd = open("/dev/mem", O_RDWR|O_SYNC); char *ptr = (char *)mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, START_ADDRESS_XADC); when I want to write now to the registers like: ptr[ 0x40 ] = 0x8200; And I read the address before writing, it returns a 0. After writing, also a 0. So I think, a don't have permissions to write to this address. Why and how do I fix that?
  10. theAsker

    Program code on PetaLinux

    update: i figured out, that I can not write to the XADC registers the configuration. Can someone tell me why?
  11. theAsker

    Program code on PetaLinux

    Thanks for the response! About working with /dev/iio:deviceX it isn't writte so much down. And reading from files is in my application to slow. So I am back at my solution way with mapping from /dev/mem. So for it is working correctly. I am possible to map. But if i let the code run. I only get 0 for voltages. I read something, that you have to disable the driver. I tried it both ways, but nothing happend. Maybe you could have a look over my code and you're seeing my mistake right now. #include <stdio.h> #include <stdlib.h> #define XADC_START_ADDR 0x43C00000 #define XADC_END_ADDR 0x43C0FFFF #define XADC_SIZE (XADC_END_ADDR - XADC_START_ADDR) #define UINT16 unsigned short #define UINT32 unsigned long int main () { int fd = open("/dev/mem", O_RDWR|O_SYNC); UINT16 test; if (fd == -1) { printf("Error: no open /dev/mem\n"); return -1; } char *xadc_addr = (char *)mmap(0, XADC_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, XADC_START_ADDR); if (xadc_addr == MAP_FAILED) { printf("Error: no mmap\n"); return -1; } //here could be the problem, but if I add the enable, i get the error: "segmentation fault" //enable: JTAG DRP (for measure external voltages) //*((volatile UINT32 *)(xadc_addr + 0x02)) = 0x0001; if(*((volatile UINT32 *)(xadc_addr + 0x02)) == 0x0001) { printf("Error: enable for external voltagemessurement"); return -1; } //continuous sampling mode in config_register0 *((volatile UINT16 *)(xadc_addr + 0x40)) |= 0x0400; if (*((volatile UINT16 *)(xadc_addr + 0x40)) == 0x0400) { printf("continuous sampling mode\n"); return -1; } //UINT16 volatile* pReg = (UINT16 volatile*)(xadc_addr + 0x40); //UINT16 val = *pReg; //printf("Register 40 is %u\n", val); //simultaneous mode in config_register1 *((volatile UINT16 *)(xadc_addr + 0x41)) |= 0x4000; if (*((volatile UINT16 *)(xadc_addr + 0x41)) == 0x4000) { printf("Error: no configuration of simultaneous mode\n"); return -1; } //enable calibration *((volatile UINT16 *)(xadc_addr + 0x48)) |= 0x0001; if (*((volatile UINT16 *)(xadc_addr + 0x41)) == 0x0001) { printf("Error: enable calibration\n"); return -1; } //ADC powered up and ADC-Clock = DCLK/2 in config_register2 *((volatile UINT16 *)(xadc_addr + 0x42)) |= 0x0400; if (*((volatile UINT16 *)(xadc_addr + 0x42)) == 0x0400) { printf("Error: ADC powered up and ADC-Clock = DCLK/2\n"); return -1; } //enable channel 6 and 14 for simultaneous mode *((volatile UINT16 *)(xadc_addr + 0x49)) |= 0x4000; if (*((volatile UINT16 *)(xadc_addr + 0x49)) == 0x4000) { printf("Error: simultaneous mode for channel 6 and 14\n"); return -1; } //enable flags *((volatile UINT16 *)(xadc_addr + 0x3F)) |= 0x0400; if(*((volatile UINT16 *)(xadc_addr + 0x3F)) == 0x0400) { printf("Error: enable JTAG_XADC\n"); return -1; } //Read: channel 6 unsigned int val1 = *((volatile UINT16 *)(xadc_addr + 0x16)); printf("channel 6: %u\n", val1); printf("successful test\n"); close(fd); return 0; } thanks for all help!
  12. theAsker

    Program code on PetaLinux

    Hello, I have some questions about application code of linux, for reading the external voltages. 1) At the moment I use the c++ commands: file.read("path"); then file >> array; and at least file.close(); It there a much more gentil way to solve it. For example mmaping the registers directly to PS. I thought about using the "GPIO" mapping function for reading ports: *((volatile unsigned *)(gpio_base + offset)); Is this possible. And if yes, how will i figure out the gpio_base (of course I mean here the xadc_base) and the necessary offset? 2) Is there the possibility to do the same with EOS (interrupt if the converting worked)? thanks for your help!
  13. theAsker

    Program code on PetaLinux

    Hi! Thank you for your answer! I read now something and found out, that the interrupt from the xadc block is not as i expected. Do you have an idea, how I can (write a c++ code) read the external voltages so that i don't miss a value? Thought about adding in the block design a clock devider and then connect it via UIO to use it then as an interrupt? Do you have another idea, or how do you solve it, getting really all voltages read, you want?
  14. theAsker

    Program code on PetaLinux

    The important thing here is: I want an event driven sampling. so always when a new sample value is there, i want that it will be read! And it is absolutly not clear for me how to do it! I am really a newbie to this and I am feeling lost.... update question: in the path: /sys/bus/iio/devices/trigger1/ there is uevent. Is this my trigger? or when is the value inside uevent not 0! What is this uevent?
  15. theAsker

    Program code on PetaLinux

    Now I am also a bit confused. Cause I don't know which xadcread.cpp file you mean. To explain my problem a bit more: At the moment I read a voltage with the following code: myvoltageIR.open("/sys/bus/iio/devices/iio\:device1/in_voltage9_vaux14_raw"); myvoltageIR >> voltage; myvoltageIR.close(); But know I want to do this only, when I get an interrupt from XADC. I also see, that there is an interrupt available: Cause if I do the following: $ cat /proc/interrupt \snip 46: 0 0 GIC-0 85 Level 43c00000.xadc_wiz \snip My problem now is, how do I build a c++ code/problem, that reads that interrupt and only reads the voltage, when an interrupt is available.
  16. theAsker

    Program code on PetaLinux

    Thank you for your Answer! Are you having an c/c++ - example, how I can read the external voltages controlled via the interrupt with my petalinux?
  17. theAsker

    Program code on PetaLinux

    I get now the correct voltages. I had one mistake in the XADC configuration. But with the help of another post of you @sbobrowicz in an other thread, I was able to fix the problem. I have two more questions: 1) If I want to safe the voltage values in a txt-file I am not able to read all values. I think the problem is, that my code works to slowly, or the linux system is to slowly. Is there a way, to make the linux more quickly. Or are you having a hint how to write all values (with 1 MSPS) to a textfile, to send it afterwards? 2) There is a file called sample_frequency int the path /sys/bus/iio/devices/iio\:device1/ . I think this is the place to change the sample frequency. The value is very, very big. What is the value I have to calculate to change the sampling frequency to 320kSPS? thanks for a lot of help!
  18. theAsker

    Program code on PetaLinux

    Hello! I was able to fix the problem. I only had to add an interrupt to the bloc diagram and also to the device driver. But now I have a now problem. The voltages I read are not correct. And I don't know why. In the attachment you can see my code for testing. Is someone having a plan, why I am having this effect? My driver is here: &xadc_wiz_0 { interrupts = <0 53 4>; interrupt-parent = <0x1>; clocks = <&clkc 15>; xlnx,channels { #address-cells = <1>; #size-cells = <0>; channelJA4@7 { reg = <7>; }; channelJA1@15 { reg = <15>; }; }; }; My constraints are: set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { Vaux14_0_v_p }]; #IO_L21P_T3_DQS_AD14P_35 Sch=JA1_R_p #set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L22P_T3_AD7P_35 Sch=JA2_R_P #set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L24P_T3_AD15P_35 Sch=JA3_R_P set_property -dict { PACKAGE_PIN K14 IOSTANDARD LVCMOS33 } [get_ports { Vaux6_0_v_p }]; #IO_L20P_T3_AD6P_35 Sch=JA4_R_P set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { Vaux14_0_v_n }]; #IO_L21N_T3_DQS_AD14N_35 Sch=JA1_R_N #set_property -dict { PACKAGE_PIN L15 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L22N_T3_AD7N_35 Sch=JA2_R_N #set_property -dict { PACKAGE_PIN J16 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L24N_T3_AD15N_35 Sch=JA3_R_N set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { Vaux6_0_v_n }]; #IO_L20N_T3_AD6N_35 Sch=JA4_R_N The configuration of the XADC is: AXI4Lite, channel_sequencer, AXI4 Stream Interface is false, Timing Mode is continuous, DCLK Frequency is 100MHz, Sequencer Mode is continuous, channel averaging ist none and enable external mux is also false. xadcread.cpp
  19. theAsker

    Program code on PetaLinux

    No there isn't an other path existing. The iio:device0 is the internal XADC. But there is not another iio:device appearing. Should be a problem with the device tree I think. But I don't know what I have to add to user-system.dtsi, or somewhere else. Maybe you can help me here. I added a comment in the code below: /include/ "system-conf.dtsi" / { chosen { bootargs = "console=ttyPS0,115200 earlyprintk uio_pdrv_genirq.of_id=generic-uio"; /*do I have to add here something, and if yes what?*/ }; }; &xadc_wiz_0 { clocks = <&clkc 15>; xlnx,channels { #address-cells = <1>; #size-cells = <0>; channelJA4@7 { reg = <7>; }; channelJA1@15 { reg = <15>; }; }; }; &axi_gpio_rgb_led { compatible = "generic-uio"; }; &axi_gpio_button { compatible = "generic-uio"; }; &axi_gpio_segment { compatible = "generic-uio"; }; The Xilinx_ADC_Driver in petalinux-config > industriell I/O is also enable. And the naming of the xadc_wiz_0 should also be correct, when you compare the posts above! I also thought about a missing rootfs driver configuration. But I find nowhere informations about it, if I forget something. Only that the xilinx-xadc-driver has to be enabled. and it is. Do you know what could be the problem?
  20. theAsker

    Program code on PetaLinux

    Thank you for your answer! I will add this. Can you tell me, where in /sys/bux/iio/devices/iio\:device0 I can find the external voltages I want to measure. Because in this path I can find the following: My driver is looking like this: &xadc_wiz_0 { clocks = <&clkc 15>; xlnx,channels { #address-cells = <1>; #size-cells = <0>; channelJA4@7 { /*Vaux6*/ reg = <7>; }; channelJA1@15 { /*Vaux14*/ reg = <15>; }; }; }; The voltage files are only counted from 0 to 7, looks a bit strange for me.
  21. theAsker

    Program code on PetaLinux

    Thanks for your answers, they are making the stuff more clear for me. But I still have some questions about the XADC: The driver you send is made for 4 Channels right? So in my case I only have to the register 7 (vaux6) and register 15 (vaux14). I configured the XADC to simultaneous access, but I read that this functions is not available for simultaneous access. Is there an other way to solve this problem? Could I add a XADC module and map it, and read from some registers the voltage values from the simultaneous access? (in this case, I won't need a driver, right?) I also have questions about the GPIO: Is there also a drive like @sbobrowicz posted for XADC existing for GPIO? Is the reading/writing of the GPIO-ports the same than, like XADC? I found this one. Is this correct. It is looking too simple... &axi_gpio_button { compatible = "generic-uio"; }; thanks a lot, and greetings,