Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

version 3: fix numerous motor controller bugs

   // - fix ADC bit width
   // - fix digital input data bit position
   // - fix serial number bug
   // - increase motor PWM base clock rate to 208 MHz to allow for 10kHz 12-bit PWM control
   // - decrease DNA clock rate to 1MHz; eliminate 2MHz clock line
   // - clean up documentation around motor and servo dividers
   // - fix ADC channel select bit position
   // - all motor control functions validated
  • Loading branch information...
commit 251feffc5fe028129e78ec9d931c874bd7bf6c4a 1 parent b6d234e
bunnie authored March 06, 2012
1  kovan1.ppr
@@ -2,6 +2,7 @@
2 2
 <Project Version="4" Minor="27">
3 3
 	<FileSet Dir="sources_1" File="fileset.xml"/>
4 4
 	<FileSet Dir="constrs_1" File="fileset.xml"/>
  5
+	<FileSet Dir="sim_1" File="fileset.xml"/>
5 6
 	<RunSet Dir="runs" File="runs.xml"/>
6 7
 	<DefaultLaunch Dir="$PRUNDIR"/>
7 8
 	<DefaultPromote Dir="$PROMOTEDIR"/>
11  kovan1.srcs/constrs_1/imports/kovan1/kovan1.ucf
@@ -96,6 +96,7 @@ NET "RX0_TMDS_N[3]" LOC = V10;
96 96
 NET "RX0_TMDS_N[3]" IOSTANDARD = TMDS_33;
97 97
 NET "RX0_TMDS_P[3]" LOC = U10;
98 98
 NET "RX0_TMDS_P[3]" IOSTANDARD = TMDS_33;
  99
+
99 100
 NET "TX0_TMDS_N[0]" LOC = V6;
100 101
 NET "TX0_TMDS_N[0]" IOSTANDARD = TMDS_33;
101 102
 NET "TX0_TMDS_P[0]" LOC = T6;
@@ -113,6 +114,16 @@ NET "TX0_TMDS_N[3]" IOSTANDARD = TMDS_33;
113 114
 NET "TX0_TMDS_P[3]" LOC = U5;
114 115
 NET "TX0_TMDS_P[3]" IOSTANDARD = TMDS_33;
115 116
 
  117
+# for debug use with a sawed-off HDMI cable
  118
+# NET "TX0_TMDS_P[0]" LOC = T6;
  119
+# NET "TX0_TMDS_P[0]" IOSTANDARD = LVCMOS33;
  120
+# NET "TX0_TMDS_P[1]" LOC = U7;
  121
+# NET "TX0_TMDS_P[1]" IOSTANDARD = LVCMOS33;
  122
+# NET "TX0_TMDS_P[2]" LOC = U8;
  123
+# NET "TX0_TMDS_P[2]" IOSTANDARD = LVCMOS33;
  124
+# NET "TX0_TMDS_P[3]" LOC = U5;
  125
+# NET "TX0_TMDS_P[3]" IOSTANDARD = LVCMOS33;
  126
+
116 127
 
117 128
 ########## i/o controller digital interfaces
118 129
 NET "DIG_ADC_CS[0]" LOC = M14;
90  kovan1.srcs/sources_1/imports/kovan1/kovan.v
@@ -33,6 +33,8 @@ parameter C3_NUM_DQ_PINS          = 16;   // External memory data width
33 33
 parameter C3_MEM_ADDR_WIDTH       = 13;   // External memory address width
34 34
 parameter C3_MEM_BANKADDR_WIDTH   = 3;    // External memory bank address width
35 35
 
  36
+`define HAS_DDR    // comment out to remove DDR interface (does not currently work)
  37
+
36 38
 module kovan (
37 39
 	      // camera IF
38 40
 	      output wire [7:0] CAM_D,
@@ -102,8 +104,8 @@ module kovan (
102 104
 	      output wire       I2S_DI1,
103 105
 	      output wire       I2S_DO0,    // audio data from record
104 106
 	      input wire        I2S_DO1,
105  
-	      input wire        I2S_LRCLK0, // left/right clock to codec
106  
-	      output wire       I2S_LRCLK1,
  107
+	      output wire       I2S_LRCLK0, // left/right clock to codec
  108
+	      input wire        I2S_LRCLK1,
107 109
 
108 110
 	      // LCD output to display
109 111
 	      output wire [7:3] LCDO_B,  // note truncation of blue channel
@@ -170,7 +172,8 @@ module kovan (
170 172
    wire 	   clk26ibuf;
171 173
    wire 	   clk26buf;
172 174
    wire 	   clk13buf;
173  
-   wire            clk3p2M; 
  175
+   wire            clk3p2M;
  176
+   wire 	   clk208M;
174 177
    wire            clk1M;  // wired up in the serial number section
175 178
    
176 179
    assign clk26 = OSC_CLK;
@@ -197,6 +200,7 @@ module kovan (
197 200
 				  .clk_out6p4(clk_qvga),
198 201
 				  .clk_out13(clk13buf),
199 202
 				  .clk_out3p25(clk3p2M), // note: a slight overclock (about 2%)
  203
+				  .clk_out208(clk208M),
200 204
 				  .RESET(glbl_reset),
201 205
 				  .LOCKED(qvga_clkgen_locked) );
202 206
    
@@ -250,7 +254,7 @@ module kovan (
250 254
    assign I2S_CLK0 = I2S_CLK1;
251 255
    assign I2S_DI1 = I2S_DI0;
252 256
    assign I2S_DO0 = I2S_DO1;
253  
-   assign I2S_LRCLK1 = I2S_LRCLK0;
  257
+   assign I2S_LRCLK0 = I2S_LRCLK1;
254 258
    
255 259
    ///////////////////////////////////////////
256 260
    // motor control unit
@@ -281,7 +285,7 @@ module kovan (
281 285
    wire [23:0] servo3_pwm_pulse;
282 286
 
283 287
    robot_iface iface(.clk(clk13buf), .glbl_reset(glbl_reset),
284  
-		     .clk_3p2MHz(clk3p2M),
  288
+		     .clk_3p2MHz(clk3p2M), .clk_208MHz(clk208M),
285 289
 
286 290
 	     // digital i/o block
287 291
 	     .dig_out_val(dig_out_val),
@@ -336,7 +340,8 @@ module kovan (
336 340
 	     .DIG_CLR_N(DIG_CLR_N)
337 341
 		     );
338 342
    
339  
-   
  343
+
  344
+`ifdef HAS_DDR   
340 345
    ///////////////////////////////////////////
341 346
    /////// DDR2 core 128 MB x 16 of memory, 312 MHz (624 Mt/s = 1.2 GiB/s)
342 347
    // generate a 312 MHz clock from the 26 MHz local buffer
@@ -632,7 +637,7 @@ module kovan (
632 637
 	 endcase // case (DDR2_RD_cstate)
633 638
       end // else: !if( ddr2_reset )
634 639
    end // always @ (posedge c3_clk0)
635  
-
  640
+`endif
636 641
    
637 642
   //////////////////////////////////////
638 643
   // cheezy low speed clock divider source
@@ -651,20 +656,16 @@ module kovan (
651 656
    ////////////////////////////////
652 657
    // serial number
653 658
    ////////////////////////////////
654  
-   reg clk2M_unbuf;
655  
-   wire clk2M;
656 659
    reg 	clk1M_unbuf;
657 660
    always @(posedge clk26buf) begin
658  
-      clk2M_unbuf <= counter[4]; // 0.8MHz clock: device DNA only runs at 2 MHz
659 661
       clk1M_unbuf <= counter[6];
660 662
    end
661 663
    
662  
-   BUFG clk2M_buf(.I(clk2M_unbuf), .O(clk2M));
663 664
    BUFG clk1M_buf(.I(clk1M_unbuf), .O(clk1M));
664 665
 
665 666
    wire dna_reset;
666 667
    sync_reset  dna_reset_sync(
667  
-			  .clk(clk_2M),
  668
+			  .clk(clk1M),
668 669
 			  .glbl_reset(glbl_reset),
669 670
 			  .reset(dna_reset) );
670 671
    
@@ -673,7 +674,7 @@ module kovan (
673 674
    wire dna_bit;
674 675
    reg [55:0] dna_data;
675 676
    
676  
-   DNA_PORT device_dna( .CLK(clk2M), .DIN(1'b0), .DOUT(dna_bit), .READ(dna_pulse), .SHIFT(dna_shift) );
  677
+   DNA_PORT device_dna( .CLK(clk1M), .DIN(1'b0), .DOUT(dna_bit), .READ(dna_pulse), .SHIFT(dna_shift) );
677 678
    
678 679
    parameter DNA_INIT =    4'b1 << 0;
679 680
    parameter DNA_PULSE =   4'b1 << 1;
@@ -686,7 +687,7 @@ module kovan (
686 687
    reg [(DNA_nSTATES-1):0] DNA_nstate;
687 688
    reg [5:0] 		   dna_shift_count;
688 689
 
689  
-   always @ (posedge clk2M) begin
  690
+   always @ (posedge clk1M) begin
690 691
       if (dna_reset)
691 692
 	DNA_cstate <= DNA_INIT; 
692 693
       else
@@ -712,7 +713,7 @@ module kovan (
712 713
       endcase // case (DNA_cstate)
713 714
    end
714 715
    
715  
-   always @ (posedge clk2M) begin
  716
+   always @ (posedge clk1M) begin
716 717
       if( dna_reset ) begin
717 718
 	   dna_shift_count <= 6'h0;
718 719
 	   dna_data <= 56'h0;
@@ -746,7 +747,7 @@ module kovan (
746 747
 	   end
747 748
 	 endcase // case (DNA_cstate)
748 749
       end // else: !if( dna_reset )
749  
-   end // always @ (posedge clk2M or posedge ~rstbtn_n)
  750
+   end // always @ (posedge clk1M or posedge ~rstbtn_n)
750 751
 
751 752
    ////////////////////////////////
752 753
    // heartbeat
@@ -755,9 +756,9 @@ module kovan (
755 756
 		 .bright(12'b0000_1111_1000), .dim(12'b0000_0001_0000) );
756 757
 
757 758
 `ifdef HDMI   
758  
-   assign FPGA_LED = blue_led | HPD_N;
  759
+   assign FPGA_LED = !blue_led | HPD_N;
759 760
 `else
760  
-   assign FPGA_LED = blue_led;
  761
+   assign FPGA_LED = !blue_led;
761 762
 `endif
762 763
 
763 764
 
@@ -958,21 +959,24 @@ module kovan (
958 959
    /////////////////
959 960
    //  register 4c-4b: motor PWM divider (MDIV)
960 961
    //  16-bit vaule specifying the divider for the motor PWM
961  
-   //  The base clock for the motor PWM is 26 MHz / 4096. The final period for the PWM is thus:
962  
-   //  6.347kHz / ( MDIV + 1 )
  962
+   //  The base clock for the motor PWM is 208MHz / 4096 (from 12 bits res). 
  963
+   //  The final period for the PWM is thus:
  964
+   //  period = 50.78kHz / ( MDIV + 2)
  965
+   //  period * MDIV + 2 * period = 50.78kHz
  966
+   //  (50.78kHz - 2 * period) / period = MDIV
963 967
    //
964 968
    /////////////////
965 969
    //  register 4d-4f: servo PWM period (SPERIOD)
966 970
    //  24-bit value which specifies the length of the PWM period for the servo
967 971
    //  Servo PWM is custom-built for specifying sparse, high-resolution narrow pulse widths.
968 972
    //  The period for the servo is defined to be:
969  
-   //  26 MHz / (SPERIOD + 1)
970  
-   //  As SPERIOD is a 24-bit number, the longest period is thus 1.5 Hz.
  973
+   //  13 MHz / (SPERIOD + 1)
  974
+   //  As SPERIOD is a 24-bit number, the longest period is thus 0.75 Hz.
971 975
    //
972 976
    /////////////////
973 977
    //  register 50-52: servo 0 pulse width (S0PULSE)
974 978
    //  24-bit value which specifies the width of the servo pulse. The quanta for the value is
975  
-   //  1/26 MHz = 38.4ns
  979
+   //  1/13 MHz = 56.8ns
976 980
    //  Please note that the pulse width is not a percentage duty cycle, but an absolute time specifier
977 981
    //
978 982
    /////////////////
@@ -1133,7 +1137,7 @@ module kovan (
1133 1137
 		      .reg_1e(Km[47:40]),
1134 1138
 		      .reg_1f(Km[55:48]),
1135 1139
 `endif //  `ifdef HDMI
1136  
-		      
  1140
+
1137 1141
 `ifdef HDMI
1138 1142
 		      //// read-only registers after this point
1139 1143
 		      .reg_20(t_hactive[7:0]),
@@ -1173,7 +1177,7 @@ module kovan (
1173 1177
 		      .reg_3f(8'hFF),    // version number
1174 1178
 
1175 1179
 		      // extended register space:
1176  
-		      // reg 40 - reg 60 are write registers (32 locations, growable to 64)
  1180
+		      // reg 40 - reg 80 are write registers (64 locations)
1177 1181
 		      // reg 80 - reg C0 are read-only registers (64 locations)
1178 1182
 		      // write-only interfaces
1179 1183
 		      .reg_40(dig_out_val),
@@ -1220,6 +1224,7 @@ module kovan (
1220 1224
 		      .reg_67(ddr2_test_addr[29:24]),
1221 1225
 		      .reg_68(ddr2_regcmd[7:0]),
1222 1226
 
  1227
+		      // reg_0x78 - reg_0x7f reserved for loopback testing
1223 1228
 		      // read-only interfaces
1224 1229
 		      .reg_80({6'b0,dig_val_good, dig_busy}),
1225 1230
 		      .reg_81(adc_in[7:0]),
@@ -1236,12 +1241,34 @@ module kovan (
1236 1241
 
1237 1242
 		      /// extened version -- 32 bits to report versions
1238 1243
 		      /// kovan starts at FF.00.01.00.01
1239  
-		      .reg_fc(8'h1),  // this is the LSB of the extended version field
  1244
+		      .reg_fc(8'h3),  // this is the LSB of the extended version field
1240 1245
 		      .reg_fd(8'h0),
1241 1246
 		      .reg_fe(8'h1),
1242 1247
 		      .reg_ff(8'h0)   // this is the MSB of the extended version field
1243 1248
 		      );
1244 1249
      
  1250
+   /////// version FF.0001.0004 (log created 3/6/2012)
  1251
+   //
  1252
+   
  1253
+   /////// version FF.0001.0003 (log created 3/1/2012)
  1254
+   // - fix ADC bit width
  1255
+   // - fix digital input data bit position
  1256
+   // - fix serial number bug
  1257
+   // - increase motor PWM base clock rate to 208 MHz to allow for 10kHz 12-bit PWM control
  1258
+   // - decrease DNA clock rate to 1MHz; eliminate 2MHz clock line
  1259
+   // - clean up documentation around motor and servo dividers
  1260
+   // - fix ADC channel select bit position
  1261
+   // - all motor control functions validated
  1262
+
  1263
+   /////// version FF.0001.0002 (log created 3/1/2012)
  1264
+   // - reverse direction of LRCLK to accommodate ES8328 codec restrictions
  1265
+   
  1266
+   /////// version FF.0001.0001 changes (log created 2/18/2012)
  1267
+   // - branch to kovan
  1268
+   // - FF means to check auxiliary vesion field
  1269
+   // - initial checkin of code
  1270
+
  1271
+   ////////////////////////////// legacy changes
1245 1272
    /////// version 4 changes
1246 1273
    // - added input registers to LCD path to clean up timing
1247 1274
    // - added a pipeline stage to the core video processing pipe
@@ -1291,12 +1318,6 @@ module kovan (
1291 1318
    // - fix RGB color depth issue; turns out that extending the LSB's isn't the right way to do it.
1292 1319
    //   now, we truncate the unused bits to zero
1293 1320
 
1294  
-   /////// version FF.01.01.01.01 changes (log create 2/18/2012)
1295  
-   // - branch to kovan
1296  
-   // - FF means to check auxiliary vesion field
1297  
-   
1298  
-
1299  
-
1300 1321
    /////////////// dummy tie-downs
1301 1322
 `ifdef HDMI
1302 1323
 
@@ -1313,10 +1334,15 @@ module kovan (
1313 1334
    IBUFDS  #(.IOSTANDARD("TMDS_33"), .DIFF_TERM("FALSE") 
1314 1335
 	     ) ibuf_dummy3 (.I(RX0_TMDS_P[3]), .IB(RX0_TMDS_N[3]), .O(dummy_tmds[3]));
1315 1336
 
  1337
+   // just for testing for sean
1316 1338
    OBUFDS TMDS0 (.I(1'b0), .O(TX0_TMDS_P[0]), .OB(TX0_TMDS_N[0])) ;
1317 1339
    OBUFDS TMDS1 (.I(1'b0), .O(TX0_TMDS_P[1]), .OB(TX0_TMDS_N[1])) ;
1318 1340
    OBUFDS TMDS2 (.I(1'b0), .O(TX0_TMDS_P[2]), .OB(TX0_TMDS_N[2])) ;
1319 1341
    OBUFDS TMDS3 (.I(1'b0), .O(TX0_TMDS_P[3]), .OB(TX0_TMDS_N[3])) ;
  1342
+//   assign TX0_TMDS_P[0] = I2S_CLK1;
  1343
+//   assign TX0_TMDS_P[1] = I2S_DI1;
  1344
+//   assign TX0_TMDS_P[2] = I2S_LRCLK1;
  1345
+//   assign TX0_TMDS_P[3] = 1'b0;
1320 1346
 
1321 1347
    assign DDC_SDA_PU = 1'b0;
1322 1348
    assign DDC_SDA_PD = 1'b0;
18  kovan1.srcs/sources_1/imports/kovan1/robot_iface.v
@@ -29,6 +29,7 @@
29 29
 module robot_iface(
30 30
 	     input wire  clk,
31 31
 	     input wire  clk_3p2MHz,
  32
+	     input wire  clk_208MHz,
32 33
 	     input wire  glbl_reset,
33 34
 
34 35
 	     // digital i/o block
@@ -126,7 +127,7 @@ module robot_iface(
126 127
    reg 			  update_dig;
127 128
    reg 			  busy;
128 129
    reg 			  dgood;
129  
-   
  130
+
130 131
       
131 132
    always @ (negedge clk) begin
132 133
       if (motor_reset)
@@ -166,6 +167,10 @@ module robot_iface(
166 167
 
167 168
    assign dig_busy = busy;
168 169
    assign dig_val_good = dgood;
  170
+
  171
+   // 0x40 ff ff ff  (locating input data on shift chain, in value = 0x81)
  172
+   //  30       23        15                0
  173
+   // 0100 0000 1111 1111 1111 1111 1111 1111
169 174
    
170 175
    //// note, we assume that DIG_SAMPLE is driven by user before this chain is triggered
171 176
    //// the split enables very precise user control over when sampling happens, versus readout
@@ -234,7 +239,7 @@ module robot_iface(
234 239
 	   
235 240
 	   dig_srload <= 1'b1;
236 241
 	   update_dig <= 1'b1;
237  
-	   dig_in_val <= shift_in[14:7];
  242
+	   dig_in_val <= shift_in[30:23];
238 243
 	   
239 244
 	   dgood <= 1'b1;
240 245
 	   busy <= 1'b0;
@@ -263,7 +268,7 @@ module robot_iface(
263 268
    reg [15:0] pwm_scaler;
264 269
    wire      pwmclk;
265 270
    
266  
-   always @(posedge clk) begin
  271
+   always @(posedge clk_208MHz) begin
267 272
       if( (pwm_scaler > mot_pwm_div) || (&pwm_scaler) ) begin
268 273
 	 pwm_scaler <= 0;
269 274
 	 pwm_clk_a <= 1;
@@ -273,7 +278,7 @@ module robot_iface(
273 278
       end
274 279
    end // always @ (posedge clk or posedge reset)
275 280
 
276  
-   always @(posedge clk) begin
  281
+   always @(posedge clk_208MHz) begin
277 282
       pwm_clk <= pwm_clk_a; // just to clean everything up, no glitches on clock
278 283
    end
279 284
 
@@ -410,7 +415,8 @@ module robot_iface(
410 415
 	end
411 416
 	ADC_START: begin
412 417
 	   adc_shift_count <= 5'b0;
413  
-	   adc_shift_out <= {11'b0,adc_chan[0],adc_chan[1],adc_chan[2],2'b0};
  418
+//	   adc_shift_out <= {11'b0,adc_chan[0],adc_chan[1],adc_chan[2],2'b0};
  419
+	   adc_shift_out <= {2'b0,adc_chan[2],adc_chan[1],adc_chan[0],11'b0};
414 420
 	   adc_shift_in <= adc_shift_in;
415 421
 	   adc_cs <= adc_chan[3] ? 2'b01 : 2'b10;
416 422
 	   
@@ -442,7 +448,7 @@ module robot_iface(
442 448
 	   adc_cs <= 2'b11;
443 449
 	   
444 450
 	   adc_valid <= 1;
445  
-	   adc_in <= adc_shift_in[13:4];
  451
+	   adc_in <= adc_shift_in[11:2];
446 452
 	end
447 453
       endcase // case (ADC_cstate)
448 454
    end // always @ (posedge clk)
14  kovan1.srcs/sources_1/ip/clk_wiz_v3_2_1/clk_wiz_v3_2_qvga.xco
... ...
@@ -1,7 +1,7 @@
1 1
 ##############################################################
2 2
 #
3 3
 # Xilinx Core Generator version 13.3
4  
-# Date: Fri Feb 24 20:57:26 2012
  4
+# Date: Mon Mar 05 13:28:11 2012
5 5
 #
6 6
 ##############################################################
7 7
 #
@@ -47,7 +47,7 @@ CSET clk_out2_port=clk_out13
47 47
 CSET clk_out2_use_fine_ps_gui=false
48 48
 CSET clk_out3_port=clk_out3p25
49 49
 CSET clk_out3_use_fine_ps_gui=false
50  
-CSET clk_out4_port=CLK_OUT4
  50
+CSET clk_out4_port=clk_out208
51 51
 CSET clk_out4_use_fine_ps_gui=false
52 52
 CSET clk_out5_port=CLK_OUT5
53 53
 CSET clk_out5_use_fine_ps_gui=false
@@ -84,9 +84,9 @@ CSET clkout3_requested_phase=0.000
84 84
 CSET clkout3_used=true
85 85
 CSET clkout4_drives=BUFG
86 86
 CSET clkout4_requested_duty_cycle=50.000
87  
-CSET clkout4_requested_out_freq=2
  87
+CSET clkout4_requested_out_freq=208
88 88
 CSET clkout4_requested_phase=0.000
89  
-CSET clkout4_used=false
  89
+CSET clkout4_used=true
90 90
 CSET clkout5_drives=BUFG
91 91
 CSET clkout5_requested_duty_cycle=50.000
92 92
 CSET clkout5_requested_out_freq=100.000
@@ -189,7 +189,7 @@ CSET mmcm_notes=None
189 189
 CSET mmcm_ref_jitter1=0.010
190 190
 CSET mmcm_ref_jitter2=0.010
191 191
 CSET mmcm_startup_wait=false
192  
-CSET num_out_clks=3
  192
+CSET num_out_clks=4
193 193
 CSET override_dcm=false
194 194
 CSET override_dcm_clkgen=false
195 195
 CSET override_mmcm=false
@@ -209,7 +209,7 @@ CSET pll_clkout1_phase=0.000
209 209
 CSET pll_clkout2_divide=128
210 210
 CSET pll_clkout2_duty_cycle=0.500
211 211
 CSET pll_clkout2_phase=0.000
212  
-CSET pll_clkout3_divide=1
  212
+CSET pll_clkout3_divide=2
213 213
 CSET pll_clkout3_duty_cycle=0.500
214 214
 CSET pll_clkout3_phase=0.000
215 215
 CSET pll_clkout4_divide=1
@@ -263,4 +263,4 @@ CSET use_status=false
263 263
 MISC pkg_timestamp=2011-03-09T16:42:33.000Z
264 264
 # END Extra information
265 265
 GENERATE
266  
-# CRC: 923f793b
  266
+# CRC: 9588c90e

0 notes on commit 251feff

Please sign in to comment.
Something went wrong with that request. Please try again.