UDB - transferring data into FIFO

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
MiRe_4638356
Level 3
Level 3
First like received First like given

I am going around in circles with the UDBs - how do I get data (3 bytes/24 bits in this case) from a programme into a FIFO (without using Ax or Dx)?

A trivial question, I know!

Thank you,

Mike

0 Likes
1 Solution
NoriTan
Employee
Employee
25 sign-ins 5 questions asked 10 sign-ins

An example is found in the Shift Register component.

The ShiftReg_WriteData() function is used to store a 24bit value into a 24bit width FIFO register using the CY_SET_REG24() macro.

    cystatus ShiftReg_WriteData(uint32 shiftData)

                                                                        

    {

        cystatus result;

        result = CYRET_INVALID_STATE;

        /* Writes data into the input FIFO if it is not FULL */

        if(ShiftReg_RET_FIFO_FULL != (ShiftReg_GetFIFOStatus(ShiftReg_IN_FIFO)))

        {

            CY_SET_REG24(ShiftReg_IN_FIFO_VAL_LSB_PTR, shiftData);

            result = CYRET_SUCCESS;

        }

        return(result);

    }

The register address ShiftReg_IN_FIFO_VAL_LSB_PTR is defined in the header file as follows.

        #define ShiftReg_IN_FIFO_VAL_LSB_PTR        ( (reg32 *) \

                                        ShiftReg_bSR_sC24_BShiftRegDp_u0__F0_REG )

Regards,

Noriaki

View solution in original post

4 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Mike-san,

> A trivial question, I know!

At least it was not trivial for me.

And it was a fun theme to try.

I tried it with CY8CKIT-044.

At first I tried to implement a fifo inside udb but the resource was not enough,

so I used the external "Control_Reg_x" as fifo buffer.

This means that main should not change the value of Control_Reg_1 ~ Control_Reg_3

during the busy is high.

There could be many other approaches, but I hope this one seems to be working.

schematic

001-schematic.JPG

pin

002-pin.JPG

Tera Term log

000-TeraTerm-log.JPG

(UDB) Verilog "udb_test.v"

=====================

module udb_test(

    input        clk,

    input        reset,

    input        trigger,

    input [7:0] indata_1,

    input [7:0] indata_2,

    input [7:0] indata_3,

    output reg   busy,

    output reg   so

    ) ;

   

    reg prev_trigger ;

    reg [4:0] mask ;

    wire [23:0] fifo ;

   

    assign fifo = { indata_1, indata_2, indata_3 } ;

   

    always @(posedge clk) begin

        if (reset == 1'b1) begin

            prev_trigger <= 1'b0 ;

            busy         <= 1'b0 ;

            so           <= 1'b0 ;

            mask         <= 5'd0 ;

        end else begin

            if ((prev_trigger == 1'b0) && (trigger == 1'b1)) begin /* rising edge of the trigger */

                busy <= 1'b1 ;

                so   <= 1'b0 ;

                mask <= 5'd23 ;

            end else begin

                if (busy == 1'b1) begin

                    so <= fifo[mask] ;

                end else begin

                    so <= 1'b0 ;

                end

                mask <= mask - 1 ;

                if (mask == 5'd0) begin

                    busy <= 1'b0 ;

                end else begin

                    busy <= 1'b1 ;

                end

            end

            prev_trigger <= trigger ;

        end

    end

endmodule   

=====================

main.c

=====================

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#define LED_ON      (0u)

#define LED_OFF     (1u)

#define CLK_ON      (1u)

#define CLK_OFF     (0u)

#define RESET_ON    (2u)

#define RESET_OFF   (0u)

#define TRIGGER_ON  (4u)

#define TRIGGER_OFF (0u)

uint32_t interval  = 100 ;

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    tty_init() ;

    splash("UDB FIFO Test") ;

}

void usage(void)

{

    print("=== usage ===\n\r") ;

    print("run <r> <g> <b>\n\r") ;

    print("ex: run 255 32 53\n\r") ;

    print("\n\r") ;

}

void run_test(char *str)

{

    int r, g, b ;

    uint8_t ctrl_value ; /* bit 0:clk, 1:reset 2:trigger */

    sscanf(str, "%*s %d %d %d", &r, &g, &b) ;

   

    /* reset udb_test module */

    Control_Reg_0_Write( CLK_OFF | RESET_ON | TRIGGER_OFF ) ;

    CyDelay(interval) ;

    Control_Reg_0_Write( CLK_ON  | RESET_ON | TRIGGER_OFF ) ;

    CyDelay(interval) ;

   

    Control_Reg_1_Write(r & 0xFF) ;

    Control_Reg_2_Write(g & 0xFF) ;

    Control_Reg_3_Write(b & 0xFF) ;

   

    /* trigger udb_test module */

    Control_Reg_0_Write( CLK_OFF  | RESET_OFF | TRIGGER_ON ) ;

    CyDelay(interval) ;   

    Control_Reg_0_Write( CLK_ON   | RESET_OFF | TRIGGER_ON ) ;

    CyDelay(interval) ;

    while(LED_G_Read() == LED_ON) { /* busy == 1'b1 */

        /* clock udb_test module */

        Control_Reg_0_Write( CLK_OFF | RESET_OFF | TRIGGER_OFF ) ; 

        CyDelay(interval) ;

        Control_Reg_0_Write( CLK_ON  | RESET_OFF | TRIGGER_OFF ) ; 

        CyDelay(interval) ;  

        if (LED_R_Read() == LED_ON) { /* so value */

            print("1") ;

        } else {

            print("0") ;

        }

    }

    print("\n\r") ;   

}

int main(void)

{

    init_hardware() ;

    prompt() ;

    for(;;)

    {

        if (get_line()) {

            if ((str[0] == 'r') || (str[0] == 'R')) {

                run_test(str) ;

            } else {

                usage() ;

            }

            prompt() ;

        }

    }

}

=====================

Best Regards,

5-Aug-2020

Motoo Tanaka

RodolfoGL
Employee
Employee
250 solutions authored 250 sign-ins 5 comments on KBA

Michael,

Does the CPU read or write to the FIFO?

The easiest way is to create a 32-bit datapath and just ignore the 8 MSB.

If the number of resources is tight, you could manually chain the datapaths, but still, the CPU accesses data at 8,16 or 32 bits. So even if you place the datapath sequentially, you would need to read the FIFOs individually, or use the 32-bit access, but if the MSB FIFO is used for something else, you might mess up its logic.

Or you can use DMAs to transfer 3x 8-bits and place in RAM on 32-bit variable.

0 Likes
NoriTan
Employee
Employee
25 sign-ins 5 questions asked 10 sign-ins

An example is found in the Shift Register component.

The ShiftReg_WriteData() function is used to store a 24bit value into a 24bit width FIFO register using the CY_SET_REG24() macro.

    cystatus ShiftReg_WriteData(uint32 shiftData)

                                                                        

    {

        cystatus result;

        result = CYRET_INVALID_STATE;

        /* Writes data into the input FIFO if it is not FULL */

        if(ShiftReg_RET_FIFO_FULL != (ShiftReg_GetFIFOStatus(ShiftReg_IN_FIFO)))

        {

            CY_SET_REG24(ShiftReg_IN_FIFO_VAL_LSB_PTR, shiftData);

            result = CYRET_SUCCESS;

        }

        return(result);

    }

The register address ShiftReg_IN_FIFO_VAL_LSB_PTR is defined in the header file as follows.

        #define ShiftReg_IN_FIFO_VAL_LSB_PTR        ( (reg32 *) \

                                        ShiftReg_bSR_sC24_BShiftRegDp_u0__F0_REG )

Regards,

Noriaki

Thank you Noriaki-san, I am not sure how I missed that. Still struggling my way through the UDB Editor for anything non-trivial.

Best wishes,

Mike

0 Likes