Intel MAX10 I2C doesn't send any signals. how can i fix it? - i2c

I use DE10-LITE board.
I try to use I2C for connect with external ROM.
In QSYS, I set up NIOS and I2C Master Core.
there is no error with compile.
it is my code
GPIO(0) <= '0' WHEN SDA_OE = '1' ELSE 'Z';
GPIO(1) <= '0' WHEN SCL_OE = '1' ELSE 'Z';
SDA <= GPIO(0);
SCL <= GPIO(1);
u0 : component QSYS
port map (
clk_clk => MAX10_CLK1_50, -- clk.clk
reset_reset_n => RST, -- reset.reset_n
i2c_0_i2c_serial_sda_in => SDA, -- i2c_0_i2c_serial.sda_in
i2c_0_i2c_serial_scl_in => SCL, -- .scl_in
i2c_0_i2c_serial_sda_oe => SDA_OE, -- .sda_oe
i2c_0_i2c_serial_scl_oe => SCL_OE -- .scl_oe
);
GPIO are inout pins.
and i write program code in Eclips like this.
i2c_dev = alt_avalon_i2c_open("/dev/i2c_0");
if (NULL==i2c_dev)
{
printf("Error: Cannot find /dev/i2c_0\n");
//return 1;
}
while(1)
{
alt_avalon_i2c_master_target_set(i2c_dev,SLAVE_ROM_ADDR);
status=alt_avalon_i2c_enable(i2c_dev);
i2c_tx_buf[0] = 0x00;
i2c_tx_buf[1] = 0x00;
i2c_tx_buf[2] = 0x03;
i2c_tx_buf[3] = 0x04;
status=alt_avalon_i2c_master_tx(i2c_dev, i2c_tx_buf, 4, 0);
}
and i connect gpio pins to oscilloscope. but it doesn't send any signals.
i also use BusBee serial bus monitor for chseck I2C signals. but it can not detect any signals.
what is problem?

Related

Using STM32 FMC HAL driver with parallel DAC

Im trying to generate sinusoidal signal with STM32f767 and DAC8412. DAC have 12 bit data bus and 2 bit address to select one of the four analog outputs. I've configuried FMC in CubeIDE for a SRAM memory with 16 bit data and 2 bit addres. I was able to create buffer with 4096 integer values of sin(). Then i've tried to write them to addres 0x60000000, but it only writes 4 values. After that, program goes to HardFault_Handler().
#define SRAM_BANK_ADDR ((uint32_t)0x60000000)
#define RESOLUTION_T ((uint32_t)0x1000)
#define RESOLUTION_Y ((uint32_t)0x1000)
uint32_t aTxBuffer[RESOLUTION_T];
uint32_t address = SRAM_BANK_ADDR;
Thats how i try to send data to DAC:
for (uint32_t i = 0; i<RESOLUTION_T; i++ )
{
*(__IO uint32_t*) address = aTxBuffer[i];
}
Thats how i fill buffer:
static void Fill_Buffer(uint32_t *pBuffer, uint32_t res_T, uint32_t res_Y)
{
uint32_t tmpIndex = 0;
double sinVal;
/* Put in global buffer different values */
for (tmpIndex = 0; tmpIndex < res_T; tmpIndex++ )
{
sinVal = round((sin(M_TWOPI*tmpIndex/res_T)+1)*res_Y/2);
pBuffer[tmpIndex] = sinVal;
}
}

How to interact with the Linux PCA953X.c driver? How does one utilize this driver?

I have a PCA9535 GPIO Expander board connected through I²C to my Raspberry Pi. I am able to set the GPIO expander output pins (to high) using the i2cset command:
sudo i2cset 1 0x20 0x02 0xFF // 0x20 (gpio expander), and register 0x02
I came across a kernel driver for the PCA953X and loaded the kernel module gpio-pca953x.ko + modified the /boot/config.txt to include the dts overlay for the expander. When I run i2detect -y 1 (for i2c-1 bus), I can see "UU" at the 0x20 slave address, which corroborates that the driver is managing it.
If I wanted to do something comparable to what I did with the i2cset command programmatically, what API / interface should I use such that I make use of the PCA953X driver that's installed? As you can see from the code below, nothing there suggests that I would be utilizing PCA953X:
int file;
int adapter_nr = 1;
char filename[20];
snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
file = open(filename, O_RDWR);
if (file < 0) {
exit(1);
}
// Writes 0xFF to register 0x02
uint8_t cmd[2] = {0x02, 0XFF};
struct i2c_msg msg = {
.addr = 0x20,
.flags = 0,
.len = sizeof(cmd)/sizeof(uint8_t),
.buf = cmd
};
struct i2c_rdwr_ioctl_data tx = {
.msgs = &msg,
.nmsgs = 1
};
ioctl(file, I2C_RDWR, &tx);
Is there a programming route that involves utilizing the PCA953X driver? What does having that module actually do?
Thanks to #TomV for pointing it out in the comments. The PCA953X driver provides a new character device in the form of "gpiochipN". In my case, it was gpiochip2. I had not noticed this extra gpiochip in /dev as I was not looking for it. Because this is a character device, I was able to use ioctl to interact with the lines:
int fd, ret;
fd = open("/dev/gpiochip2", O_RDONLY);
if (fd < 0) {
printf("Unable to open: %s", strerror(errno));
return;
}
struct gpiohandle_request req;
req.lineoffsets[0] = 0;
req.lineoffsets[1] = 1;
req.lineoffsets[2] = 2;
req.lineoffsets[3] = 3;
req.lineoffsets[4] = 4;
req.lineoffsets[5] = 5;
req.lineoffsets[6] = 6;
req.lineoffsets[7] = 7;
req.lines = 8;
req.flags = GPIOHANDLE_REQUEST_OUTPUT;
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
if (-1 == ret) {
printf("Failed to get line handle:%s\n", strerror(ret));
close(fd);
return;
}
// Sets all 8 lines to high (equivalent to setting register 0x3 to 0b11111111 or 0xFF)
struct gpiohandle_data data;
data.values[0] = 1;
data.values[1] = 1;
data.values[2] = 1;
data.values[3] = 1;
data.values[4] = 1;
data.values[5] = 1;
data.values[6] = 1;
data.values[7] = 1;
ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (-1 == ret) {
printf("Failed to set line value\n");
}
else {
close(req.fd);
}
close(fd);
The above code interacts with the gpiochip2 character device, which is made possible by having the PCA953X installed. Without it, I would have to read and write to the registers through the i2c bus as was posted in my original question.

Can Someone explain the use of `if (EP_DATA == 13)` in the code?

unsigned char i2c_read(void)
{
unsigned char i;
lsb = SDA;
for (i = 0; i <= 7; i++) {
EP_DATA = EP_DATA << 1;
lsb = SDA;
SCL = 1;
SCL = 0;
}
if (EP_DATA == 13) {
SDA = 1;
SCL = 1;
SCL = 0;
SDA = 0;
i2c_stop();
return EP_DATA;
}
SDA = 0;
SCL = 1;
SCL = 0;
SDA = 1;
return EP_DATA;
}
I found the code on GitHub for I²C protocol for communication with DS1307 written by Embetronicx and I was unable to understand the use of the if condition if (EP_DATA == 13)
if (EP_DATA == 13) {
SDA = 1;
SCL = 1;
SCL = 0;
SDA = 0;
i2c_stop();
return EP_DATA
}
So, please can someone explain the use to that.
I don't think that this can be real working code.
This is not least because there are no delays between the clock edges. Unless the microcontroller executes these instructions at I2C compatible speeds (1940s hardware maybe?) then this will not work.
The particular if block you refer to can never be entered. Because ED_DATA is left shifted 8 times in the preceding loop, it can never equal 13.
If I was going to guess the meaning of 13 then I might suggest that it was meant to be the numerical value of '\r' a carriage return, delimiting the end of a line of ASCII text. Really though only the author of the code can tell you for certain why they wrote this.

I2C communication with Wire.h(ESP32)

I trying to connect with nitric oxide sensor over I2C bus. I'm using Wire.h library.
http://semeatech.com/uploads/SensorModule/7-Smart_EN-v1.0.pdf <- Aplication note
My code:
Wire.beginTransmission(0x0B);
Wire.write(0x00);
Wire.write(0x01);
byte err = Wire.endTransmission(false);
Wire.requestFrom(0x0B, 3);
while(Wire.available()){
//Read data
}
Sensor returns msb = 0, lsb = 0 and checkSum = 255
Am I doing something wrong with I2C bus?

Msp430 i²c module and libraries

I have a project that has a MSP430G2553 master device and a Triple-Axis Digital-Output Gyro ITG-3200 Breakout slave. ITG3200 uses i²c protocol to communicate so i've been checking out the i²c module usage on Msp. For a starter i downloaded the TI I²c examples which can be found in http://www.ti.com/lsds/ti/microcontroller/16-bit_msp430/msp430_software_landing.page After i debugged the first code which is between a MSP master and a TMP100 temperature sensor as a slave. Here is the sample code.
//******************************************************************************
// MSP430G2xx3 Demo - USCI_B0 I2C Master to TMP100, Set P1.0 if Temp > 28C
//
// Description: I2C interface to TMP100 temperature sensor in 9-bit mode.
// Timer_A CCR0 interrupt is used to wake up and read the two bytes of
// the TMP100 temperature register every 62ms. If the temperature is greater
// than 28C, P1.0 is set, else reset. CPU is operated in LPM0. I2C speed
// is ~100kHz.
// ACLK = n/a, MCLK = SMCLK = TACLK = BRCLK = default DCO = ~1.2MHz
//
// /|\ /|\ /|\
// | TMP100 10k 10k MSP430G2xx3
// | ------- | | -------------------
// +--|Vcc SDA|<-|---+->|P1.7/UCB0SDA XIN|-
// | | | | | |
// +--|A1,A0 | | | XOUT|-
// | | | | |
// +--|Vss SCL|<-+------|P1.6/UCB0SCL P1.0|---> LED
// \|/ ------- | |
//
// D. Dang
// Texas Instruments Inc.
// February 2011
// Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include <msp430.h>
unsigned int RxByteCtr;
unsigned int RxWord;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= BIT0; // P1.0 output
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x4e; // Set slave address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
IE2 |= UCB0RXIE; // Enable RX interrupt
TACTL = TASSEL_2 + MC_2; // SMCLK, contmode
while (1)
{
RxByteCtr = 2; // Load RX byte counter
UCB0CTL1 |= UCTXSTT; // I2C start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts
// Remain in LPM0 until all data
// is RX'd
if (RxWord < 0x1d00) // >28C?
P1OUT &= ~0x01; // No, P1.0 = 0
else
P1OUT |= 0x01; // Yes, P1.0 = 1
__disable_interrupt();
TACCTL0 |= CCIE; // TACCR0 interrupt enabled
__bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts
// Remain in LPM0 until TACCR0
// interrupt occurs
TACCTL0 &= ~CCIE; // TACCR0 interrupt disabled
}
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TA0_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
// The USCIAB0TX_ISR is structured such that it can be used to receive any
// 2+ number of bytes by pre-loading RxByteCtr with the byte count.
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
RxByteCtr--; // Decrement RX byte counter
if (RxByteCtr)
{
RxWord = (unsigned int)UCB0RXBUF << 8; // Get received byte
if (RxByteCtr == 1) // Only one byte left?
UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
}
else
{
RxWord |= UCB0RXBUF; // Get final received byte,
// Combine MSB and LSB
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
I built up the same circuit where 2 10k pull ups on SDA and SCL, changed the slave address to either 0x69 or 0x68 which is the gyro address given in the user guide of the device. Since i did not built up any monitoring yet, i used an oscilloscope to check out the pulses on SCL and SDA. I didn't expect to see anything on SDA yet but what i am wondering is why i can't even see any clock cycle on SCL bus. It is either always on 3.3V (MSP internal vcc) or sometimes, its near 1V (0.80~). Even when i remove the gyroscope, SDA and SCL bus, i can't see any pulses on P1.6 port. Any ideas?