demo: I2C working

parent 9a3b9bd8
......@@ -31,7 +31,7 @@ module system(
input btn,
output [3:0] led,
inout onewire,
output scl,
output sdc,
inout sda,
// TDC
......@@ -438,9 +438,8 @@ uart #(
// System Controller
//---------------------------------------------------------------------------
wire onewire_drivelow;
wire gpio_sdc;
wire gpio_sdaoe;
wire gpio_sdaout;
wire sdc_gpio;
wire sda_drivelow;
sysctl #(
.csr_addr(4'h1),
.ninputs(3),
......@@ -460,13 +459,13 @@ sysctl #(
.csr_do(csr_dr_sysctl),
.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)
);
assign onewire = onewire_drivelow ? 1'b0 : 1'bz;
assign sdc = ~gpio_sdc ? 1'b0 : 1'bz;
assign sda = (gpio_sdaoe & ~gpio_sdaout) ? 1'b0 : 1'bz;
assign sdc = ~sdc_gpio ? 1'b0 : 1'bz;
assign sda = sda_drivelow ? 1'b0 : 1'bz;
//---------------------------------------------------------------------------
// TDC
......
......@@ -20,7 +20,7 @@ NET "led[1]" LOC = F20 | IOSTANDARD = "LVCMOS18";
NET "led[2]" LOC = F18 | IOSTANDARD = "LVCMOS18";
NET "led[3]" LOC = C20 | IOSTANDARD = "LVCMOS18";
NET "onewire" LOC = D4 | IOSTANDARD = "LVCMOS25";
NET "scl" LOC = F7 | IOSTANDARD = "LVCMOS25";
NET "sdc" LOC = F7 | IOSTANDARD = "LVCMOS25";
NET "sda" LOC = F8 | IOSTANDARD = "LVCMOS25";
# ==== TDC ====
......
......@@ -15,8 +15,6 @@
* 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 <hw/sysctl.h>
......@@ -31,17 +29,20 @@ static int i2c_init()
unsigned int timeout;
i2c_started = 0;
CSR_GPIO_OUT = GPIO_I2C_SDC;
CSR_GPIO_OUT |= GPIO_I2C_SDC;
/* Check the I2C bus is ready */
timeout = 2000;
while((timeout > 0) && (!(CSR_GPIO_IN & GPIO_I2C_SDAIN))) timeout--;
timeout = 100;
while((timeout > 0) && (!(CSR_GPIO_IN & GPIO_I2C_SDAIN))) {
udelay(1);
timeout--;
}
return timeout;
}
static void i2c_delay()
{
udelay(20);
udelay(100);
}
/* I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c */
......@@ -50,25 +51,24 @@ static unsigned int i2c_read_bit()
unsigned int bit;
/* Let the slave drive data */
CSR_GPIO_OUT = 0;
CSR_GPIO_OUT &= ~(GPIO_I2C_SDC|GPIO_I2C_SDA_DRIVELOW);
i2c_delay();
CSR_GPIO_OUT = GPIO_I2C_SDC;
CSR_GPIO_OUT |= GPIO_I2C_SDC;
i2c_delay();
bit = CSR_GPIO_IN & GPIO_I2C_SDAIN;
i2c_delay();
CSR_GPIO_OUT = 0;
CSR_GPIO_OUT &= ~(GPIO_I2C_SDC);
return bit;
}
static void i2c_write_bit(unsigned int bit)
{
if(bit) {
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDAOUT;
CSR_GPIO_OUT &= ~GPIO_I2C_SDA_DRIVELOW;
} else {
CSR_GPIO_OUT = GPIO_I2C_SDAOE;
CSR_GPIO_OUT |= GPIO_I2C_SDA_DRIVELOW;
}
i2c_delay();
/* Clock stretching */
CSR_GPIO_OUT |= GPIO_I2C_SDC;
i2c_delay();
CSR_GPIO_OUT &= ~GPIO_I2C_SDC;
......@@ -78,26 +78,26 @@ static void i2c_start_cond()
{
if(i2c_started) {
/* set SDA to 1 */
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDAOUT;
CSR_GPIO_OUT &= ~GPIO_I2C_SDA_DRIVELOW;
i2c_delay();
CSR_GPIO_OUT |= GPIO_I2C_SDC;
i2c_delay();
}
/* 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();
CSR_GPIO_OUT = GPIO_I2C_SDAOE;
CSR_GPIO_OUT &= ~GPIO_I2C_SDC;
i2c_started = 1;
}
static void i2c_stop_cond()
{
/* 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();
/* Clock stretching */
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDC;
/* SCL is high, set SDA from 0 to 1 */
CSR_GPIO_OUT = GPIO_I2C_SDC;
CSR_GPIO_OUT &= ~GPIO_I2C_SDA_DRIVELOW;
i2c_delay();
i2c_started = 0;
}
......@@ -130,12 +130,14 @@ static unsigned char i2c_read(int ack)
void set_dac_level(int level)
{
int i;
if(!i2c_init()) {
printf("I2C init failed\n");
return;
}
i2c_start_cond();
if(!i2c_write(0x50))
if(!i2c_write(0x90))
printf("DAC not detected\n");
i2c_write(0x2f);
i2c_write((level & 0xff0) >> 4);
......
......@@ -31,7 +31,6 @@
#define GPIO_LD5 (0x00000008)
#define GPIO_1W_DRIVELOW (0x00000010)
#define GPIO_I2C_SDC (0x00000020)
#define GPIO_I2C_SDAOE (0x00000040)
#define GPIO_I2C_SDAOUT (0x00000080)
#define GPIO_I2C_SDA_DRIVELOW (0x00000040)
#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