1概述 前面几讲期我们介绍了很多理论知识,但是当我们完成了所有的前期准备工作,准备将编码完成后的数据输出到显示器上的时候,发现并不能发出声音。这是由以下硬件协议和信号处理机制共同决定的: 1. 协议层阻断 HDMI/DP规范要求: - 主机必须通过EDID中的`音频描述符`(Audio Descriptor)确认显示器支持音频功能,才会启用音频数据包封装。 - 即使强制发送音频包(如通过显卡驱动绕过检测),显示器端的HDMI接收芯片(如Silicon Image SiI9033)会因未收到EDID中的`AUDIO_SUPPORT`标志,直接丢弃TMDS中的音频数据包。 2. 固件级静默 显示器主控芯片(如联发科MTK 5891)在启动时检测EDID中的`Speaker Allocation`字段: - 若未检测到有效音频配置,会关闭音频DAC模块的电源(如TI TAS5707),物理上阻断音频信号输出。 - 即使音频数据到达显示器,因DAC未供电,扬声器/耳机孔均无信号。
2 读取显示器EDID在EDID读取的驱动实现中,采用米联客提供的uii2c.v模块作为底层I²C通信核心,其详细原理可参考《米联客FPGA程序设计基础实验》课程资料。 本章聚焦于搭建顶层控制模块edid_reader,通过精准的状态机调度uii2c.v模块完成EDID数据时序控制、地址解析及数据包解析等关键操作,最终实现EDID数据的完整提取,避免重复讲解底层通信协议实现细节。
- module edid_reader (
- input I_clk, // 50MHz时钟输入
- input I_reset_n, // 低电平复位
- inout IO_edid_sda, // EDID SDA总线
- output O_edid_scl // EDID SCL时钟
- );
- // I2C控制器参数
- localparam WRITE_BYTES = 2; // 器件地址+寄存器地址
- localparam READ_BYTES = 128; // EDID数据长度
- localparam CLK_DIV = 499; // 100kHz @50MHz
-
- // 状态机定义
- localparam [2:0] S_IDLE = 3'd0;
- localparam [2:0] S_START_WRITE = 3'd1;
- localparam [2:0] S_WRITE_DATA = 3'd2;
- localparam [2:0] S_START_WAIT_BUSY1 = 3'd3;
- localparam [2:0] S_STOP = 3'd4;
- localparam [2:0] S_ERROR = 3'd5;
-
- reg [3:0] state ;
- reg [7:0] retry_cnt ;
- reg [10:0] timeout_cnt ;
-
- // 控制信号
- reg iic_req ;
- reg [15:0] wr_data_reg ; // 默认写数据:0xA0 + 0x00
- reg [7 :0] wr_cnt = 8'd0;//写数据计数器
- reg [7 :0] rd_cnt = 8'd0;//读数据计数器
-
- wire iic_busy;
- wire iic_bus_error;
-
- wire [7:0] edid_data; // 当前读取的EDID数据
- wire edid_valid; // EDID数据有效标志
-
- // I2C控制器实例化
- uii2c #(
- .WMEN_LEN(WRITE_BYTES),
- .RMEN_LEN(READ_BYTES),
- .CLK_DIV(CLK_DIV)
- ) u_i2c_ctrl (
- .clk_i(I_clk),
- .rstn_i(I_reset_n),
- .iic_scl(O_edid_scl),
- .iic_sda(IO_edid_sda),
- .wr_data(wr_data_reg),
- .wr_cnt(wr_cnt),
- .rd_data(edid_data),
- .rd_cnt(rd_cnt),
- .iic_req(iic_req),
- .iic_busy(iic_busy),
- .iic_bus_error(iic_bus_error)
- );
-
- always @(posedge I_clk or negedge I_reset_n) begin
- if (!I_reset_n) begin
- timeout_cnt <= 0;
- end
- else if (timeout_cnt[10])begin
- timeout_cnt <= timeout_cnt;
- end
- else timeout_cnt <= timeout_cnt +1 ;
- end
- // 主状态机
- always @(posedge I_clk or negedge I_reset_n) begin
- if (!I_reset_n) begin
- state <= S_IDLE;
- iic_req <= 0;
- retry_cnt <= 0;
- end else begin
- case (state)
- S_IDLE: begin
- if (timeout_cnt[10]) begin
- state <= S_START_WRITE;
- wr_data_reg <= {8'h00,8'hA0}; // 写地址+寄存器
- end else begin
- state <= S_IDLE;
- end
- end
-
- S_START_WRITE: begin
- if (!iic_busy) begin
- iic_req <= 1;
- wr_cnt <= 8'd2;
- rd_cnt <= 8'd128; //不需要读数据
- state <= S_START_WAIT_BUSY1;
- end
- else state <= S_START_WRITE;
- end
-
- S_START_WAIT_BUSY1:begin
- if (iic_busy) begin
- state <= S_WRITE_DATA;
- end
- else begin
- state <= S_START_WAIT_BUSY1;
- end
- end
-
- S_WRITE_DATA: begin
- iic_req <= 0;
- if (!iic_bus_error) begin
- if (!iic_busy) begin
- state <= S_STOP;
- end
- else state <= S_WRITE_DATA;
- end
- else state <= S_ERROR;
- end
-
- S_STOP: begin
- state <= S_STOP; // 完成读取
- end
-
- S_ERROR: begin
- iic_req <= 0;
- if (!I_reset_n)
- state <= S_IDLE; // 重试机制
- else begin
- state <= S_ERROR; // 重试机制
- end
- end
- endcase
- end
- end
-
- // 有效信号生成
- assign edid_valid = (state == S_STOP) && !iic_busy;
-
- endmodule
复制代码
3 工程建立
通过TPG参数可控制测试信号源的生成模式:当参数设置为1时,系统将调用IP内部集成的TPG测试图像模块及模拟音频信号;若参数设置为0,则基于外部输入控制信号生成数据岛时序,同时图像与音频信号均采用实际采集数据。 完成管脚绑定与编译后,需通过硬件板级测试验证功能完整性及信号同步性。 4测试结果
|