You've already forked gitified_old_clb_svn
131 lines
2.4 KiB
C
131 lines
2.4 KiB
C
/*
|
|
* This work is part of the White Rabbit project
|
|
*
|
|
* Copyright (C) 2011,2012 CERN (www.cern.ch)
|
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
|
* Author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
|
|
*
|
|
* Released according to the GNU GPL, version 2 or any later version.
|
|
*/
|
|
#include "types.h"
|
|
#include "board.h"
|
|
#include "syscon.h"
|
|
|
|
#define I2C_DELAY 300
|
|
|
|
void mi2c_delay()
|
|
{
|
|
int i;
|
|
for (i = 0; i < I2C_DELAY; i++)
|
|
asm volatile ("nop");
|
|
}
|
|
|
|
#define M_SDA_OUT(i, x) { gpio_out(i2c_if[i].sda, x); mi2c_delay(); }
|
|
#define M_SCL_OUT(i, x) { gpio_out(i2c_if[i].scl, x); mi2c_delay(); }
|
|
#define M_SDA_IN(i) gpio_in(i2c_if[i].sda)
|
|
|
|
void mi2c_start(uint8_t i2cif)
|
|
{
|
|
M_SDA_OUT(i2cif, 0);
|
|
M_SCL_OUT(i2cif, 0);
|
|
}
|
|
|
|
void mi2c_repeat_start(uint8_t i2cif)
|
|
{
|
|
M_SDA_OUT(i2cif, 1);
|
|
M_SCL_OUT(i2cif, 1);
|
|
M_SDA_OUT(i2cif, 0);
|
|
M_SCL_OUT(i2cif, 0);
|
|
}
|
|
|
|
void mi2c_stop(uint8_t i2cif)
|
|
{
|
|
M_SDA_OUT(i2cif, 0);
|
|
M_SCL_OUT(i2cif, 1);
|
|
M_SDA_OUT(i2cif, 1);
|
|
}
|
|
|
|
unsigned char mi2c_put_byte(uint8_t i2cif, unsigned char data)
|
|
{
|
|
char i;
|
|
unsigned char ack;
|
|
|
|
for (i = 0; i < 8; i++, data <<= 1) {
|
|
M_SDA_OUT(i2cif, data & 0x80);
|
|
M_SCL_OUT(i2cif, 1);
|
|
M_SCL_OUT(i2cif, 0);
|
|
}
|
|
|
|
M_SDA_OUT(i2cif, 1);
|
|
M_SCL_OUT(i2cif, 1);
|
|
|
|
ack = M_SDA_IN(i2cif); /* ack: sda is pulled low ->success. */
|
|
|
|
M_SCL_OUT(i2cif, 0);
|
|
M_SDA_OUT(i2cif, 0);
|
|
|
|
return ack != 0;
|
|
}
|
|
|
|
void mi2c_get_byte(uint8_t i2cif, unsigned char *data, uint8_t last)
|
|
{
|
|
|
|
int i;
|
|
unsigned char indata = 0;
|
|
|
|
M_SDA_OUT(i2cif, 1);
|
|
/* assert: scl is low */
|
|
M_SCL_OUT(i2cif, 0);
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
M_SCL_OUT(i2cif, 1);
|
|
indata <<= 1;
|
|
if (M_SDA_IN(i2cif))
|
|
indata |= 0x01;
|
|
M_SCL_OUT(i2cif, 0);
|
|
}
|
|
|
|
if (last) {
|
|
M_SDA_OUT(i2cif, 1); //noack
|
|
M_SCL_OUT(i2cif, 1);
|
|
M_SCL_OUT(i2cif, 0);
|
|
} else {
|
|
M_SDA_OUT(i2cif, 0); //ack
|
|
M_SCL_OUT(i2cif, 1);
|
|
M_SCL_OUT(i2cif, 0);
|
|
}
|
|
|
|
*data = indata;
|
|
}
|
|
|
|
void mi2c_init(uint8_t i2cif)
|
|
{
|
|
M_SCL_OUT(i2cif, 1);
|
|
M_SDA_OUT(i2cif, 1);
|
|
}
|
|
|
|
uint8_t mi2c_devprobe(uint8_t i2cif, uint8_t i2c_addr)
|
|
{
|
|
uint8_t ret;
|
|
mi2c_start(i2cif);
|
|
ret = !mi2c_put_byte(i2cif, i2c_addr << 1);
|
|
mi2c_stop(i2cif);
|
|
|
|
return ret;
|
|
}
|
|
|
|
//void mi2c_scan(uint8_t i2cif)
|
|
//{
|
|
// int i;
|
|
//
|
|
// //for(i=0;i<0x80;i++)
|
|
// for(i=0x50;i<0x51;i++)
|
|
// {
|
|
// mi2c_start(i2cif);
|
|
// if(!mi2c_put_byte(i2cif, i<<1)) mprintf("found : %x\n", i);
|
|
// mi2c_stop(i2cif);
|
|
//
|
|
// }
|
|
// mprintf("Nothing more found...\n");
|
|
//}
|