Permalink
Browse files

Added motor controller interfaces

digital I/O, ADC, and motor PWM/servo PWM interfaces added.
Also, register bank expanded.
  • Loading branch information...
1 parent 613fbc9 commit 8e75c74c8fe63fe2eb63ac6a60eb99a69c6b29fa @bunnie committed Feb 23, 2012
@@ -127,12 +127,60 @@ module i2c_slave (
input wire [7:0] reg_3b,
input wire [7:0] reg_3c,
input wire [7:0] reg_3d,
-
input wire [7:0] reg_3e,
+
input wire [7:0] reg_3f,
output wire [7:0] reg_40,
+ output wire [7:0] reg_41,
+ output wire [7:0] reg_42,
+ output wire [7:0] reg_43,
+ output wire [7:0] reg_44,
+ output wire [7:0] reg_45,
+ output wire [7:0] reg_46,
+ output wire [7:0] reg_47,
+ output wire [7:0] reg_48,
+ output wire [7:0] reg_49,
+ output wire [7:0] reg_4a,
+ output wire [7:0] reg_4b,
+ output wire [7:0] reg_4c,
+ output wire [7:0] reg_4d,
+ output wire [7:0] reg_4e,
+ output wire [7:0] reg_4f,
+ output wire [7:0] reg_50,
+ output wire [7:0] reg_51,
+ output wire [7:0] reg_52,
+ output wire [7:0] reg_53,
+ output wire [7:0] reg_54,
+ output wire [7:0] reg_55,
+ output wire [7:0] reg_56,
+ output wire [7:0] reg_57,
+ output wire [7:0] reg_58,
+ output wire [7:0] reg_59,
+ output wire [7:0] reg_5a,
+ output wire [7:0] reg_5b,
+
+ output wire [7:0] reg_60,
+ output wire [7:0] reg_61,
+ output wire [7:0] reg_62,
+ output wire [7:0] reg_63,
+ output wire [7:0] reg_64,
+ output wire [7:0] reg_65,
+ output wire [7:0] reg_66,
+ output wire [7:0] reg_67,
+ output wire [7:0] reg_68,
+
input wire [7:0] reg_80,
+ input wire [7:0] reg_81,
+ input wire [7:0] reg_82,
+ input wire [7:0] reg_83,
+
+ input wire [7:0] reg_90,
+ input wire [7:0] reg_91,
+ input wire [7:0] reg_92,
+ input wire [7:0] reg_93,
+ input wire [7:0] reg_94,
+ input wire [7:0] reg_95,
input wire [7:0] reg_fc,
input wire [7:0] reg_fd,
@@ -235,7 +283,7 @@ module i2c_slave (
/// extended register set for Kovan
parameter EXT_RAM_WIDTH = 8;
- parameter EXT_RAM_ADDR_BITS = 5; // note parameter width exception in reg_a* assign block below
+ parameter EXT_RAM_ADDR_BITS = 6; // note parameter width exception in reg_a* assign block below
reg [EXT_RAM_WIDTH-1:0] I2C_regblock_ext [(2**RAM_ADDR_BITS)-1:0];
reg [EXT_RAM_WIDTH-1:0] I2C_regread_async_ext;
@@ -589,9 +637,45 @@ module i2c_slave (
assign reg_1f = I2C_regblock[5'h1f]; // msb of Km
/// extended block
- assign reg_40 = I2C_regblock_ext[5'h0]; // note the renumbering -- it's (target address - 0x40)
+ assign reg_40 = I2C_regblock_ext[6'h0]; // note the renumbering -- it's (target address - 0x40)
+ assign reg_41 = I2C_regblock_ext[6'h1];
+ assign reg_42 = I2C_regblock_ext[6'h2];
+ assign reg_43 = I2C_regblock_ext[6'h3];
+ assign reg_44 = I2C_regblock_ext[6'h4];
+ assign reg_45 = I2C_regblock_ext[6'h5];
+ assign reg_46 = I2C_regblock_ext[6'h6];
+ assign reg_47 = I2C_regblock_ext[6'h7];
+ assign reg_48 = I2C_regblock_ext[6'h8];
+ assign reg_49 = I2C_regblock_ext[6'h9];
+ assign reg_4a = I2C_regblock_ext[6'ha];
+ assign reg_4b = I2C_regblock_ext[6'hb];
+ assign reg_4c = I2C_regblock_ext[6'hc];
+ assign reg_4d = I2C_regblock_ext[6'hd];
+ assign reg_4e = I2C_regblock_ext[6'he];
+ assign reg_4f = I2C_regblock_ext[6'hf];
+ assign reg_50 = I2C_regblock_ext[6'h10];
+ assign reg_51 = I2C_regblock_ext[6'h11];
+ assign reg_52 = I2C_regblock_ext[6'h12];
+ assign reg_53 = I2C_regblock_ext[6'h13];
+ assign reg_54 = I2C_regblock_ext[6'h14];
+ assign reg_55 = I2C_regblock_ext[6'h15];
+ assign reg_56 = I2C_regblock_ext[6'h16];
+ assign reg_57 = I2C_regblock_ext[6'h17];
+ assign reg_58 = I2C_regblock_ext[6'h18];
+ assign reg_59 = I2C_regblock_ext[6'h19];
+ assign reg_5a = I2C_regblock_ext[6'h1a];
+ assign reg_5b = I2C_regblock_ext[6'h1b];
-
+ assign reg_60 = I2C_regblock_ext[6'h20];
+ assign reg_61 = I2C_regblock_ext[6'h21];
+ assign reg_62 = I2C_regblock_ext[6'h22];
+ assign reg_63 = I2C_regblock_ext[6'h23];
+ assign reg_64 = I2C_regblock_ext[6'h24];
+ assign reg_65 = I2C_regblock_ext[6'h25];
+ assign reg_66 = I2C_regblock_ext[6'h26];
+ assign reg_67 = I2C_regblock_ext[6'h27];
+ assign reg_68 = I2C_regblock_ext[6'h28];
+
always @(*) begin
case (I2C_addr[7:0])
8'h2: begin
@@ -717,10 +801,41 @@ module i2c_slave (
I2C_regread_async = reg_3f;
end
+
8'h80: begin
I2C_regread_async = reg_80;
end
-
+ 8'h81: begin
+ I2C_regread_async = reg_81;
+ end
+ 8'h82: begin
+ I2C_regread_async = reg_82;
+ end
+ 8'h83: begin
+ I2C_regread_async = reg_83;
+ end
+
+
+ 8'h90: begin
+ I2C_regread_async = reg_90;
+ end
+ 8'h91: begin
+ I2C_regread_async = reg_91;
+ end
+ 8'h92: begin
+ I2C_regread_async = reg_92;
+ end
+ 8'h93: begin
+ I2C_regread_async = reg_93;
+ end
+ 8'h94: begin
+ I2C_regread_async = reg_94;
+ end
+ 8'h95: begin
+ I2C_regread_async = reg_95;
+ end
+
+
8'hfc: begin
I2C_regread_async = reg_fc;
end
@@ -0,0 +1,39 @@
+module mot_pwm(
+ input wire clk,
+ input wire [PWM_PRECISION_WIDTH-1:0] duty_cycle,
+ output wire pwm_output
+ );
+
+ parameter PWM_PRECISION_WIDTH = 12;
+
+ reg [PWM_PRECISION_WIDTH-1:0] duty_cycle_reg, temp_reg, old_dc;
+ reg [PWM_PRECISION_WIDTH-1:0] pwm_count;
+
+ reg new_duty_cycle;
+ reg pwm_state;
+ reg got_new_dc;
+
+ // synchronize changes to local register if d/c changes
+ always @ (posedge clk) begin
+ if (~|pwm_count) begin
+ duty_cycle_reg <= duty_cycle; // only update when pwm_count is at 0 state
+ end else begin
+ duty_cycle_reg <= duty_cycle_reg;
+ end
+ end
+
+ // now PWM
+ always @(posedge clk) begin
+ pwm_count <= pwm_count + 1;
+ if( &duty_cycle_reg ) begin
+ pwm_state <= 1'b1; // if duty cycle is 100%, don't glitch
+ end else if( duty_cycle_reg > pwm_count ) begin
+ pwm_state <= 1'b1;
+ end else begin
+ pwm_state <= 1'b0;
+ end
+ end // always @ (posedge clk or posedge reset)
+
+ assign pwm_output = pwm_state;
+
+endmodule // mot_pwm
@@ -0,0 +1,49 @@
+// servo PWM module
+// basically, you have a major period, which is approx. 20 ms (50Hz)
+// and then a pulse, which has a tmin ~ 1ms duration
+// and a tmax ~ 2ms duration
+// and you want to subdivide the pulse by some number of ticks
+
+// we have a 26 MHz clock available which should theoretically give
+// us 38ns resolution if this is done right.
+
+// let's assume the 26 MHz clock is a given, fixed, and invariant.
+//
+// first, we need to have a mechanism to tell us when 20 ms has passed.
+// when that has passed, we then want to count out a period of time
+// which corresponds to tmin + pwmval * delta,
+// where pwmval * delta < (tmax - tmin)
+
+module servo_pwm(
+ input wire clk, // 26 MHz
+ input wire [23:0] period,
+ input wire [23:0] pulse,
+ output wire pwm_output
+ );
+
+ reg [23:0] period_cnt;
+ reg pwm_state;
+ reg pwm_deglitch;
+
+ always @(posedge clk) begin
+ if( period_cnt[23:0] >= period[23:0] ) begin
+ period_cnt <= 24'h0;
+ end else begin
+ period_cnt <= period_cnt + 1;
+ end
+ end // always @ (posedge clk or posedge reset)
+
+ always @(posedge clk) begin
+ if( period_cnt > pulse ) begin
+ pwm_state <= 1;
+ end else begin
+ pwm_state <= 0;
+ end
+
+ pwm_deglitch <= pwm_state;
+ end // always @ (posedge clk or posedge reset)
+
+ assign pwm_output = !pwm_deglitch;
+
+endmodule // servo_pwm
+
Oops, something went wrong.

0 comments on commit 8e75c74

Please sign in to comment.