demo: I2C working

parent 9a3b9bd8
...@@ -31,7 +31,7 @@ module system( ...@@ -31,7 +31,7 @@ module system(
input btn, input btn,
output [3:0] led, output [3:0] led,
inout onewire, inout onewire,
output scl, output sdc,
inout sda, inout sda,
// TDC // TDC
...@@ -438,9 +438,8 @@ uart #( ...@@ -438,9 +438,8 @@ uart #(
// System Controller // System Controller
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
wire onewire_drivelow; wire onewire_drivelow;
wire gpio_sdc; wire sdc_gpio;
wire gpio_sdaoe; wire sda_drivelow;
wire gpio_sdaout;
sysctl #( sysctl #(
.csr_addr(4'h1), .csr_addr(4'h1),
.ninputs(3), .ninputs(3),
...@@ -460,13 +459,13 @@ sysctl #( ...@@ -460,13 +459,13 @@ sysctl #(
.csr_do(csr_dr_sysctl), .csr_do(csr_dr_sysctl),
.gpio_inputs({sda, onewire, btn}), .gpio_inputs({sda, onewire, btn}),
.gpio_outputs({gpio_sdaout, gpio_sdaoe, gpio_sdc, onewire_drivelow, led}), .gpio_outputs({sda_drivelow, sdc_gpio, onewire_drivelow, led}),
.hard_reset(hard_reset) .hard_reset(hard_reset)
); );
assign onewire = onewire_drivelow ? 1'b0 : 1'bz; assign onewire = onewire_drivelow ? 1'b0 : 1'bz;
assign sdc = ~gpio_sdc ? 1'b0 : 1'bz; assign sdc = ~sdc_gpio ? 1'b0 : 1'bz;
assign sda = (gpio_sdaoe & ~gpio_sdaout) ? 1'b0 : 1'bz; assign sda = sda_drivelow ? 1'b0 : 1'bz;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// TDC // TDC
......
...@@ -20,7 +20,7 @@ NET "led[1]" LOC = F20 | IOSTANDARD = "LVCMOS18"; ...@@ -20,7 +20,7 @@ NET "led[1]" LOC = F20 | IOSTANDARD = "LVCMOS18";
NET "led[2]" LOC = F18 | IOSTANDARD = "LVCMOS18"; NET "led[2]" LOC = F18 | IOSTANDARD = "LVCMOS18";
NET "led[3]" LOC = C20 | IOSTANDARD = "LVCMOS18"; NET "led[3]" LOC = C20 | IOSTANDARD = "LVCMOS18";
NET "onewire" LOC = D4 | IOSTANDARD = "LVCMOS25"; NET "onewire" LOC = D4 | IOSTANDARD = "LVCMOS25";
NET "scl" LOC = F7 | IOSTANDARD = "LVCMOS25"; NET "sdc" LOC = F7 | IOSTANDARD = "LVCMOS25";
NET "sda" LOC = F8 | IOSTANDARD = "LVCMOS25"; NET "sda" LOC = F8 | IOSTANDARD = "LVCMOS25";
# ==== TDC ==== # ==== TDC ====
......
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* WARNING/FIXME: The I2C functions clear the other GPIO bits! */
#include <stdio.h> #include <stdio.h>
#include <hw/sysctl.h> #include <hw/sysctl.h>
...@@ -31,17 +29,20 @@ static int i2c_init() ...@@ -31,17 +29,20 @@ static int i2c_init()
unsigned int timeout; unsigned int timeout;
i2c_started = 0; i2c_started = 0;
CSR_GPIO_OUT = GPIO_I2C_SDC; CSR_GPIO_OUT |= GPIO_I2C_SDC;
/* Check the I2C bus is ready */ /* Check the I2C bus is ready */
timeout = 2000; timeout = 100;
while((timeout > 0) && (!(CSR_GPIO_IN & GPIO_I2C_SDAIN))) timeout--; while((timeout > 0) && (!(CSR_GPIO_IN & GPIO_I2C_SDAIN))) {
udelay(1);
timeout--;
}
return timeout; return timeout;
} }
static void i2c_delay() static void i2c_delay()
{ {
udelay(20); udelay(100);
} }
/* I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c */ /* I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c */
...@@ -50,25 +51,24 @@ static unsigned int i2c_read_bit() ...@@ -50,25 +51,24 @@ static unsigned int i2c_read_bit()
unsigned int bit; unsigned int bit;
/* Let the slave drive data */ /* Let the slave drive data */
CSR_GPIO_OUT = 0; CSR_GPIO_OUT &= ~(GPIO_I2C_SDC|GPIO_I2C_SDA_DRIVELOW);
i2c_delay(); i2c_delay();
CSR_GPIO_OUT = GPIO_I2C_SDC; CSR_GPIO_OUT |= GPIO_I2C_SDC;
i2c_delay(); i2c_delay();
bit = CSR_GPIO_IN & GPIO_I2C_SDAIN; bit = CSR_GPIO_IN & GPIO_I2C_SDAIN;
i2c_delay(); i2c_delay();
CSR_GPIO_OUT = 0; CSR_GPIO_OUT &= ~(GPIO_I2C_SDC);
return bit; return bit;
} }
static void i2c_write_bit(unsigned int bit) static void i2c_write_bit(unsigned int bit)
{ {
if(bit) { if(bit) {
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDAOUT; CSR_GPIO_OUT &= ~GPIO_I2C_SDA_DRIVELOW;
} else { } else {
CSR_GPIO_OUT = GPIO_I2C_SDAOE; CSR_GPIO_OUT |= GPIO_I2C_SDA_DRIVELOW;
} }
i2c_delay(); i2c_delay();
/* Clock stretching */
CSR_GPIO_OUT |= GPIO_I2C_SDC; CSR_GPIO_OUT |= GPIO_I2C_SDC;
i2c_delay(); i2c_delay();
CSR_GPIO_OUT &= ~GPIO_I2C_SDC; CSR_GPIO_OUT &= ~GPIO_I2C_SDC;
...@@ -78,26 +78,26 @@ static void i2c_start_cond() ...@@ -78,26 +78,26 @@ static void i2c_start_cond()
{ {
if(i2c_started) { if(i2c_started) {
/* set SDA to 1 */ /* set SDA to 1 */
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDAOUT; CSR_GPIO_OUT &= ~GPIO_I2C_SDA_DRIVELOW;
i2c_delay(); i2c_delay();
CSR_GPIO_OUT |= GPIO_I2C_SDC; CSR_GPIO_OUT |= GPIO_I2C_SDC;
i2c_delay();
} }
/* SCL is high, set SDA from 1 to 0 */ /* SCL is high, set SDA from 1 to 0 */
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDC; CSR_GPIO_OUT |= GPIO_I2C_SDA_DRIVELOW;
i2c_delay(); i2c_delay();
CSR_GPIO_OUT = GPIO_I2C_SDAOE; CSR_GPIO_OUT &= ~GPIO_I2C_SDC;
i2c_started = 1; i2c_started = 1;
} }
static void i2c_stop_cond() static void i2c_stop_cond()
{ {
/* set SDA to 0 */ /* set SDA to 0 */
CSR_GPIO_OUT = GPIO_I2C_SDAOE; CSR_GPIO_OUT |= GPIO_I2C_SDA_DRIVELOW;
i2c_delay();
CSR_GPIO_OUT |= GPIO_I2C_SDC;
i2c_delay(); i2c_delay();
/* Clock stretching */ CSR_GPIO_OUT &= ~GPIO_I2C_SDA_DRIVELOW;
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDC;
/* SCL is high, set SDA from 0 to 1 */
CSR_GPIO_OUT = GPIO_I2C_SDC;
i2c_delay(); i2c_delay();
i2c_started = 0; i2c_started = 0;
} }
...@@ -130,12 +130,14 @@ static unsigned char i2c_read(int ack) ...@@ -130,12 +130,14 @@ static unsigned char i2c_read(int ack)
void set_dac_level(int level) void set_dac_level(int level)
{ {
int i;
if(!i2c_init()) { if(!i2c_init()) {
printf("I2C init failed\n"); printf("I2C init failed\n");
return; return;
} }
i2c_start_cond(); i2c_start_cond();
if(!i2c_write(0x50)) if(!i2c_write(0x90))
printf("DAC not detected\n"); printf("DAC not detected\n");
i2c_write(0x2f); i2c_write(0x2f);
i2c_write((level & 0xff0) >> 4); i2c_write((level & 0xff0) >> 4);
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#define GPIO_LD5 (0x00000008) #define GPIO_LD5 (0x00000008)
#define GPIO_1W_DRIVELOW (0x00000010) #define GPIO_1W_DRIVELOW (0x00000010)
#define GPIO_I2C_SDC (0x00000020) #define GPIO_I2C_SDC (0x00000020)
#define GPIO_I2C_SDAOE (0x00000040) #define GPIO_I2C_SDA_DRIVELOW (0x00000040)
#define GPIO_I2C_SDAOUT (0x00000080)
#endif /* __HW_GPIO_H */ #endif /* __HW_GPIO_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment