- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
pin
Tera Term log
(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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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