- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My environment is CY8CKIT-059 PSoC 5LP Prototyping Kit and PSoC Creator 4.2 on Windows 10.
I want to send a 32bit value from CPU(C lang) to Datapath.
First of all, I created a sending program(OneDrive) by interrupt and it works(See sreg_out.cysym in an archived file).
And I tryed to make this program correspond to DMA, but it is not successful currently.
#include "project.h"
const uint32_t patterns[] = {
0b11111111000000001111111100000000,
0b11110000111100001111000011110000,
0b11001100110011001100110011001100,
0b10101010101010101010101010101010,0b11001100110011001100110011001100,
0b11110000111100001111000011110000,
};uint8_t send_buffer[2][24];
/* Defines for sreg_dma */
#define sreg_dma_BYTES_PER_BURST 4
#define sreg_dma_REQUEST_PER_BURST 1
#define sreg_dma_SRC_BASE (CYDEV_SRAM_BASE)
#define sreg_dma_DST_BASE (CYDEV_PERIPH_BASE)/* Variable declarations for sreg_dma */
/* Move these variable declarations to the top of the function */
uint8 sreg_dma_Chan;
uint8 sreg_dma_TD[2];void InitDma()
{
/* DMA Configuration for sreg_dma */
sreg_dma_Chan = sreg_dma_DmaInitialize(sreg_dma_BYTES_PER_BURST, sreg_dma_REQUEST_PER_BURST,
HI16(sreg_dma_SRC_BASE), HI16(sreg_dma_DST_BASE));
sreg_dma_TD[0] = CyDmaTdAllocate();
sreg_dma_TD[1] = CyDmaTdAllocate();
CyDmaTdSetConfiguration(sreg_dma_TD[0], 24, sreg_dma_TD[1], sreg_dma__TD_TERMOUT_EN | CY_DMA_TD_INC_SRC_ADR);
CyDmaTdSetConfiguration(sreg_dma_TD[1], 24, sreg_dma_TD[0], sreg_dma__TD_TERMOUT_EN | CY_DMA_TD_INC_SRC_ADR);
CyDmaTdSetAddress(sreg_dma_TD[0], LO16((uint32)send_buffer[0]), LO16((uint32)sreg_out_DMA_PTR));
CyDmaTdSetAddress(sreg_dma_TD[1], LO16((uint32)send_buffer[1]), LO16((uint32)sreg_out_DMA_PTR));
CyDmaChSetInitialTd(sreg_dma_Chan, sreg_dma_TD[0]);
CyDmaChEnable(sreg_dma_Chan, 1);
}CY_ISR(OnInterruptSO)
{
}int main(void)
{
CyGlobalIntEnable;
memcpy(send_buffer[0], patterns, 24);
memcpy(send_buffer[1], patterns, 24);InitDma();
//so_isr_StartEx(OnInterruptSO);for(;;)
{
}
}
According to this discussion, PSoC 5LP seems that it supports 32bit DMA transferring. However, I don't make much progress because there is no concrete exsamples(Official documents detailed that 8bit DMA transfer).
Please tell me if you know a good solution.
Solved! Go to Solution.
- Labels:
-
PSoC 5 Device Programming
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Today, I have tried the DMA transfer in 32-bit. As the conclusion, UDB cannot be used for 32-bit access but 16-bit DMA is available. So, I recommend to support 16-bit patterns.
I have modified your Verilog code as follows.
reg [2:0] pg_state;
wire [3:0] so_32;
reg [4:0] out_count;
wire [3:0] f0_empty;
wire [3:0] f0_not_full;
so_32, f0_empty, and f0_not_full are declared as wire signals because these signals are used as the output of the datapath.
always @(posedge clock)
begin
case(pg_state)
PG_IDLE:
begin
if(f0_empty == 4'b0000)
begin
pg_state <= PG_COPY_F0;
end
end
PG_COPY_F0:
begin
out_count <= 5'd0;
pg_state <= PG_SHIFTOUT;
end
PG_SHIFTOUT:
begin
out_count <= out_count + 5'd1;
if(out_count == 5'd31)
begin
pg_state <= PG_IDLE;
end
end
endcase
end
In the always clause, non-blocking assignments are used for reg elements. As the result, the out_count register is compared with 5'd31 instead of 5'd0.
In line 06, the state transition condition is modified to (f0_empty == 4'b0000) This means all FIFO has data at least one byte each.
assign isr = (f0_not_full == 4'b1111);
assign data = so_32[3];
The isr signal is made from f0_not_full. This logic means all FIFO has a room at least one byte. When f0_empty is used here, the logic means all FIFO has no data. FIFO cannot be used FIFO.
Regards,
Noriaki
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the sreg_out.h file,
#ifndef __`$INSTANCE_NAME`_H__
#define __`$INSTANCE_NAME`_H__
#define `$INSTANCE_NAME`_DMA_PTR ((reg32*)`$INSTANCE_NAME`_dp_u3__F0_REG)
#define `$INSTANCE_NAME`_SetValue(v) CY_SET_REG32(`$INSTANCE_NAME`_dp_u0__F0_REG, v)
#endif
Why are you using `$INSTANCE_NAME`_dp_u3__F0_REG instead of `$INSTANCE_NAME`_dp_u0__F0_REG ?
If you want to access the F0 register as a 32-bit register, the lower address (u0) should be used.
Regards,
Noriaki
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the reply.
Original code was "u0__F0_REG". But with this code, the signal will stop. Therefore, I specified an incorrect value further.
I fixed this code and update an archive file(It has not worked yet).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know if UDB can be used for 32-bit DMA transfer because UDBs are connected to the PHUB with 16-bit spoke.
This table is contained in the "PSoC 5LP Architecture TRM, Document No. 001-78426" If UDB cannot be accessed by a 32-bit DMA, two 16-bit DMAs should be issued and the sreg_out component is triggered by the second access.
I found a strange description in the Verilog file.
}))dp(
/* input */ .clk(clock),
/* input [02:00] */ .cs_addr(pg_state),
/* input */ .route_si(1'b0),
/* input */ .route_ci(1'b0),
/* input */ .f0_load(1'b0),
/* input */ .f1_load(1'b0),
/* input */ .d0_load(1'b0),
/* input */ .d1_load(1'b0),
/* output [03:00] */ .f0_bus_stat(f0_not_empty),
/* output [03:00] */ .f0_blk_stat(f0_full),
/* output [03:00] */ .f1_bus_stat(),
/* output [03:00] */ .f1_blk_stat(),
/* output [03:00] */ .so(so_32)
);
At the port list of the "dp" instance, the 4-bit bus f0_bus_stat[3:0] is assigned to f0_not_empty but the f0_not_empty is not declared as a bus. In this case, only the LSB bit f0_bus_stat[0] is assigned to f0_not_empty and is used in the state machine. If 32-bit access is divided into two 16-bit accesses, f0_bus_stat[3] could be used by the state machine.
Regards,
Noriaki
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found a strange point. All figures come from the "PSoC 5LP Architecture TRM, Document No. 001-78426"
`SC_A0_SRC_ACC, `SC_SHIFT_SL, 1'h0,
1'h0, `SC_FIFO1_BUS, `SC_FIFO0_BUS,
`SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,
`SC_FB_NOCHN, `SC_CMP1_NOCHN,
`SC_CMP0_NOCHN, /*CFG15-14: */
You are setting the F0_INSEL to BUS. This means you are using the FIFO0 in "Input Mode"
If the FIFO0 is used as "Input Mode" the status bits f0_bus_stat and f0_blk_stat are used as "Not Full" and "Empty" respectively.
So, if you want to detect that the FIFO0 has at least one data, f0_blk_stat should be used as f0_empty
Regards,
Noriaki
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I upload a latest version here.
According to the data presented by you, PSoC DMA may not support 32bit. If there is no further progress, I'll try to implement this function with 8bit DMA transfer. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Today, I have tried the DMA transfer in 32-bit. As the conclusion, UDB cannot be used for 32-bit access but 16-bit DMA is available. So, I recommend to support 16-bit patterns.
I have modified your Verilog code as follows.
reg [2:0] pg_state;
wire [3:0] so_32;
reg [4:0] out_count;
wire [3:0] f0_empty;
wire [3:0] f0_not_full;
so_32, f0_empty, and f0_not_full are declared as wire signals because these signals are used as the output of the datapath.
always @(posedge clock)
begin
case(pg_state)
PG_IDLE:
begin
if(f0_empty == 4'b0000)
begin
pg_state <= PG_COPY_F0;
end
end
PG_COPY_F0:
begin
out_count <= 5'd0;
pg_state <= PG_SHIFTOUT;
end
PG_SHIFTOUT:
begin
out_count <= out_count + 5'd1;
if(out_count == 5'd31)
begin
pg_state <= PG_IDLE;
end
end
endcase
end
In the always clause, non-blocking assignments are used for reg elements. As the result, the out_count register is compared with 5'd31 instead of 5'd0.
In line 06, the state transition condition is modified to (f0_empty == 4'b0000) This means all FIFO has data at least one byte each.
assign isr = (f0_not_full == 4'b1111);
assign data = so_32[3];
The isr signal is made from f0_not_full. This logic means all FIFO has a room at least one byte. When f0_empty is used here, the logic means all FIFO has no data. FIFO cannot be used FIFO.
Regards,
Noriaki