Test with modem connected
This commit is contained in:
BIN
capture1.png
Normal file
BIN
capture1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
8193
capture2.csv
Normal file
8193
capture2.csv
Normal file
File diff suppressed because it is too large
Load Diff
BIN
capture2.png
Normal file
BIN
capture2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
@@ -38,7 +38,7 @@ module sd_adc_q15 #(
|
|||||||
);
|
);
|
||||||
|
|
||||||
lpf_iir_q15_k #(
|
lpf_iir_q15_k #(
|
||||||
.K(6)
|
.K(8)
|
||||||
) lpf (
|
) lpf (
|
||||||
.i_clk(i_clk_15), .i_rst_n(i_rst_n),
|
.i_clk(i_clk_15), .i_rst_n(i_rst_n),
|
||||||
.i_x_q15(raw_sample_q15),
|
.i_x_q15(raw_sample_q15),
|
||||||
@@ -46,8 +46,8 @@ module sd_adc_q15 #(
|
|||||||
);
|
);
|
||||||
|
|
||||||
decimate_by_r_q15 #(
|
decimate_by_r_q15 #(
|
||||||
.R(200), // 15MHz/200 = 75KHz
|
// .R(200), // 15MHz/200 = 75KHz
|
||||||
// .R(375), // 15MHz/375 = 40KHz
|
.R(375), // 15MHz/375 = 40KHz
|
||||||
.CNT_W(10)
|
.CNT_W(10)
|
||||||
) decimate (
|
) decimate (
|
||||||
.i_clk(i_clk_15), .i_rst_n(i_rst_n),
|
.i_clk(i_clk_15), .i_rst_n(i_rst_n),
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ module signal_scope_q15 #(
|
|||||||
wire [3:0] wb_reg_idx = wb_adr[5:2];
|
wire [3:0] wb_reg_idx = wb_adr[5:2];
|
||||||
reg [15:0] trigger_sample;
|
reg [15:0] trigger_sample;
|
||||||
reg trigger_sample_valid;
|
reg trigger_sample_valid;
|
||||||
|
reg wb_mem_read_pending;
|
||||||
|
reg wb_mem_read_half;
|
||||||
|
reg wb_mem_read_oob;
|
||||||
|
reg [16*4-1:0] wb_mem_rdata;
|
||||||
|
|
||||||
jtag_wb_bridge #(
|
jtag_wb_bridge #(
|
||||||
.chain(chain),
|
.chain(chain),
|
||||||
@@ -119,6 +123,10 @@ module signal_scope_q15 #(
|
|||||||
signal_b_pending <= 1'b0;
|
signal_b_pending <= 1'b0;
|
||||||
signal_c_pending <= 1'b0;
|
signal_c_pending <= 1'b0;
|
||||||
signal_d_pending <= 1'b0;
|
signal_d_pending <= 1'b0;
|
||||||
|
wb_mem_read_pending <= 1'b0;
|
||||||
|
wb_mem_read_half <= 1'b0;
|
||||||
|
wb_mem_read_oob <= 1'b0;
|
||||||
|
wb_mem_rdata <= {(16*4){1'b0}};
|
||||||
end else begin
|
end else begin
|
||||||
|
|
||||||
// Sample signals
|
// Sample signals
|
||||||
@@ -188,9 +196,16 @@ module signal_scope_q15 #(
|
|||||||
|
|
||||||
// WB slave response: register window + capture memory window.
|
// WB slave response: register window + capture memory window.
|
||||||
arm_req <= 1'b0;
|
arm_req <= 1'b0;
|
||||||
wb_ack <= wb_cyc & wb_stb & !wb_ack;
|
wb_ack <= 1'b0;
|
||||||
if(wb_cyc & wb_stb & !wb_ack) begin
|
|
||||||
|
if(wb_mem_read_pending) begin
|
||||||
|
wb_ack <= 1'b1;
|
||||||
|
wb_rdt <= wb_mem_read_oob ? 32'b0 :
|
||||||
|
(wb_mem_read_half ? wb_mem_rdata[63:32] : wb_mem_rdata[31:0]);
|
||||||
|
wb_mem_read_pending <= 1'b0;
|
||||||
|
end else if(wb_cyc & wb_stb) begin
|
||||||
if(wb_we) begin
|
if(wb_we) begin
|
||||||
|
wb_ack <= 1'b1;
|
||||||
wb_rdt <= 32'b0;
|
wb_rdt <= 32'b0;
|
||||||
if(wb_is_reg) begin
|
if(wb_is_reg) begin
|
||||||
// Keep register write decode in one case so new writable registers
|
// Keep register write decode in one case so new writable registers
|
||||||
@@ -217,6 +232,7 @@ module signal_scope_q15 #(
|
|||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
if(wb_is_reg) begin
|
if(wb_is_reg) begin
|
||||||
|
wb_ack <= 1'b1;
|
||||||
case(wb_reg_idx)
|
case(wb_reg_idx)
|
||||||
// [3:2]=trigger_channel, [1]=trigger_enable, [0]=arm(write pulse only/read 0).
|
// [3:2]=trigger_channel, [1]=trigger_enable, [0]=arm(write pulse only/read 0).
|
||||||
reg_control: wb_rdt <= {28'b0, trigger_channel, trigger_enable, 1'b0};
|
reg_control: wb_rdt <= {28'b0, trigger_channel, trigger_enable, 1'b0};
|
||||||
@@ -225,11 +241,12 @@ module signal_scope_q15 #(
|
|||||||
reg_trig_val: wb_rdt <= {16'b0, trig_val};
|
reg_trig_val: wb_rdt <= {16'b0, trig_val};
|
||||||
default: wb_rdt <= 32'b0;
|
default: wb_rdt <= 32'b0;
|
||||||
endcase
|
endcase
|
||||||
end else if(wb_mem_idx <= depth_last) begin
|
|
||||||
// A single frame is 64-bit: {a, b, c, d}. WB reads low/high 32-bit halves.
|
|
||||||
wb_rdt <= wb_adr[2] ? mem[wb_mem_idx][63:32] : mem[wb_mem_idx][31:0];
|
|
||||||
end else begin
|
end else begin
|
||||||
wb_rdt <= 32'b0;
|
// Synchronous RAM read for BRAM inference: issue read now, acknowledge next cycle.
|
||||||
|
wb_mem_rdata <= mem[wb_mem_idx];
|
||||||
|
wb_mem_read_half <= wb_adr[2];
|
||||||
|
wb_mem_read_oob <= (wb_mem_idx > depth_last);
|
||||||
|
wb_mem_read_pending <= 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ module toplevel(
|
|||||||
// signal_q15 is unipolar and biased (0-3.3V -> 0..32767)
|
// signal_q15 is unipolar and biased (0-3.3V -> 0..32767)
|
||||||
reg signed [15:0] signal_unbiased_q15 = 16'sd0;
|
reg signed [15:0] signal_unbiased_q15 = 16'sd0;
|
||||||
reg signal_unbiased_valid = 1'b0;
|
reg signal_unbiased_valid = 1'b0;
|
||||||
localparam bias = 12050;
|
localparam bias = 2**14;
|
||||||
localparam gain = 2;
|
localparam gain = 2;
|
||||||
always @(posedge clk_15) begin
|
always @(posedge clk_15) begin
|
||||||
if (sys_reset_r) begin
|
if (sys_reset_r) begin
|
||||||
@@ -91,7 +91,7 @@ module toplevel(
|
|||||||
|
|
||||||
|
|
||||||
signal_scope_q15 #(
|
signal_scope_q15 #(
|
||||||
.depth(2**10),
|
.depth(2**13),
|
||||||
.chain(1)
|
.chain(1)
|
||||||
) scope1 (
|
) scope1 (
|
||||||
.i_clk(clk_15),
|
.i_clk(clk_15),
|
||||||
|
|||||||
79
modem/modem_dtmf.py
Executable file
79
modem/modem_dtmf.py
Executable file
@@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import serial
|
||||||
|
|
||||||
|
def read_response(port: serial.Serial, timeout_s: float) -> list[str]:
|
||||||
|
deadline = time.monotonic() + timeout_s
|
||||||
|
lines: list[str] = []
|
||||||
|
|
||||||
|
while time.monotonic() < deadline:
|
||||||
|
raw = port.readline()
|
||||||
|
if not raw:
|
||||||
|
continue
|
||||||
|
|
||||||
|
line = raw.decode(errors="replace").strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
lines.append(line)
|
||||||
|
if line in {"OK", "ERROR"}:
|
||||||
|
break
|
||||||
|
|
||||||
|
return lines
|
||||||
|
|
||||||
|
def send_at(port: serial.Serial, command: str, timeout_s: float) -> tuple[bool, list[str]]:
|
||||||
|
port.write((command + "\r").encode())
|
||||||
|
port.flush()
|
||||||
|
lines = read_response(port, timeout_s)
|
||||||
|
|
||||||
|
ok = any(line == "OK" for line in lines)
|
||||||
|
err = any(line == "ERROR" for line in lines)
|
||||||
|
return ok and not err, lines
|
||||||
|
|
||||||
|
def send_and_log(port: serial.Serial, command: str, timeout_s: float) -> tuple[bool, list[str]]:
|
||||||
|
ok, lines = send_at(port, command, timeout_s)
|
||||||
|
print(f"> {command}")
|
||||||
|
for line in lines:
|
||||||
|
print(f"< {line}")
|
||||||
|
return ok, lines
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
parser = argparse.ArgumentParser(description="Control an AT modem and send DTMF tones")
|
||||||
|
parser.add_argument("device", help="Serial device path, e.g. /dev/ttyACM0")
|
||||||
|
parser.add_argument("--baud", type=int, default=115200, help="Serial baudrate (default: 115200)")
|
||||||
|
parser.add_argument("--timeout", type=float, default=2.0, help="AT command timeout seconds")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
with serial.Serial(args.device, args.baud, timeout=0.2, write_timeout=1.0) as port:
|
||||||
|
port.reset_input_buffer()
|
||||||
|
port.reset_output_buffer()
|
||||||
|
|
||||||
|
# Inicialise
|
||||||
|
|
||||||
|
for cmd in ("AT", "ATZ0", "ATE1", "ATX0"):
|
||||||
|
ok, lines = send_and_log(port, cmd, args.timeout)
|
||||||
|
if not ok:
|
||||||
|
print(f"Modem did not accept {cmd}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
send_and_log(port, "ATS6=0", args.timeout) # Set wait for dial tone time to 0
|
||||||
|
send_and_log(port, "ATS11=2", args.timeout) # set tone length to 1 ms
|
||||||
|
send_and_log(port, "ATH1", args.timeout)
|
||||||
|
while True:
|
||||||
|
send_and_log(port, "ATDT0123456789;", args.timeout)
|
||||||
|
send_and_log(port, "ATH0", args.timeout)
|
||||||
|
|
||||||
|
except serial.SerialException as exc:
|
||||||
|
print(f"Serial error: {exc}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print("Done")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user