Драйвер i2c-vortex для ЗОСРВ Нейтрино редакции 2020
This commit is contained in:
commit
4e4298f0b9
55
README.md
Normal file
55
README.md
Normal file
@ -0,0 +1,55 @@
|
||||
## Общая структура I2C драйвера
|
||||
|
||||
```
|
||||
┌───────────────────────────┐
|
||||
│ │
|
||||
│ I2C шина │
|
||||
│ │
|
||||
└─────────────▴─────────────┘
|
||||
│
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
│ I2C-драйвер (i2c-*) │
|
||||
│ │
|
||||
└───────────────────────────┘
|
||||
▲
|
||||
┌─────────────┴─────────────┐
|
||||
│ │
|
||||
│ Клиентское приложение │
|
||||
│ │
|
||||
└───────────────────────────┘
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Дерево исходных кодов
|
||||
|
||||
```
|
||||
|- i2c/
|
||||
| `- vortex/ - Исходный код I2C-драйвера для vortex86
|
||||
| |- Makefile - Правила сборки дерева исходников
|
||||
| `- common.mk - Параметры сборки драйверов
|
||||
|
|
||||
`- Makefile - Правила сборки дерева исходников
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Сборка драйвера
|
||||
|
||||
- Установить и настроить [комплект разработчика](https://help.kpda.ru/help/topic/ru.kpda.doc.dev_tools_ru/html/devkit/devkit.html) для [ЗОСРВ "Нейтрино" редакции 2020](https://help.kpda.ru/help/index.jsp).
|
||||
- Выполнить команду:
|
||||
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Запуск драйвера
|
||||
|
||||
```
|
||||
i2c-* [параметры] &
|
||||
```
|
||||
|
||||
|
2
i2c/Makefile
Normal file
2
i2c/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
LIST=CLASS
|
||||
include recurse.mk
|
8
i2c/vortex/Makefile
Normal file
8
i2c/vortex/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
LIST=CPU
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
15
i2c/vortex/common.mk
Normal file
15
i2c/vortex/common.mk
Normal file
@ -0,0 +1,15 @@
|
||||
ifndef QCONFIG
|
||||
QCONFIG=qconfig.mk
|
||||
endif
|
||||
include $(QCONFIG)
|
||||
|
||||
NAME = i2c-vortex
|
||||
|
||||
INSTALLDIR = sbin
|
||||
|
||||
include $(MKFILES_ROOT)/qtargets.mk
|
||||
|
||||
LIBS = i2c-master
|
||||
|
||||
include $(PROJECT_ROOT)/pinfo.mk
|
||||
|
408
i2c/vortex/i2c-vortex.c
Normal file
408
i2c/vortex/i2c-vortex.c
Normal file
@ -0,0 +1,408 @@
|
||||
/*
|
||||
* (c) 2022, SWD Embedded Systems Limited, http://www.kpda.ru
|
||||
*/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
struct sigevent int_event;
|
||||
unsigned long int_n = 0;
|
||||
uintptr_t pci_io;
|
||||
void *pci;
|
||||
|
||||
int i2c_master_getfuncs(i2c_master_funcs_t *funcs, int tabsize) {
|
||||
I2C_ADD_FUNC(i2c_master_funcs_t, funcs, init, vortex_i2c_init, tabsize);
|
||||
I2C_ADD_FUNC(i2c_master_funcs_t, funcs, fini, vortex_i2c_fini, tabsize);
|
||||
I2C_ADD_FUNC(i2c_master_funcs_t, funcs, send, vortex_i2c_send, tabsize);
|
||||
I2C_ADD_FUNC(i2c_master_funcs_t, funcs, recv, vortex_i2c_recv, tabsize);
|
||||
I2C_ADD_FUNC(i2c_master_funcs_t, funcs, set_slave_addr, vortex_i2c_set_slave_addr, tabsize);
|
||||
I2C_ADD_FUNC(i2c_master_funcs_t, funcs, set_bus_speed, vortex_i2c_set_bus_speed, tabsize);
|
||||
I2C_ADD_FUNC(i2c_master_funcs_t, funcs, version_info, vortex_i2c_version_info, tabsize);
|
||||
I2C_ADD_FUNC(i2c_master_funcs_t, funcs, driver_info, vortex_i2c_driver_info, tabsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int verbosity = 0;
|
||||
|
||||
int vortex_i2c_driver_info(void *hdl, i2c_driver_info_t *info) {
|
||||
info->speed_mode = I2C_SPEED_STANDARD | I2C_SPEED_FAST;
|
||||
info->addr_mode = I2C_ADDRFMT_7BIT | I2C_ADDRFMT_10BIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *vortex_i2c_init(int argc, char *argv[]) {
|
||||
vortex_i2c_dev_t *dev = NULL;
|
||||
|
||||
if (-1 == ThreadCtl(_NTO_TCTL_IO, 0)) {
|
||||
perror("ThreadCtl");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev = malloc(sizeof(vortex_i2c_dev_t));
|
||||
if (!dev) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (-1 == vortex_i2c_parseopts(dev, argc, argv))
|
||||
goto fail;
|
||||
|
||||
if (pthread_mutex_init (&dev->lock, NULL) == -1) {
|
||||
perror("Unable to initialize lock");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
I2C_Set_Base(I2C_DEF_BASE_ADDR);
|
||||
dev->physbase = I2C_Init(I2C_CHANNEL0);
|
||||
|
||||
return dev;
|
||||
|
||||
fail:
|
||||
free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i2c_status_t vortex_i2c_recv(void *hdl, void *buf, unsigned int len, unsigned int stop) {
|
||||
vortex_i2c_dev_t *dev = hdl;
|
||||
int recvd = len - 1;
|
||||
unsigned char *buffer = buf;
|
||||
int rval = I2C_STATUS_DONE;
|
||||
uint16_t ba;
|
||||
|
||||
v_i2c_slogf(_SLOG_INFO, "[%s]", __FUNCTION__);
|
||||
|
||||
if (len <= 0)
|
||||
return I2C_STATUS_DONE;
|
||||
|
||||
pthread_mutex_lock(&dev->lock);
|
||||
|
||||
I2C_Set_Base(I2C_DEF_BASE_ADDR);
|
||||
I2C_Start(I2C_CHANNEL0, dev->slave_addr.addr & 0xFE, I2C_NOTLASTBYTE, DEF_TIMEOUT);
|
||||
I2C_WriteByte(I2C_CHANNEL0, buffer[0], I2C_NOTLASTBYTE, DEF_TIMEOUT);
|
||||
|
||||
do {
|
||||
I2C_Start(I2C_CHANNEL0, dev->slave_addr.addr | 0x01, I2C_NOTLASTBYTE, DEF_TIMEOUT);
|
||||
I2C_ReadByte(I2C_CHANNEL0, buffer+recvd, I2C_NOTLASTBYTE, DEF_TIMEOUT);
|
||||
recvd--;
|
||||
} while (recvd >= 0 && rval != I2C_STATUS_ERROR && rval != I2C_STATUS_NACK);
|
||||
|
||||
v_i2c_slogf(_SLOG_INFO, "[%s] *** STAT = 0x%02x", __FUNCTION__, i2c_get_byte(I2C_DATA_REG));
|
||||
|
||||
i2c_set_stop(ba);
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int vortex_i2c_parseopts(vortex_i2c_dev_t *dev, int argc, char *argv[]) {
|
||||
int c;
|
||||
int prev_optind;
|
||||
int done = 0;
|
||||
|
||||
while (!done) {
|
||||
prev_optind = optind;
|
||||
c = getopt(argc, argv, "v");
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
if (optopt == '-') {
|
||||
++optind;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
|
||||
case -1:
|
||||
if (prev_optind < optind)
|
||||
return -1;
|
||||
|
||||
if (argv[optind] == NULL) {
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*argv[optind] != '-') {
|
||||
++optind;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vortex_i2c_set_slave_addr(void *hdl, unsigned int addr, i2c_addrfmt_t fmt) {
|
||||
vortex_i2c_dev_t *dev = hdl;
|
||||
|
||||
if (fmt != I2C_ADDRFMT_7BIT && fmt != I2C_ADDRFMT_10BIT) {
|
||||
v_i2c_slogf(_SLOG_INFO, "[%s] Invalid address format", __FUNCTION__, addr);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
v_i2c_slogf(_SLOG_INFO, "[%s] Setting slave address to 0x%x", __FUNCTION__, addr);
|
||||
dev->slave_addr.addr = addr;
|
||||
dev->slave_addr.fmt = fmt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v_i2c_slogf(int level, const char *fmt, ...) {
|
||||
int status = 0;
|
||||
|
||||
if (level <= verbosity) {
|
||||
va_list arg;
|
||||
va_start(arg, fmt);
|
||||
|
||||
status = vslogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), level, fmt, arg);
|
||||
if (verbosity > 7) {
|
||||
status = vfprintf(stderr, fmt, arg);
|
||||
status += fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
i2c_status_t vortex_i2c_send(void *hdl, void *buf, unsigned int len, unsigned int stop) {
|
||||
vortex_i2c_dev_t *dev = hdl;
|
||||
unsigned char *buffer = buf;
|
||||
unsigned int transmitted = 0;
|
||||
int rval = I2C_STATUS_DONE;
|
||||
uint16_t timeout;
|
||||
uint16_t ba;
|
||||
|
||||
if (len <= 0)
|
||||
return I2C_STATUS_DONE;
|
||||
|
||||
pthread_mutex_lock(&dev->lock);
|
||||
|
||||
I2C_Set_Base(I2C_DEF_BASE_ADDR);
|
||||
ba = I2C_Init(I2C_CHANNEL0);
|
||||
|
||||
do {
|
||||
v_i2c_slogf(_SLOG_INFO, "[%s] *** Sending data byte (0x%02x) to (0x%x)", __FUNCTION__, buffer[transmitted],
|
||||
dev->slave_addr.addr);
|
||||
timeout = I2C_Start(I2C_CHANNEL0, dev->slave_addr.addr & 0xFE, I2C_NOTLASTBYTE, DEF_TIMEOUT);
|
||||
timeout = I2C_WriteByte(I2C_CHANNEL0, buffer[transmitted], I2C_NOTLASTBYTE, DEF_TIMEOUT);
|
||||
if(timeout == 0) {
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
return 0;
|
||||
}
|
||||
v_i2c_slogf(_SLOG_INFO, "[%s] 0", __FUNCTION__);
|
||||
} while (++transmitted < len);
|
||||
|
||||
i2c_set_stop(ba);
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
return rval;
|
||||
}
|
||||
|
||||
void vortex_i2c_fini(void *hdl) {
|
||||
vortex_i2c_dev_t *dev = hdl;
|
||||
pthread_mutex_destroy(&dev->lock);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
int vortex_i2c_set_bus_speed(void *hdl, unsigned int speed, unsigned int *ospeed) {
|
||||
vortex_i2c_dev_t *dev = hdl;
|
||||
|
||||
if (ospeed)
|
||||
*ospeed = dev->scl_freq;
|
||||
|
||||
if (speed == dev->scl_freq) {
|
||||
return 0;
|
||||
}
|
||||
dev->scl_freq = speed;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vortex_i2c_version_info(i2c_libversion_t *version) {
|
||||
version->major = I2CLIB_VERSION_MAJOR;
|
||||
version->minor = I2CLIB_VERSION_MINOR;
|
||||
version->revision = I2CLIB_REVISION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I2C_Set_Base(uint16_t ba) {
|
||||
uint32_t pwr_dat;
|
||||
|
||||
pci_read_config(pci, I2C_BASE_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
pwr_dat = (pwr_dat & 0xFFFF0000) | 0x80000000 | (ba & 0xFFF0);
|
||||
pci_write_config(pci, I2C_BASE_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
}
|
||||
|
||||
uint16_t inline i2c_get_base(uint8_t channel) {
|
||||
uint32_t pwr_dat;
|
||||
|
||||
pci_read_config(pci, I2C_BASE_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
pwr_dat = (pwr_dat & 0xFFF0) + ((0 << 3) & 0x08);
|
||||
return pwr_dat;
|
||||
}
|
||||
|
||||
|
||||
uint16_t I2C_Init(uint8_t channel) {
|
||||
uint16_t ba;
|
||||
uint32_t pwr_dat;
|
||||
int pd;
|
||||
channel = I2C_CHANNEL0;
|
||||
vortex_i2c_dev_t *dev;
|
||||
|
||||
struct pci_dev_info;
|
||||
|
||||
pd = pci_attach(0);
|
||||
|
||||
if (-1 == pd) {
|
||||
perror("pci_attach");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dev->vendor = 0x17f3;
|
||||
dev->device = 0x6035;
|
||||
|
||||
attach_to_device(dev->vendor, dev->device);
|
||||
|
||||
I2C_Set_Base(I2C_DEF_BASE_ADDR);
|
||||
|
||||
I2C_Power_On(channel);
|
||||
ba = i2c_get_base(channel);
|
||||
i2c_reset(ba);
|
||||
out8(ba + I2C_CLK_CONTROL1, I2C_CLK1_400);
|
||||
out8(ba + I2C_CLK_CONTROL2, I2C_CLK2_VAL);
|
||||
out8(ba + I2C_STATUS, I2C_DEF_STATUS);
|
||||
out8(ba + I2C_CONTROL, I2C_DEF_CONTROL);
|
||||
pci_read_config(pci, VORTEX_ICNT_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
pwr_dat |= 0x00000100;
|
||||
pci_write_config(pci, VORTEX_ICNT_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
void I2C_Power_On(uint8_t channel) {
|
||||
uint32_t pwr_dat;
|
||||
|
||||
pci_read_config(pci, I2C_PINMODE_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
pwr_dat |= (0x02 << (channel & 0x01));
|
||||
pci_write_config(pci, I2C_PINMODE_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
pci_read_config(pci, I2C_PWR_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
pwr_dat &= (~(0x10000 << (channel & 0x01)));
|
||||
pci_write_config(pci, I2C_PWR_PCICFG, 1, sizeof(pwr_dat), &pwr_dat);
|
||||
}
|
||||
|
||||
uint16_t I2C_Start(uint8_t channel, uint8_t addr, uint8_t gen_stop, uint16_t timeout) {
|
||||
uint16_t ba;
|
||||
|
||||
ba = i2c_get_base(channel);
|
||||
i2c_clr_rx(ba);
|
||||
i2c_clr_tx(ba);
|
||||
i2c_put_addr(ba, addr);
|
||||
timeout = i2c_wait_tx(ba, timeout);
|
||||
if(timeout == 0) {
|
||||
return 0;
|
||||
};
|
||||
i2c_clr_tx(ba);
|
||||
if(addr & 0x01) i2c_get_byte(ba);
|
||||
if(gen_stop) {
|
||||
i2c_set_stop(ba);
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
uint16_t I2C_WriteByte(uint8_t channel, uint8_t dat, uint8_t lastbyte, uint16_t timeout) {
|
||||
uint16_t ba;
|
||||
|
||||
ba = i2c_get_base(channel);
|
||||
i2c_put_byte(ba, dat);
|
||||
timeout = i2c_wait_tx(ba, timeout);
|
||||
if(timeout == 0) return 0;
|
||||
i2c_clr_tx(ba);
|
||||
if(lastbyte) {
|
||||
i2c_set_stop(ba);
|
||||
}
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
uint16_t I2C_ReadByte(uint8_t channel, uint8_t * dat, uint8_t lastbyte, uint16_t timeout) {
|
||||
uint16_t ba;
|
||||
|
||||
ba = i2c_get_base(channel);
|
||||
timeout = i2c_wait_rx(ba, timeout);
|
||||
if(timeout == 0) return 0;
|
||||
if(lastbyte) i2c_set_stop(ba);
|
||||
*dat = i2c_get_byte(ba);
|
||||
i2c_clr_rx(ba);
|
||||
if(lastbyte == 0) i2c_get_byte(ba);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
void inline i2c_clr_rx(uint16_t ba) {
|
||||
out8(ba + I2C_STATUS, I2C_RX_RDY);
|
||||
}
|
||||
|
||||
void inline i2c_put_addr(uint16_t ba, uint8_t addr) {
|
||||
out8(ba + I2C_RW_ADDR, addr);
|
||||
}
|
||||
|
||||
void inline i2c_put_byte(uint16_t ba, uint8_t dat) {
|
||||
out8(ba + I2C_DATA_REG, dat);
|
||||
}
|
||||
|
||||
void inline i2c_clr_tx(uint16_t ba) {
|
||||
out8(ba + I2C_STATUS, I2C_TX_DONE);
|
||||
}
|
||||
|
||||
uint16_t inline i2c_wait_tx(uint16_t ba, uint16_t timeout) {
|
||||
while(timeout > 0) {
|
||||
if(in8(ba + I2C_STATUS) & I2C_TX_DONE) break;
|
||||
nanospin_ns(15000);
|
||||
timeout = timeout - 1;
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
uint16_t inline i2c_wait_rx(uint16_t ba, uint16_t timeout) {
|
||||
while(timeout > 0) {
|
||||
if(in8(ba + I2C_STATUS) & I2C_RX_RDY) break;
|
||||
nanospin_ns(15000);
|
||||
timeout = timeout - 1;
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
uint8_t inline i2c_get_byte(uint16_t ba) {
|
||||
return in8(ba + I2C_DATA_REG);
|
||||
}
|
||||
|
||||
void inline i2c_set_stop(uint16_t ba) {
|
||||
out8(ba + I2C_CONTROL, I2C_TX_STOP);
|
||||
}
|
||||
|
||||
void inline i2c_reset(uint16_t ba) {
|
||||
out8(ba + I2C_EX_CONTROL, in8(ba + I2C_EX_CONTROL) | 0x80);
|
||||
}
|
||||
|
||||
int attach_to_device(unsigned vendor, unsigned device)
|
||||
{
|
||||
struct pci_dev_info pci_info;
|
||||
|
||||
memset(&pci_info, 0, sizeof pci_info);
|
||||
pci_info.VendorId = vendor;
|
||||
pci_info.DeviceId = device;
|
||||
|
||||
pci = pci_attach_device(NULL, PCI_SEARCH_VENDEV|PCI_SHARE, 0, &pci_info);
|
||||
|
||||
if (pci == NULL) {
|
||||
printf("Device not found. Error: %s \n\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
pci_attach_device(pci, PCI_INIT_ALL|PCI_INIT_ROM|PCI_SHARE, 0, &pci_info);
|
||||
|
||||
int_n = pci_info.Irq;
|
||||
|
||||
return 1;
|
||||
}
|
7
i2c/vortex/i2c-vortex.use
Normal file
7
i2c/vortex/i2c-vortex.use
Normal file
@ -0,0 +1,7 @@
|
||||
%C - I2C bus resource manager for vortex86 family
|
||||
|
||||
Usage: i2c-vortex [-v*]
|
||||
|
||||
Options:
|
||||
|
||||
-v Verbose (for debugging purposes)
|
3
i2c/vortex/pinfo.mk
Normal file
3
i2c/vortex/pinfo.mk
Normal file
@ -0,0 +1,3 @@
|
||||
define PINFO
|
||||
PINFO DESCRIPTION=I2C bus driver for the vortex86
|
||||
endef
|
129
i2c/vortex/proto.h
Executable file
129
i2c/vortex/proto.h
Executable file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* (c) 2022, SWD Embedded Systems Limited, http://www.kpda.ru
|
||||
*/
|
||||
|
||||
#ifndef PROTO_H_
|
||||
#define PROTO_H_
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
//#include <i86.h>
|
||||
|
||||
#include <sys/neutrino.h>
|
||||
#include <sys/mman.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <hw/inout.h>
|
||||
#include <hw/i2c.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <hw/pci.h>
|
||||
#include <hw/pci_devices.h>
|
||||
|
||||
/* logging support */
|
||||
#include <stdarg.h>
|
||||
#include <sys/slog.h>
|
||||
#include <sys/slogcodes.h>
|
||||
|
||||
|
||||
#define I2C_CONTROL 0x00
|
||||
#define I2C_STATUS 0x01
|
||||
#define I2C_SL_ADDR 0x02
|
||||
#define I2C_RW_ADDR 0x03
|
||||
#define I2C_DATA_REG 0x04
|
||||
#define I2C_CLK_CONTROL1 0x05
|
||||
#define I2C_CLK_CONTROL2 0x06
|
||||
#define I2C_EX_CONTROL 0x07
|
||||
|
||||
//#define I2C_TIMEOUT 20000
|
||||
//SCL CLK=400kHz
|
||||
#define I2C_CLK1_400 0x26
|
||||
//SCL CLK=100kHz
|
||||
#define I2C_CLK1_100 0x98
|
||||
#define I2C_CLK2_VAL 0x81
|
||||
#define I2C_TX_DONE 0x20
|
||||
#define I2C_TX_STOP 0x02
|
||||
#define I2C_NACK_EN 0x01
|
||||
#define I2C_RX_RDY 0x40
|
||||
|
||||
#define I2C_DEF_STATUS 0xFC
|
||||
#define I2C_DEF_CONTROL 0x00
|
||||
#define I2C_DEF_BASE_ADDR 0xF100
|
||||
|
||||
#define one_ms_in_ticks 1190
|
||||
#define I2C_BASE_PCICFG 0x000000D4
|
||||
#define I2C_PINMODE_PCICFG 0x000000CC
|
||||
#define I2C_PWR_PCICFG 0x000000BC
|
||||
|
||||
#define VORTEX_ICNT_PCICFG 0x800000A0
|
||||
#define VORTEX_ICNT_START 0x498
|
||||
#define VORTEX_ICNT_STOP 0x499
|
||||
#define VORTEX_ICNT_VALUE 0x494
|
||||
#define TICKS_IN_1USEC 600
|
||||
#define TICKS_IN_10USEC 6000
|
||||
|
||||
#define I2C_CHANNEL0 0
|
||||
#define I2C_CHANNEL1 1
|
||||
|
||||
#define I2C_LASTBYTE 1
|
||||
#define I2C_NOTLASTBYTE 0
|
||||
|
||||
#define DEF_TIMEOUT 200
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned physbase;
|
||||
|
||||
unsigned scl_freq;
|
||||
i2c_addr_t slave_addr;
|
||||
|
||||
pthread_mutex_t lock;
|
||||
uint16_t timeout;
|
||||
unsigned device;
|
||||
unsigned vendor;
|
||||
} vortex_i2c_dev_t;
|
||||
|
||||
|
||||
// uOps
|
||||
int v_i2c_slogf(int, const char *, ...);
|
||||
int vortex_i2c_set_bus_speed(void *, unsigned int, unsigned int *);
|
||||
int vortex_i2c_version_info(i2c_libversion_t *);
|
||||
int vortex_i2c_driver_info(void *, i2c_driver_info_t *);
|
||||
int vortex_i2c_set_slave_addr(void *, unsigned int, i2c_addrfmt_t);
|
||||
void vortex_i2c_fini(void *);
|
||||
int vortex_i2c_parseopts (vortex_i2c_dev_t*, int, char**);
|
||||
int attach_to_device (unsigned vendor, unsigned device);
|
||||
void inline i2c_reset( uint16_t ba );
|
||||
void inline i2c_clr_status( uint16_t ba );
|
||||
void inline i2c_put_addr( uint16_t ba, uint8_t addr );
|
||||
uint8_t inline i2c_get_byte( uint16_t ba );
|
||||
void inline i2c_put_byte( uint16_t ba, uint8_t dat );
|
||||
void inline i2c_set_stop( uint16_t ba );
|
||||
void inline i2c_clr_rx( uint16_t ba );
|
||||
void inline i2c_clr_tx( uint16_t ba );
|
||||
void inline i2c_set_stop( uint16_t ba );
|
||||
uint16_t inline i2c_wait_tx( uint16_t ba, uint16_t timeout );
|
||||
uint16_t inline i2c_wait_rx( uint16_t ba, uint16_t timeout );
|
||||
uint32_t inline pci_get_cfg_reg( uint32_t addr );
|
||||
void inline pci_set_cfg_reg( uint32_t addr, uint32_t dat );
|
||||
uint16_t inline i2c_get_base( uint8_t channel );
|
||||
i2c_status_t vortex_i2c_send(void *, void *, unsigned int, unsigned int);
|
||||
void *vortex_i2c_init(int, char **);
|
||||
i2c_status_t vortex_i2c_recv(void *, void *, unsigned int, unsigned int);
|
||||
|
||||
// API functions
|
||||
uint16_t I2C_Get_Base();
|
||||
void I2C_Set_Base( uint16_t ba );
|
||||
void I2C_Power_On( uint8_t channel );
|
||||
uint16_t I2C_Init( uint8_t channel ); // set base address if not zero
|
||||
uint16_t I2C_Start( uint8_t channel, uint8_t addr, uint8_t gen_stop, uint16_t timeout );
|
||||
uint16_t I2C_ReadByte( uint8_t channel, uint8_t * dat, uint8_t lastbyte, uint16_t timeout );
|
||||
uint16_t I2C_WriteByte( uint8_t channel, uint8_t dat, uint8_t lastbyte, uint16_t timeout );
|
||||
|
||||
#endif /* PROTO_H_ */
|
2
i2c/vortex/x86/Makefile
Normal file
2
i2c/vortex/x86/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
LIST=VARIANT
|
||||
include recurse.mk
|
1
i2c/vortex/x86/o/Makefile
Normal file
1
i2c/vortex/x86/o/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include ../../common.mk
|
Loading…
Reference in New Issue
Block a user