demo: DAC I2C access (untested)

parent 6910c04a
...@@ -31,6 +31,8 @@ module system( ...@@ -31,6 +31,8 @@ module system(
input btn, input btn,
output [3:0] led, output [3:0] led,
inout onewire, inout onewire,
output scl,
inout sda,
// TDC // TDC
output test_clk_oe_n, output test_clk_oe_n,
...@@ -436,10 +438,13 @@ uart #( ...@@ -436,10 +438,13 @@ uart #(
// System Controller // System Controller
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
wire onewire_drivelow; wire onewire_drivelow;
wire gpio_sdc;
wire gpio_sdaoe;
wire gpio_sdaout;
sysctl #( sysctl #(
.csr_addr(4'h1), .csr_addr(4'h1),
.ninputs(2), .ninputs(3),
.noutputs(5), .noutputs(8),
.systemid(32'h53504543) /* SPEC */ .systemid(32'h53504543) /* SPEC */
) sysctl ( ) sysctl (
.sys_clk(sys_clk), .sys_clk(sys_clk),
...@@ -454,12 +459,14 @@ sysctl #( ...@@ -454,12 +459,14 @@ sysctl #(
.csr_di(csr_dw), .csr_di(csr_dw),
.csr_do(csr_dr_sysctl), .csr_do(csr_dr_sysctl),
.gpio_inputs({onewire, btn}), .gpio_inputs({sda, onewire, btn}),
.gpio_outputs({onewire_drivelow, led}), .gpio_outputs({gpio_sdaout, gpio_sdaoe, gpio_sdc, 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 sda = (gpio_sdaoe & ~gpio_sdaout) ? 1'b0 : 1'bz;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// TDC // TDC
......
...@@ -20,6 +20,8 @@ NET "led[1]" LOC = F20 | IOSTANDARD = "LVCMOS18"; ...@@ -20,6 +20,8 @@ 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 "sda" LOC = F8 | IOSTANDARD = "LVCMOS25";
# ==== TDC ==== # ==== TDC ====
NET "test_clk_oe_n" LOC = V17 | IOSTANDARD = "LVCMOS25"; NET "test_clk_oe_n" LOC = V17 | IOSTANDARD = "LVCMOS25";
......
MMDIR=../.. MMDIR=../..
include $(MMDIR)/software/include.mak include $(MMDIR)/software/include.mak
OBJECTS=crt0.o main.o tdc.o temperature.o OBJECTS=crt0.o main.o tdc.o udelay.o temperature.o dac.o
SEGMENTS=-j .text -j .data -j .rodata SEGMENTS=-j .text -j .data -j .rodata
all: demo.bin demo.h0 demo.h1 demo.h2 demo.h3 all: demo.bin demo.h0 demo.h1 demo.h2 demo.h3
......
/*
* DAC5578 bit-banging driver
* Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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>
#include <hw/gpio.h>
#include "udelay.h"
static int i2c_started;
static int i2c_init()
{
unsigned int timeout;
i2c_started = 0;
CSR_GPIO_OUT = GPIO_I2C_SDC;
/* Check the I2C bus is ready */
timeout = 2000;
while((timeout > 0) && (!(CSR_GPIO_IN & GPIO_I2C_SDAIN))) timeout--;
return timeout;
}
static void i2c_delay()
{
udelay(20);
}
/* I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c */
static unsigned int i2c_read_bit()
{
unsigned int bit;
/* Let the slave drive data */
CSR_GPIO_OUT = 0;
i2c_delay();
CSR_GPIO_OUT = GPIO_I2C_SDC;
i2c_delay();
bit = CSR_GPIO_IN & GPIO_I2C_SDAIN;
i2c_delay();
CSR_GPIO_OUT = 0;
return bit;
}
static void i2c_write_bit(unsigned int bit)
{
if(bit) {
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDAOUT;
} else {
CSR_GPIO_OUT = GPIO_I2C_SDAOE;
}
i2c_delay();
/* Clock stretching */
CSR_GPIO_OUT |= GPIO_I2C_SDC;
i2c_delay();
CSR_GPIO_OUT &= ~GPIO_I2C_SDC;
}
static void i2c_start_cond()
{
if(i2c_started) {
/* set SDA to 1 */
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDAOUT;
i2c_delay();
CSR_GPIO_OUT |= GPIO_I2C_SDC;
}
/* SCL is high, set SDA from 1 to 0 */
CSR_GPIO_OUT = GPIO_I2C_SDAOE|GPIO_I2C_SDC;
i2c_delay();
CSR_GPIO_OUT = GPIO_I2C_SDAOE;
i2c_started = 1;
}
static void i2c_stop_cond()
{
/* set SDA to 0 */
CSR_GPIO_OUT = GPIO_I2C_SDAOE;
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;
i2c_delay();
i2c_started = 0;
}
static unsigned int i2c_write(unsigned char byte)
{
unsigned int bit;
unsigned int ack;
for(bit = 0; bit < 8; bit++) {
i2c_write_bit(byte & 0x80);
byte <<= 1;
}
ack = !i2c_read_bit();
return ack;
}
static unsigned char i2c_read(int ack)
{
unsigned char byte = 0;
unsigned int bit;
for(bit = 0; bit < 8; bit++) {
byte <<= 1;
byte |= i2c_read_bit();
}
i2c_write_bit(!ack);
return byte;
}
void set_dac_level(int level)
{
if(!i2c_init()) {
printf("I2C init failed\n");
return;
}
i2c_start_cond();
if(!i2c_write(0x50))
printf("DAC not detected\n");
i2c_write(0x2f);
i2c_write((level & 0xff0) >> 4);
i2c_write((level & 0x00f) << 4);
i2c_stop_cond();
}
#ifndef __DAC_H
#define __DAC_H
void set_dac_level(int level);
#endif /* __DAC_H */
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <hw/uart.h> #include <hw/uart.h>
#include "tdc.h" #include "tdc.h"
#include "dac.h"
#include "temperature.h" #include "temperature.h"
/* General address space functions */ /* General address space functions */
...@@ -189,6 +190,24 @@ static void crc(char *startaddr, char *len) ...@@ -189,6 +190,24 @@ static void crc(char *startaddr, char *len)
printf("CRC32: %08x\n", crc32((unsigned char *)addr, length)); printf("CRC32: %08x\n", crc32((unsigned char *)addr, length));
} }
static void daclevel(char *level)
{
char *c;
unsigned int level2;
if(*level == 0) {
printf("daclevel <level> \n");
return;
}
level2 = strtoul(level, &c, 0);
if(*c != 0) {
printf("incorrect level\n");
return;
}
set_dac_level(level2);
}
/* Init + command line */ /* Init + command line */
static char *get_token(char **str) static char *get_token(char **str)
...@@ -220,10 +239,11 @@ static void do_command(char *c) ...@@ -220,10 +239,11 @@ static void do_command(char *c)
else if(strcmp(token, "reboot") == 0) reboot(); else if(strcmp(token, "reboot") == 0) reboot();
/* payload */ /* payload */
else if(strcmp(token, "temp") == 0) temp();
else if(strcmp(token, "rofreq") == 0) rofreq(); else if(strcmp(token, "rofreq") == 0) rofreq();
else if(strcmp(token, "calinfo") == 0) calinfo(); else if(strcmp(token, "calinfo") == 0) calinfo();
else if(strcmp(token, "daclevel") == 0) daclevel(get_token(&c));
else if(strcmp(token, "mraw") == 0) mraw(); else if(strcmp(token, "mraw") == 0) mraw();
else if(strcmp(token, "temp") == 0) temp();
else if(strcmp(token, "diff") == 0) diff(); else if(strcmp(token, "diff") == 0) diff();
else if(strcmp(token, "") != 0) else if(strcmp(token, "") != 0)
......
...@@ -20,19 +20,9 @@ ...@@ -20,19 +20,9 @@
#include <hw/sysctl.h> #include <hw/sysctl.h>
#include <hw/gpio.h> #include <hw/gpio.h>
#include "udelay.h"
#include "temperature.h" #include "temperature.h"
static void udelay(int usec)
{
int limit;
limit = usec*125;
CSR_TIMER0_CONTROL = 0;
CSR_TIMER0_COUNTER = 0;
CSR_TIMER0_CONTROL = TIMER_ENABLE;
while(CSR_TIMER0_COUNTER < limit);
}
static int reset_1w() static int reset_1w()
{ {
int ok; int ok;
......
#include <hw/sysctl.h>
#include "udelay.h"
void udelay(int usec)
{
int limit;
limit = usec*125;
CSR_TIMER0_CONTROL = 0;
CSR_TIMER0_COUNTER = 0;
CSR_TIMER0_CONTROL = TIMER_ENABLE;
while(CSR_TIMER0_COUNTER < limit);
}
#ifndef __UDELAY_H
#define __UDELAY_H
void udelay(int usec);
#endif /* __UDELAY_H */
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
/* Inputs */ /* Inputs */
#define GPIO_PB2 (0x00000001) #define GPIO_PB2 (0x00000001)
#define GPIO_1W (0x00000002) #define GPIO_1W (0x00000002)
#define GPIO_I2C_SDAIN (0x00000004)
/* Outputs */ /* Outputs */
#define GPIO_LD2 (0x00000001) #define GPIO_LD2 (0x00000001)
...@@ -29,5 +30,8 @@ ...@@ -29,5 +30,8 @@
#define GPIO_LD4 (0x00000004) #define GPIO_LD4 (0x00000004)
#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_SDAOE (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