Jump to content

BYTEMAN

Members
  • Posts

    82
  • Joined

  • Last visited

Posts posted by BYTEMAN

  1. To be more complete I've attached the Block Design pdf schematic.

    Do you have some idea why the bootloader output is not clear with any baudarete between 9600 bps up to 115200 bps? The system is properly working but apparently the baudrate generated from the bootloader seems not correct. As application the baudarete is working properly at 9600 bps as is set into the AXI UartLite IP block:

    immagine.png.741a8ea78963c09aba9259607f176da5.png

    the only trouble to have a clear output is related the bootloader.

    Thanks and best regards.

    design_1.pdf

  2. Another little step, now all seems able to work but to do that I've to apply the change as reported inside this forum thread:

    https://support.xilinx.com/s/question/0D52E00006hpafvSAA/issue-with-booting-from-qspi-flash-using-srec-spi-bootloader-for-microblaze?language=en_US

    the part that solve this issue is on the last post, here below the detailed step with some image taken from Vivado.

    In Vivado open the Block Design, I'm assuming you have the AXI Quad SPI IP core inside the design.

    You need to re-customize the core.

    immagine.png.ae367bccb92447bba6f6c0892c7fef9c.png

    double click inside the AXI Quad SPI block and check about the following options:

    immagine.png.47be044f54ab81f4bd833c48b3407a79.png

    immagine.thumb.png.500078cb373b1a8fd05e389549c7f72f.png

    Under the IMPLEMENTATION tab inside the Flow Navigator select Open Implemented Design, then select Tools->Edit Device Properties... option, make sure that in Configuration under the SPI Configuration section, the  BUS width option is set to NONE.

    immagine.thumb.png.d7348c03526e184cf99a180a724a9f0a.png

    select the Configuration Modes and check that your Configuration Mode is Master SPI x1.

    immagine.thumb.png.8bf795dfa77589f1cb2e8b243292ec86.png

    Next you have to regenerate the bitstream so go into the Flow Navigator panel and under the PROGRAM AND DEBUG panel select Generate Bitstream.

    Next go to File->Export->Export Hardware and after it finish you can create the new composite bitstream using the Associate ELF File and then Generate Memory Configuration File, from this point all the others step are same to the ones listed into the "How To Store Your SDK Project in SPI Flash" tutorial.

    The composite bitstream can be written inside the SPI Flash serial memory by means of the Hardware Manager from Vivado:

    immagine.png.e120b7cabdae1aa50976137bbe971601.png

    looks for the composite bitstream and load it as Configuration file, choose the Memory Device and press OK to program the SPI memory on the Cmod A7-35t board.

    immagine.png.62251185b4c40874d303da617c479849.png

    The programmed bitstream have the FPGA fabric definitions and the bootloader code.

    Now you have to go in Vitis and program the Application program by using the Xilinx->Program Flash option, choose the elf file of your application and make sure to write as Offset the one used into the blconfig.h (bootloader), for this board 0x00300000 is fine. You must also not forget to check the "Convert ELF file to bootable SREC format" because the bootloader is designed to manage the SREC format.

    Now go back in Vivado, close the Hardware Manager and then make a power cycle to the board (disconnect the board from the USB, wait some seconds then attach the board again). The bootloader is able to start, due to some baud rate settings the output is messed up (I've to do some checking about this point), but when the data stop to came this means that the bitstream is configured, now press the BTN0 in the Cmod A7-35t to reset the MicroBlaze, the system should start to work properly (in my block design the reset input of the board is tied to the Clocking Wizard block).

    immagine.png.e62a021b5cc5f204890573efe47b2bc3.png

    after this first try seems that the SPI SREC bootloader actually implemented is only able to work as simple SPI not as quad spi, it would be nice if someone can also take a look to this matter.

    Thanks and best regards.

  3. I've did some test by using the SREC SPI bootloader, despite the xilisf library is no more available I think that the driver should be able to work also as is provided into the new release (Vivado and Vitis 2021.2), now after doing all the classical step to make the composite bin file from the bitstream and the bootloader and then after program it into the SPI Flash and also after programming the application program into the SPI flash (of course the bootloader FLASH_IMAGE_BASEADDR was properly set with same value used into the flash programming for the application code), when I perform the power cycle to the Cmod A7-35t board nothing appear (the Hardware Manager in Vivado is closed), but by pressing the BTN0 (that should be connected to the reset input) I got this output:

    immagine.png.8e5a5674933a8553bec2c4f7c0447846.png

    someone have idea how to avoid such error?

    Thanks!

  4. 19 hours ago, twinvalleytech said:

     

    @twinvalleytechdear friend if you are just starting with FPGA development I can suggest to use a simple and cheaper Cmod A7-35t development board. If you like to practice with a softcore MicroBlaze and interact with the fabric logic inside the FPGA, coding with VHDL/Verilog this board is very interesting and give an useful starting point. There are plenty of good tutorial around here and when get some feeling you can step toward to a more complex board.

    Basys 3 (I've never used it) have a slightly higher cost, but more peripheral around the FPGA and then you can avoid to breadboard around the Cmod A7-35t but is up to you. Actually I've start to use the Cmod A7-35t, is very small and lightweight and a very good to start with basic IP Block Design, MicroBlaze testing, RTL with VHDL/Verilog coding, for my little experience a great board.

    Bye

  5. Hi @RichardV, I'm just working on this board and on a design that have:

    - MicroBlaze

    - UART Lite

    -Interrupt controller connected to the MicroBlaze in order to handle the UART by interrupt

    - Some GPIO input and output managed from the MicroBlaze

    - Some RTL logic written in VHDL with some line interfaced to GPIO of the MicroBlaze

    This design will act as a base to start in developing with MicroBlaze and this very nice evaluation board from Digilent.

    Actually I've written a post on some things about this design, if you like we can work together to write a full tuturial, step by step, I hink that can be useful for better understand how to proceed and give a general starting point for other design.

    Post link: my post link

    Cheers!

     

  6. Dear all,

    testing with the latest release of Vivado and MicroBlaze with the CmodA7-35t board give a compilation error in Vitis (equivalent to the new SDK of the old Vivado release), the strange things is that same design can not be fit here the compilation error:

    'Invoking: MicroBlaze gcc linker'
    mb-gcc -Wl,-T -Wl,../src/lscript.ld -LC:/Users/........./Xworkspace/blinkymb_wrapper/export/blinkymb_wrapper/sw/blinkymb_wrapper/standalone_microblaze_0/bsplib/lib -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -Wl,--gc-sections -o "blinkymb.elf"  ./src/bootloader.o ./src/platform.o ./src/srec.o   -Wl,--start-group,-lxil,-lgcc,-lc,--end-group
    c:/xilinx/vitis/2021.2/gnu/microblaze/nt/x86_64-oesdk-mingw32/usr/bin/microblaze-xilinx-elf/../../libexec/microblaze-xilinx-elf/gcc/microblaze-xilinx-elf/10.2.0/real-ld.exe: blinkymb.elf section `.text' will not fit in region `microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem'
    c:/xilinx/vitis/2021.2/gnu/microblaze/nt/x86_64-oesdk-mingw32/usr/bin/microblaze-xilinx-elf/../../libexec/microblaze-xilinx-elf/gcc/microblaze-xilinx-elf/10.2.0/real-ld.exe: region `microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem' overflowed by 8904 bytes

    in bold the relevant part of the error message, I got an overflow error related the MicroBlaze memory occupation that is not enough (overflow of 8904 bytes), searching through the forum, from another thread, I can read this answer:

    "basically you went out of space, your application does not fit into the provided BRAM memory. This is mostly because when you add the xil_printf function the implementation on the library of the printf needs some space too, when you do not use it it is optimized and removed by the linker. You need more memory on your device to fit all the drivers and BSP stuff (at least if you are using them)."

    Then I've did a try avoiding the bootloader to be verbose, so into the bootloader.c source code I've commented the #define VERBOSE, the new compilation give again the memory error despite the overflow was reduced:

    'Building target: blinkymb.elf'
    'Invoking: MicroBlaze gcc linker'
    mb-gcc -Wl,-T -Wl,../src/lscript.ld -LC:/Users/........../Xworkspace/blinkymb_wrapper/export/blinkymb_wrapper/sw/blinkymb_wrapper/standalone_microblaze_0/bsplib/lib -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -Wl,--gc-sections -o "blinkymb.elf"  ./src/bootloader.o ./src/platform.o ./src/srec.o   -Wl,--start-group,-lxil,-lgcc,-lc,--end-group
    c:/xilinx/vitis/2021.2/gnu/microblaze/nt/x86_64-oesdk-mingw32/usr/bin/microblaze-xilinx-elf/../../libexec/microblaze-xilinx-elf/gcc/microblaze-xilinx-elf/10.2.0/real-ld.exe: blinkymb.elf section `.text' will not fit in region `microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem'
    c:/xilinx/vitis/2021.2/gnu/microblaze/nt/x86_64-oesdk-mingw32/usr/bin/microblaze-xilinx-elf/../../libexec/microblaze-xilinx-elf/gcc/microblaze-xilinx-elf/10.2.0/real-ld.exe: region `microblaze_0_local_memory_ilmb_bram_if_cntlr_Mem_microblaze_0_local_memory_dlmb_bram_if_cntlr_Mem' overflowed by 4032 bytes

    the overflow was reduced to 4032, but still present.

    Someone have encoutered similar issue in porting from old Vivado to the latest release? Some hint?

    Thanks and best regards.

    F.

    UPDATE FOR SOLUTION

    Dear all,

    after some searching and test I was able to compile properly the bootloader inside Vitis.

    To achieve this of course we have to enlarge the BRAM into design, but this can not be achieved directly from the Block Design by working around the MicroBlaze local memory IP, you have instead to work on the Address Editor tab, looks below the final settings to do:

    immagine.png.432fecbe70f86b552727b7403cca78b2.png

    because the message was related the program size, we have to work on the /microblaze_0/Instruction (then the memory space reserved for the program code, about data I've changed it to 32k and I think is enough) so I've incremented this value up to 64K (with 32k the memory space error was still present).

    After did this change you have to run again the bitstream generation (if you do not launch from this you got the [Board 49-67] error when you try to generate the bitstream, this is a know issue from the past Vivado release, but I confirm that is still present also into the latest Vivado 2021.2, but if you run the synthesis and implementation directly from the bitstream, so in one single passage, this warnings is not show), after the bitstream generation, if you look at the Block Manager and double click into the MicroBlaze local memory as shown below:

    immagine.png.2609fd4ae5c93f81e3f143513ff49a81.png

    and then double click inside the lmb_bram block responsible for the local block memory generation inside the FPGA, you will see now that the Write Depth is increased accordling to the setting did into the Address Editor window!

    immagine.thumb.png.2772f711153c2decee3d2519eb21a253.png

    After exporting the Hardware and then launch Vitis the compilation of the SREC bottoloader was fine, here below the message at the end of the bootloader compilation:

    ...

    'Building target: cmoda7qspi.elf'
    'Invoking: MicroBlaze gcc linker'
    mb-gcc -Wl,-T -Wl,../src/lscript.ld -LC:/Users/........../Xworkspace/design_1_wrapper/export/design_1_wrapper/sw/design_1_wrapper/standalone_microblaze_0/bsplib/lib -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -Wl,--gc-sections -o "cmoda7qspi.elf"  ./src/bootloader.o ./src/platform.o ./src/srec.o   -Wl,--start-group,-lxil,-lgcc,-lc,--end-group
    'Finished building target: cmoda7qspi.elf'
    ' '
    'Invoking: MicroBlaze Print Size'
    mb-size cmoda7qspi.elf  |tee "cmoda7qspi.elf.size"
       text       data        bss        dec        hex    filename
      14636        316       2096      17048       4298    cmoda7qspi.elf
    'Finished building: cmoda7qspi.elf.size'
    ' '

    14:33:22 Build Finished (took 2s.853ms)

    so the memory occupation overflow was not present! Yep!

    Then the next step will be try to set up the classical "Hello World" application to test also the UART communication and put all into the SPI memory to have the program running at the power cycle.

    PROPOSAL

    Due to the Cmod A7-35t is a very nice evaluation board I kindly ask the Digilent team if is possible to update the oldest tutorial for the Cmod A7-35t and QSPI at the latest Vivado/Vitis release.

    Thanks for your time!!

    Byteman

  7. Dear @jpeyron, in order to use same way as into the CmodA7-35t to program the on board SPI memory through Vivado and the USB-serial VCP I kindly require if is possibile to have the schematic details of the FTDI chip used and related connection to replicate same way on my board and then use the another Cmod A7-35t as bridge programming interface to my board, in this way I can avoid to replicate all the components used to program the board that is already present inside the CmodA7-35t.

    It is possible to have the full electrical schematics?

    Thanks and best regards!

     

  8. On 8/3/2021 at 12:41 AM, JColvin said:

    I had to manually create a board_files folder in the Vivado installation path for Vivado 2021.1

    Dear JColvin,

    sorry for long time, I'm back on this question.

    I've did some checking, actually Into the Project settings at the Tool Settings -> Vivado Sore -> Board Repositiry there is a window where to insert the list of the board repository paths, my environment point to this one and the execution of the command get_boards_parts give the following answer:

    immagine.png.f6443a386b6c80045426acf325cd5132.png

    so I think that the board is properly identified, but I can not understand why I got 2 critical warning at the Implementation stage:

    immagine.png.7b7d71990319343abfc4e7239f2c580e.png

    immagine.png.b0b9167deb3516bdd639ba5642c91c80.png

    if the boards is properly identified why I got these warning?

    Thanks for your help.

    Best Regards.

    EDIT

    May be I've solved, I've just checked at the repository path, I think there is somethings wrong where the board files definition was put (in bold what to me seems an extra path):

    C:\Users\STE\AppData\Roaming\Xilinx\Vivado\2021.1\xhub\board_store\xilinx_board_store\XilinxBoardStore\Vivado\2021.1\boards\Digilent\cmod_a7-35t

    then I've do a copy of only the cmod_a7-35t folder to the path listed into the project settings:

    C:\Users\STE\AppData\Roaming\Xilinx\Vivado\2021.1\xhub\board_store\xilinx_board_store

    after running again the implement process this one was able to end without any error or warning

    immagine.png.553d94e41e79b5d069dc5ee56f243497.png

    Actually my repository folder looks as reported below:

    immagine.png.984e0f7ca04aef64998a28eb12e7f033.png

    and now seems able to work properly.

    May be only a issue originated when the Vivado save the boards file from the searching tool when a new design is created?

    Just as a side question, is possible to change the board definition for a already created design?

    Thanks!

    immagine.png

  9. Hi all,

    I've an update.

    II've recognized one error into the added constraint condition about the clock.

    This is the correct command to use:

    set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets sysclk];

    In my previous test the error Common 17-55 was due to the incorrected row:

    set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets sysclk_IBUF];

    hence I've written sysclk_IBUF instead simply sysclk.

    After this correction all the synthesis and Implementation run nicely without any error or warning (image attached).

    Anyway trhe question is why into the previous VIVADO release this message was not show and then I've no need to add this constraint specification.

    Thanks and best regards.

     

    projectsummary-corrected.jpg

  10. Hi all,

    I've checked the Project Summary report, here attached the project part is the Cmod A7-35t (xc7a35tcpg236-1) and the Messages tab content.

    Looking at the Messages sound strange the following one:

    "[Board 49-67] The board_part definition was not found for digilentinc.com:cmod_a7-35t:part0:1.1. This can happen sometimes when you use custom board part. You can resolve this issue by setting 'board.repoPaths' parameter, pointing to the location of custom board files. Valid board_part values can be retrieved with the 'get_board_parts' Tcl command."

    Looking at the path:

    C:\Users\<myuser>\AppData\Roaming\Xilinx\Vivado\2021.1\xhub\board_store\xilinx_board_store\XilinxBoardStore\Vivado\2021.1\boards\Digilent\cmod_a7-35t\B.0\1.1

    I can see the boards file that I think was downloaded and installed by Vivado.

    After that on the forum I've see another procedure detailed at this link:

    https://www.xilinx.com/support/answers/72033.html

    looking at the GitHub repo I can see that the boards version is the same but I noticed a difference, into the GitHub the path at the board file is:

    XilinxBoardStore/boards/Digilent/cmod_a7-35t/B.0/

    inside the B.0 folder there are the board files, but into the PC folder I've instead a 1.1 folder and then inside this one the board files.

    Is correct? Sound strange the difference between the repository file and the one that was download and installed through the Vivado suite...

    LANGUAGE DEFINITION

    There is another point about the language definition. Why even I've set the language as VHDL, into the Project summary there is always listed Verilog instead?

    Thanks and best regards.

    Thanks

     

    projectsummary.jpg

    Messages.jpg

  11. Dear Sir,

    I've installed the latest Vivado 2021.1 suite and try to compile an old blinky design in VHDL, here below the source code:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    -- Uncomment the following library declaration if using
    -- arithmetic functions with Signed or Unsigned values
    --use IEEE.NUMERIC_STD.ALL;
    
    -- Uncomment the following library declaration if instantiating
    -- any Xilinx leaf cells in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;
    
    entity blinky is
    --  Port ( );
    port (
            sysclk : in std_logic;
            led : buffer std_logic_vector (1 downto 0)
        );
    end blinky;
    
    architecture Behavioral of blinky is
        constant max_count : natural := 48000000;
        signal Rst : std_logic;
    begin
    Rst <= '0';
     
        -- 0 to max_count counter
        ctr_led : process(sysclk, Rst)
            variable count : natural range 0 to max_count;
        begin
            if Rst = '1' then
                count := 0;
                led(0) <= '1';
            elsif rising_edge(sysclk) then
                if count < max_count/2 then
                    count := count + 1;
                    led(0) <= '1';
                elsif count < max_count then
                    led(0) <= '0';
                    count := count + 1;
                else
                    led(0) <= '1';
                    count := 0;
                end if;
            end if;
        end process ctr_led; 
    
    end Behavioral;

    on the Digilent Cmod-A7-Master.xdc file I've uncommented following lines (clock and led):

    ## This file is a general .xdc for the CmodA7 rev. B
    ## To use it in a project:
    ## - uncomment the lines corresponding to used pins
    ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
    
    ## 12 MHz Clock Signal
    set_property -dict { PACKAGE_PIN L17   IOSTANDARD LVCMOS33 } [get_ports { sysclk }]; #IO_L12P_T1_MRCC_14 Sch=gclk
    create_clock -add -name sys_clk_pin -period 83.33 -waveform {0 41.66} [get_ports {sysclk}];
    
    ## LEDs
    set_property -dict { PACKAGE_PIN A17   IOSTANDARD LVCMOS33 } [get_ports { led[0] }]; #IO_L12N_T1_MRCC_16 Sch=led[1]
    set_property -dict { PACKAGE_PIN C16   IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L13P_T2_MRCC_16 Sch=led[2]
    
    ## RGB LED
    #set_property -dict { PACKAGE_PIN B17   IOSTANDARD LVCMOS33 } [get_ports { led0_b }]; #IO_L14N_T2_SRCC_16 Sch=led0_b
    #set_property -dict { PACKAGE_PIN B16   IOSTANDARD LVCMOS33 } [get_ports { led0_g }]; #IO_L13N_T2_MRCC_16 Sch=led0_g
    #set_property -dict { PACKAGE_PIN C17   IOSTANDARD LVCMOS33 } [get_ports { led0_r }]; #IO_L14P_T2_SRCC_16 Sch=led0_r

    Synthesis give no errors but Implementation show 3 errors:

    [Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override this clock rule.
    	< set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets sysclk_IBUF] >
    
    	sysclk_IBUF_inst (IBUF.O) is locked to IOB_X0Y102
    	 and sysclk_IBUF_BUFG_inst (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y18
    [Place 30-99] Placer failed with error: 'IO Clock Placer failed'
    Please review all ERROR, CRITICAL WARNING, and WARNING messages during placement to understand the cause for failure.
    [Common 17-69] Command failed: Placer could not place all instances

    Looking through the forum I've found this solution:

    set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]

    but why this was not shown with older Vivado release? There are some way to avoid such constraints and select anothr pin on the Cmod A7 board or is an hardware trouble and then the only workaround is to update the constraints file with the above directive?

    Thanks and best regards.

  12. UPDATE FOR THE XILINX SYSTEM DEBUGGER ERROR (VIVADO 2016.1)

    From XILINX this error appear as a software bugs, I've asked for a patch.

    Best regards

    UPDATE - 19/04/2018

    The patch tried was not working with the 2016.1 (I'm able to debug only with the GDB) then I've make a test by importing all design into the VIVADO 2017.4 and now I'm able to debug with GDB and also with the Xilinx System Debugger.

    Best regards

  13. 2 hours ago, JColvin said:

    Hello @BYTEMAN,

    Taking a look at this thread, you may need to re-generate your BSP sources, or potentially delete it and create a new one. I would also make sure that all of the SDK settings (I'm not certain if you have changed any) are on their default settings.

    Thanks,
    JColvin

    Thank you @JColvin,

    I've did many test with the System Debugger but results is still the same and I'm unable to perform the debugging.

    With the GDB debugger all is fine and no error arise and I'm able to debug the system.

    I don't know why isn't possible doing the System Debugger and over the net I've not found any useful info on this specific error "Failed to call get_cpu_nr".

    Best regards

  14. 16 hours ago, JColvin said:

    Hi @BYTEMAN,

    I'm not certain on the differences between the two interrupt controllers, you will likely need to contact Xilinx to see if they have any additional thoughts or concerns on this.

    As for the SDK debugging behavior, according to this Xilinx site, the GDB mode is depreciated, so you will likely want to instead use the "Launch on Hardware (System Debugger)" option instead for some better results, as this Xilinx forum thread seems to indicate as well.

    Thanks,
    JColvin

    thank you @JColvin,

    I've did some test but already get following error:

    Error while launching program:
    Failed to call get_cpu_nr
    Reason: ERROR: [Common 17-55] 'get_property' expects at least one object.
    Resolution: If [get_<value>] was used to populate the object, check to make sure this command returns at least one valid object.

    Failed to call get_cpu_nr
    Reason: ERROR: [Common 17-55] 'get_property' expects at least one object.
    Resolution: If [get_<value>] was used to populate the object, check to make sure this command returns at least one valid object.


    Here the sequence of step I've used:

    system-debugger-1.jpg.8bb7053b88610cb9039f265a408e12cf.jpgsystem-debugger-1.jpg.8bb7053b88610cb9039f265a408e12cf.jpg

    system-debugger-2.thumb.jpg.a160588d6acf0ac5b0190c01d0e17495.jpg

    system-debugger-3.jpg.90d95164e7a39e524e509fef18d7fadd.jpg

    Do you have some advice how to solve this issue?

    Thank

    Best regards

  15. FIRST WORKING TEST WITH TX INTERRUPT ON UARTLITE (VIVADO 2016.1 - Cmod A7-35T)

    Waiting for some help on the precedent question, I've made a test starting from the xuartlite_intr_example.c code (not the xuartlite_intr_tapp_example.c code, see my previous post about this point).Here below my full implemented code:

    Spoiler


    
    /*
     * helloworld.c: simple test application
     *
     * This application configures UART 16550 to baud rate 9600.
     * PS7 UART (Zynq) is not initialized by this application, since
     * bootrom/bsp configures it to baud rate 115200
     *
     * ------------------------------------------------
     * | UART TYPE   BAUD RATE                        |
     * ------------------------------------------------
     *   uartns550   9600
     *   uartlite    Configurable only in HW design
     *   ps7_uart    115200 (configured by bootrom/bsp)
     */
    
    #include <stdio.h>
    #include "platform.h"
    #include "xil_printf.h"
    #include "microblaze_sleep.h"
    
    #include "xparameters.h"
    #include "xuartlite.h"
    #include "xintc.h"
    #include "xil_exception.h"
    
    // ----------------------------------------------------
    // CONSTANT
    // ----------------------------------------------------
    
    /*
     * The following constants map to the XPAR parameters created in the
     * xparameters.h file. They are defined here such that a user can easily
     * change all the needed parameters in one place.
     */
    #define UARTLITE_DEVICE_ID      XPAR_UARTLITE_0_DEVICE_ID
    #define INTC_DEVICE_ID          XPAR_INTC_0_DEVICE_ID
    #define UARTLITE_INT_IRQ_ID     XPAR_INTC_0_UARTLITE_0_VEC_ID
    
    /*
     * The following constant controls the length of the buffers to be sent
     * and received with the UartLite device.
     */
    #define TEST_BUFFER_SIZE        100
    
    // ----------------------------------------------------
    // FUNCTION PROTOTYPE
    // ----------------------------------------------------
    int UartLiteInit(u16 DeviceId);
    int SetupInterruptSystem(XUartLite *UartLitePtr);
    void SendHandler(void *CallBackRef, unsigned int EventData);
    void RecvHandler(void *CallBackRef, unsigned int EventData);
    
    // ----------------------------------------------------
    // VARIABLE DEFINITIONS
    // ----------------------------------------------------
    XUartLite UartLite;            		// The instance of the UartLite Device
    XIntc InterruptController;     		// The instance of the Interrupt Controller
    
    u8 SendBuffer[TEST_BUFFER_SIZE];	// UART TX buffer (shared with interrupt code)
    u8 ReceiveBuffer[TEST_BUFFER_SIZE];	// UART RX buffer (shared with interrupt code)
    
    static volatile int TotalReceivedCount;	// UART RX char counter (shared with interrupt code)
    static volatile int TotalSentCount;		// UART TX char counter (shared with interrupt code)
    static volatile int TxIsDone=TRUE;		// UART TX flag (TRUE=tx is possible) (shared with interrupt code)
    static volatile int TxMaxChr;			// UART TX chars number to transmit (shared with interrupt code)
    
    // ----------------------------------------------------
    // FUNCTION DEFINITION
    // ----------------------------------------------------
    
    /****************************************************************************/
    /**
    *
    * This function does a minimal test on the UartLite device and driver as a
    * design example. The purpose of this function is to illustrate
    * how to use the XUartLite component.
    *
    * This function uses interrupt driver mode of the UartLite device. The calls
    * to the UartLite driver in the handlers should only use the non-blocking
    * calls.
    *
    * @param	DeviceId is the Device ID of the UartLite Device and is the
    *			XPAR_<uartlite_instance>_DEVICE_ID value from xparameters.h.
    *
    * @return	XST_SUCCESS if successful, otherwise XST_FAILURE.
    *
    * @note
    *
    *
    ****************************************************************************/
    int UartLiteInit(u16 DeviceId)
    {
    	int Status;
    
    	//Initialize the UartLite driver so that it's ready to use.
    	Status = XUartLite_Initialize(&UartLite, DeviceId);
    	if (Status != XST_SUCCESS) {
    		return XST_FAILURE;
    	}
    
    	// Perform a self-test to ensure that the hardware was built correctly.
    	Status = XUartLite_SelfTest(&UartLite);
    	if (Status != XST_SUCCESS) {
    		return XST_FAILURE;
    	}
    
    	// Connect the UartLite to the interrupt subsystem such that interrupts can
    	// occur. This function is application specific.
    	Status = SetupInterruptSystem(&UartLite);
    	if (Status != XST_SUCCESS) {
    		return XST_FAILURE;
    	}
    
    	// Setup the handlers for the UartLite that will be called from the
    	// interrupt context when data has been sent and received, specify a
    	// pointer to the UartLite driver instance as the callback reference so
    	// that the handlers are able to access the instance data.
    	XUartLite_SetSendHandler(&UartLite, SendHandler, &UartLite);
    	XUartLite_SetRecvHandler(&UartLite, RecvHandler, &UartLite);
    
    	// Enable the interrupt of the UartLite so that interrupts will occur.
    	XUartLite_EnableInterrupt(&UartLite);
    
    	return XST_SUCCESS;
    }
    
    /*****************************************************************************/
    /**
    *
    * This function is the handler which performs processing to send data to the
    * UartLite. It is called from an interrupt context such that the amount of
    * processing performed should be minimized. It is called when the transmit
    * FIFO of the UartLite is empty and more data can be sent through the UartLite.
    *
    * This handler provides an example of how to handle data for the UartLite,
    * but is application specific.
    *
    * @param	CallBackRef contains a callback reference from the driver.
    *			In this case it is the instance pointer for the UartLite driver.
    * @param	EventData contains the number of bytes sent or received for sent
    *			and receive events.
    *
    * @return	None.
    *
    * @note		None.
    *
    ****************************************************************************/
    void SendHandler(void *CallBackRef, unsigned int EventData)
    {
    	// Get the number of transmitted chars
    	TotalSentCount = EventData;
    
    	// Check if all is done
    	if (TotalSentCount >= TxMaxChr){
    		TxIsDone = TRUE;
    	}else{
    		TxIsDone = FALSE;
    	}
    
    }
    
    /****************************************************************************/
    /**
    *
    * This function is the handler which performs processing to receive data from
    * the UartLite. It is called from an interrupt context such that the amount of
    * processing performed should be minimized.  It is called data is present in
    * the receive FIFO of the UartLite such that the data can be retrieved from
    * the UartLite. The size of the data present in the FIFO is not known when
    * this function is called.
    *
    * This handler provides an example of how to handle data for the UartLite,
    * but is application specific.
    *
    * @param	CallBackRef contains a callback reference from the driver, in
    *		this case it is the instance pointer for the UartLite driver.
    * @param	EventData contains the number of bytes sent or received for sent
    *		and receive events.
    *
    * @return	None.
    *
    * @note		None.
    *
    ****************************************************************************/
    void RecvHandler(void *CallBackRef, unsigned int EventData)
    {
    	TotalReceivedCount = EventData;
    }
    
    /****************************************************************************/
    /**
    *
    * This function setups the interrupt system such that interrupts can occur
    * for the UartLite device. This function is application specific since the
    * actual system may or may not have an interrupt controller. The UartLite
    * could be directly connected to a processor without an interrupt controller.
    * The user should modify this function to fit the application.
    *
    * @param    UartLitePtr contains a pointer to the instance of the UartLite
    *           component which is going to be connected to the interrupt
    *           controller.
    *
    * @return   XST_SUCCESS if successful, otherwise XST_FAILURE.
    *
    * @note     None.
    *
    ****************************************************************************/
    int SetupInterruptSystem(XUartLite *UartLitePtr)
    {
    
    	int Status;
    
    	// Initialize the interrupt controller driver so that it is ready to use
    	Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
    	if (Status != XST_SUCCESS) {
    		return XST_FAILURE;
    	}
    
    	/*
    	 * Connect a device driver handler that will be called when an interrupt
    	 * for the device occurs, the device driver handler performs the
    	 * specific interrupt processing for the device.
    	 */
    	Status = XIntc_Connect(&InterruptController, UARTLITE_INT_IRQ_ID,
    			   (XInterruptHandler)XUartLite_InterruptHandler,
    			   (void *)UartLitePtr);
    	if (Status != XST_SUCCESS) {
    		return XST_FAILURE;
    	}
    
    	/*
    	 * Start the interrupt controller such that interrupts are enabled for
    	 * all devices that cause interrupts, specific real mode so that
    	 * the UartLite can cause interrupts through the interrupt controller.
    	 */
    	Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
    	if (Status != XST_SUCCESS) {
    		return XST_FAILURE;
    	}
    
    	// Enable the interrupt for the UartLite device.
    	XIntc_Enable(&InterruptController, UARTLITE_INT_IRQ_ID);
    
    	// Initialize the exception table.
    	Xil_ExceptionInit();
    
    	// Register the interrupt controller handler with the exception table.
    	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    			 (Xil_ExceptionHandler)XIntc_InterruptHandler,
    			 &InterruptController);
    
    	// Enable exceptions.
    	Xil_ExceptionEnable();
    
    	return XST_SUCCESS;
    }
    
    /***************************************************************************
    * MAIN
    ****************************************************************************/
    int main()
    {
    	int Status;
    
        init_platform();
    
        xil_printf("System start\n\r");
    
        // UARTLite initialization and interrupt setup
        Status = UartLiteInit(UARTLITE_DEVICE_ID);
        if (Status != XST_SUCCESS) {
            cleanup_platform();
            return 0;
        }
    
        // Infinite loop for microcontroller activity
        while(1){
    
        	if (TxIsDone == TRUE){
    			TxIsDone = FALSE;
    			SendBuffer[0]='H';
    			SendBuffer[1]='e';
    			SendBuffer[2]='l';
    			SendBuffer[3]='l';
    			SendBuffer[4]='o';
    			SendBuffer[5]='!';
    			SendBuffer[6]='\n';
    			SendBuffer[7]='\r';
    			TxMaxChr = 8;
    			XUartLite_Send(&UartLite, SendBuffer, TxMaxChr);
        	}
    
        	// xil_printf("System running\n\r");
        	// MB_Sleep(100);
        }
    
        cleanup_platform();
        return 0;
    }


     

    I've do some simple change to adapt the code to my case, the change reside in how to manage the interrupt transmission, I've used the TxIsDone flag to know when the transmission was finished and then get another one, in this way I'm sure to start a new transmission just after the old one is completed (see the SendHandler function).

    Actually the system is working properly into the SDK Debug Mode (GDB), into the RealTerm monitor I can see the transmitted chars:

    image.png.923e765ca7dc8ec09a38de4e040f7daa.png

    Total transmissione time check
    Now I can see a CPS equal approximatively to 2000, if this value reflect the Chars Per Seconds sounds to me higher than the correct value should be.
    For a 9600,8,N,1 setting we have a 10 bit (1 start + 8 data + 1 stop) for every char to be transmitted then a final time equal to 10/9600=1.042 ms. This give theorically 960 character every seconds if we suppose zero delay time between the frame so is a upper theoretical limit. This is a know bug of the Realterm that effectively show twice regarding the correct value so the UART Lite behaviour should be correct also from this point (https://sourceforge.net/p/realterm/bugs/37/).

    QUESTION #1 - SDK Debug behavior in GDB mode
    A question is related to the SDK debugger, when I run the Debug (GDB mode) I'm able to step the code, but if I choose the Resume option (then to run freely the code) the debug can't be paused and the only choice is to terminate the debug (the pause button on the toolbar is greyed and no way to stop the debugging with it).
    Someone have seen this behaviour and found a way to overcome this problem?

    Thank!

    Best regards

  16. Hi All,

    I'm start working with the AXI UART Lite in my Block Design with a Microblaze soft core.

    Actually I've the whole design working, using the xil_printf I'm able to send data out the board to the PC through the Virtual COM Port exposed by the board itself.

    The better approach involve the use of interrupts in order to manage the RX and TX operations.

    My first try was to found some documents about this point, found it into the yourdesign_bsp > BSP Documentation > uartlite_v3_2 folder:

    image.png.404919891cdcaf7997b21fa84b8a8785.png

    right click and select Open Documentation give the API list on the browser, the documentation reside locally on the following path (I'm using VIVADO 2016.1):

    C:/Xilinx/SDK/2016.1/data/embeddedsw/XilinxProcessorIPLib/drivers/uartlite_v3_2/doc/html/api/index.html

    Opening the:

    C:/Xilinx/SDK/2016.1/data/embeddedsw/XilinxProcessorIPLib/drivers/uartlite_v3_2

    image.png.a35fdf5b757383322e46021845e79607.png

    inside the examples there are several examples how to use interrupt with this peripheral, I took the xuartlite_intr_tapp_example.c file.

    Concerning this example I've some question to asking.

    Looking through the source code I see:

    #ifdef XPAR_INTC_0_DEVICE_ID
    #include "xintc.h"
    #include <stdio.h>
    #else
    #include "xscugic.h"
    #include "xil_printf.h"
    #endif

    First question is about this conditional statement.

    Starting from the SDK I've opened the xparameters.h file:

    image.png.68793ddd956c50628211fbdbad3fd854.png

     

     

    scroll down until you reach the xparameters.h file.

    image.png.f82d49363999250003076c416b7be509.png

    Double click on to open the file and make a search for the XPAR_INTC_0_DEVICE_ID label:

    image.png.4f70e323be75d38d30494da778056ce1.png

    This label should be the reference to the AXI Interrupt Controller present into the Block Design (system.pdf).with name microblaze_0_axi_intc.

    Now I need to know the exact difference between this two type of controller, the AXI is into the Fabric and I think is automatically managed from the Microblaze side by means of a dedicated software layer also the Generic Interrupt Controller I think is also managed by Microblaze but may be I've to configure it in order to instruct what peripheral have to use I'm correct?

    In this example I'm using the AXI Interrupt Controller so I can avoid to insert the whole code related the Generic Interrupt Controller, correct?

    Another question is if I'm using the AXI Interrupt Controller there are some reason to use also the Generic Interrupt Controller or I can't use it due to some constraints or other reasons? Someone can give me some explanation about this point?

    Thank!

×
×
  • Create New...