-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdGMUX_BKeys_main.v
267 lines (196 loc) · 6.43 KB
/
dGMUX_BKeys_main.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
module gGMUX_BKeys (
// LVDS input
input [2:0] LVDS_IG_A_DATA ,
input [2:0] LVDS_IG_B_DATA ,
input LVDS_IG_A_CLK ,
// Panel control signals input
input LVDS_IG_BKL_ON ,
input LVDS_IG_PANEL_PWR ,
// LVDS output
output [2:0] LVDS_A_DATA ,
output [2:0] LVDS_B_DATA ,
output LVDS_A_CLK ,
output LVDS_B_CLK ,
// Panel control signals output
output LCD_BKLT_EN ,
output LCD_PWR_EN ,
output LCD_BKLT_PWM ,
// dGPU power enable and reset
output P3V3GPU_EN ,
output P1V5FB1V8GPU_R_EN ,
output P1V0GPU_EN ,
output GPUVCORE_EN ,
output EG_RESET_L ,
// DDC signals
output LVDS_DDC_SEL_IG ,
output LVDS_DDC_SEL_EG ,
// Test DP_MUX for IG DP Funk
output DP_MUX_EN ,
output DP_MUX_SEL_EG ,
output GMUX_INT ,
/////////////////
/// Modifications by Sjenja87 and Romain to implement PWM generation and key press ///
// Clock input
input LPC_CLK33M_GMUX ,
// Keyboard Brightness Control Input
input GMUX_RESET_L
);
assign LVDS_A_DATA[2:0] = LVDS_IG_A_DATA[2:0];
assign LVDS_B_DATA[2:0] = LVDS_IG_B_DATA[2:0];
assign LVDS_A_CLK = LVDS_IG_A_CLK;
assign LVDS_B_CLK = LVDS_IG_A_CLK;
// Pass through panel control signals
assign LCD_BKLT_EN = LVDS_IG_BKL_ON;
assign LCD_PWR_EN = LVDS_IG_PANEL_PWR;
// Disable dGPU rails and hold in reset
assign P3V3GPU_EN = 0;
assign P1V5FB1V8GPU_R_EN = 0;
assign P1V0GPU_EN = 0;
assign GPUVCORE_EN = 0;
assign EG_RESET_L = 0;
// Display Config Channel MUX select
assign LVDS_DDC_SEL_IG = 1;
assign LVDS_DDC_SEL_EG = 0;
// DP Output IG
assign DP_MUX_EN = 1;
assign DP_MUX_SEL_EG = 0;
assign GMUX_INT = 1;
//////////////////// Modifications by Sjenja87 and Romain to implement the keyboard brightness buttons.
wire Rising_Edge_Event;//Rising edge event trigger
wire Falling_edge_event;//Faling edge event trigger
reg Edge_Event_dly;//For delayed edge register
always @(posedge LPC_CLK33M_GMUX)//Edgre detector
begin
Edge_Event_dly <= GMUX_RESET_L;
end
assign Rising_Edge_Event = (GMUX_RESET_L && !Edge_Event_dly);//Trigger if rising edge detected
assign Falling_edge_event = (!GMUX_RESET_L && Edge_Event_dly);//Trigger if falling edge detected
localparam Delay = 'h528; // 40us
localparam N = 5;
reg[10:0] Delay_Counter;
reg[13:0] Decoded_Frame = 'h000;//13 bit frame from keypress
reg[3:0] Bit_Number = 0;
reg[16:0] Frame_Counter = 0;
localparam Frame_Time = 'h10000; //2ms
localparam Brightness_Up = 'h1FFD;
localparam Brightness_Down = 'h1FFE;
reg[1:0] Last_Key_Press = 0;
reg[5:0] N_Frames_Counter = 0;
always @(posedge LPC_CLK33M_GMUX)
begin
if(Rising_Edge_Event == 1 || Falling_edge_event == 1) begin
Delay_Counter <= 0;
end else if(Delay_Counter <= Delay-1) begin
if(Delay_Counter == Delay-1) begin
Decoded_Frame[Bit_Number] = GMUX_RESET_L;
if(Bit_Number < 13) begin
Bit_Number= Bit_Number + 1;
end
else begin
Bit_Number = 0;
end
end
Delay_Counter <= Delay_Counter +1;
end
if(GMUX_RESET_L == 1) begin
Frame_Counter = 0;
end
else if(GMUX_RESET_L == 0) begin
Frame_Counter = Frame_Counter + 1;
end
if(Frame_Counter >= Frame_Time) begin
if(Decoded_Frame == Brightness_Up) begin
Last_Key_Press[0] = 1;
N_Frames_Counter = 0;
end else if (Decoded_Frame == Brightness_Down) begin
Last_Key_Press[1] = 1;
N_Frames_Counter = 0;
end else begin
N_Frames_Counter = N_Frames_Counter + 1;
end
if(N_Frames_Counter >= N && Last_Key_Press > 0 ) begin
Last_Key_Press = 0;
N_Frames_Counter = 0;
end
Frame_Counter = 0;
Bit_Number = 0;
Decoded_Frame = 0;
end
end
reg Key_Clock= 1'b0;
// Spec target 8 Hz
// Use 33Mhz divided by 4194304 gives 7.86 Hz
localparam Prescale = 'h400000 ;
reg[22:0] Prescale_Counter = 0; // Counter for prescalling Button_Clock
always @(posedge LPC_CLK33M_GMUX)
begin
Prescale_Counter <= Prescale_Counter + 1;
if(Prescale_Counter>=(Prescale)) begin
Prescale_Counter <= 'h0;
end
Key_Clock <= Prescale_Counter[22] ; // ~8Hz
end
reg [4:0] Brightness_Level = 'd11; //17-values Duty_Cycle, reset at level 10.
always @(posedge Key_Clock)
begin
if (Last_Key_Press[0] == 1 && Brightness_Level < 'd16 ) begin
Brightness_Level <= Brightness_Level + 1;
end else if(Last_Key_Press[1] == 1 && Brightness_Level > 'd0 ) begin
Brightness_Level <= Brightness_Level - 1;
end else begin
// Nothing
end
end
wire Brightness_Trigger ;
reg Brightness_Trigger_dly = 1'b0;
wire Brightness_Trigger_Event ;
// Create button event @33MHz, with auto-repeat @8Hz
assign Brightness_Trigger = (Key_Clock);
always @(posedge LPC_CLK33M_GMUX)
begin
Brightness_Trigger_dly <= Brightness_Trigger ;
end
assign Brightness_Trigger_Event = (Brightness_Trigger && !Brightness_Trigger_dly)?1:0 ;
// Reset values for Duty_Cycle and Periode
reg [31:0] Duty_Cycle='d49949; //reset value for the Duty_Cycle : 35% duty clycle
reg [31:0] Periode ='d142711; //Constant value 200Hz PWM freq
always @(posedge LPC_CLK33M_GMUX)
begin
/// BIL Button write operation
/// Use 16 pre-defined values, obtained by retro-engineering of the PWM signal from a 13" MBP 2011
if (Brightness_Trigger_Event) begin
case (Brightness_Level)
'd0 : Duty_Cycle <= 'd0 ;
'd1 : Duty_Cycle <= 'd2854 ;
'd2 : Duty_Cycle <= 'd4281 ;
'd3 : Duty_Cycle <= 'd5708 ;
'd4 : Duty_Cycle <= 'd8563 ;
'd5 : Duty_Cycle <= 'd11417 ;
'd6 : Duty_Cycle <= 'd15698 ;
'd7 : Duty_Cycle <= 'd19980 ;
'd8 : Duty_Cycle <= 'd25688 ;
'd9 : Duty_Cycle <= 'd34251 ;
'd10 : Duty_Cycle <= 'd41386 ;
'd11 : Duty_Cycle <= 'd49949 ;
'd12 : Duty_Cycle <= 'd59939 ;
'd13 : Duty_Cycle <= 'd72783 ;
'd14 : Duty_Cycle <= 'd87054 ;
'd15 : Duty_Cycle <= 'd105606 ;
'd16 : Duty_Cycle <= 'd127013 ;
default : ;
endcase
end
end
// The current frequency obtained is ~200Hz with a counter based on 33MHz
// This could be improved by manipulation the Duty_Cycle and Periode registers before generating the PWM
// The Duty_Cycle value will directly set the duty cycle
reg[16:0] PWM_Counter = 0;
always @(posedge LPC_CLK33M_GMUX)
begin
PWM_Counter <= PWM_Counter + 1;
if(PWM_Counter>=Periode)
PWM_Counter <= 0;
end
assign LCD_BKLT_PWM = (PWM_Counter<Duty_Cycle) ? 1:0 ;
/////////////////
endmodule