- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I need to wire up something using timers and counters with the following behaviour:
* Output goes low if the input sees two rising edges occur 20us or less apart.
* Output goes high on any other input edge.
Can anyone suggest how I might do this?
Many thanks in advance.
Hugo Elias
- Labels:
-
PSoC 3
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- This can be achieved using the Timer component. Use the UDB implementation of the timer component. Set the input clock to the component to be 12 Mhz. Configure the parameters as shown in the picture attached(Timer_20us_Capture,bmp).
- Input Clock of 12 Mhz with a period value of 240 gives rise to a period of 20us. At the end of period a pule is generated on the terminal count , TC terminal appearing at the timer output.
- Set the Trigger and Capture mode parameters to Rising Edge. Connect the trigger and Capture terminal on the component input side to the input signal being monitored. Configuring the trigger mode for rising edge makes the timer component start its down count on the first rising edge appearing on trigger input terminal. The same rising edge is also tied to the Capture input terminal. Now if another edge occurs before 20us elapses, a capture event occurs and a pulse appears at the capture out terminal of timer. Since we know that the timer was started and the capture event occured before 20us this can be used to take necessary action(output goes low). This can be achieved by connecting an ISR to the capture terminal.
- If the second rising edge does not occur in 20us, then the timer elapses and the terminal count pulses appears(exactly 20us after the first pulse appeared). An ISR component can be connected to the terminal count set the output high.In the ISR stop the timer and start using APIs and the process repeats.
This is one of the way i can think about implementing this. It requires very little software overhead.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the suggestion. Ideally, I'd like to do it entirely in hardware. I can't figure out how to do it by adding descrete logic, so I'l learning Verilog.
Is there somewhere people can post their own created components so others can share them?
Hugo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Currently we do not have any place where we are sharing components. However there are App Notes that describe some prominent components that has been created. Also note many of the components in the component catalog in PSoC Crestor are built using Verilog. We will consider your suggestion and see what best cypress can do about this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, so I'm trying to write this in Verilog now. But, since it's my first ever Verilog code, I'm finding it quite confusing. What I imagine would work is this, but it fails to compile:
module DoubleEdge (
Counter,
Q,
C,
D,
R
);
output [4:0] Counter; // Used for timing
output Q; //
input C; // Clock input
input D; // The edges to detect
input R; // Reset the module
//`#start body` -- edit after this line, do not edit this line
reg [4:0] Counter;
reg Q;
reg T;
always @(posedge R)
begin
Counter <= 20;
Q <= 1;
end
always @(posedge C)
begin
if (Counter) Counter <= Counter - 1;
end
always @(posedge D)
begin
if (Counter) Q <= 0;
else Counter <= 20;
end
always @(negedge D)
begin
Q <= 1;
end
endmodule
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's another attempt, which still doesn't seem to work. The counter LEDs just go crazy.
module DoubleEdge (
Counter,
Q,
C,
D,
R
);
output [4:0] Counter;
output Q;
input C;
input D;
input R;
//`#start body` -- edit after this line, do not edit this line
reg [4:0] Counter;
reg Q;
reg T;
always @(C)
begin
if (C) begin // Clock rising edge
if (D & !T) begin // Data rising edge
if (Counter) Q <= 0;
Counter <= 20;
end else begin
if (R) Counter <= 20;
end
if (!D & T) Q <= 1;
end else begin // Clock falling edge
if (Counter) Counter <= Counter - 1;
T <= D;
end
end
endmodule
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Let me understand your requrement completely. If after the first rising edge, what if a falling edge comes. Should the output go high or should the edge be ignored.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After lots of trial and error, and with some help from the edaforum, I was able to write it in Verilog:
module CS_Detect (
CS,
CLK,
EDGES
);
output CS;
input CLK;
input EDGES;
//`#start body` -- edit after this line, do not edit this line
reg [1:0] edges_reg;
reg [3:0] Counter;
reg CS;
wire pos_pulse = edges_reg[0] & !edges_reg[1];
wire neg_pulse = !edges_reg[0] & edges_reg[1];
always @(posedge CLK)
begin
edges_reg[0] <= EDGES;
edges_reg[1] <= edges_reg[0];
//edges_reg <= EDGES;
if (pos_pulse == 1) begin
Counter <= 15;
end else begin
if (Counter > 0) Counter <= Counter - 1;
end
end
always @(posedge CLK)
begin
if ((pos_pulse == 1) && (Counter > 0)) begin
CS <= 0;
end else begin
if (neg_pulse == 1) begin
CS <= 1;
end
end
end
//`#end` -- edit above this line, do not edit this line
endmodule
Many thanks
Hugo