2.3.6.8.2. I2C (HW api)
2.3.6.8.2.1. Description
This example demonstrates communication with the EEPROM memory on the Red Pitaya using the I2C protocol. The code below reads the calibration values from the EEPROM and displays them. The data is displayed correctly only on 125-xx boards.
2.3.6.8.2.2. Required hardware
Red Pitaya
Note
The calibration parameter order has changed with 2.00 OS. We will update the example soon.
2.3.6.8.2.3. Code - C
Note
Although the C code examples don’t require the use of the SCPI server, we have included them here to demonstrate how the same functionality can be achieved with different programming languages. Instructions on how to compile the code are here.
/* @brief This is a simple application for testing I2C communication on a RedPitaya
*
* (c) Red Pitaya http://www.redpitaya.com
*
* This part of code is written in C programming language.
* Please visit http://en.wikipedia.org/wiki/C_(programming_language)
* for more details on the language used herein.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "rp_hw.h"
int main(int argc, char *argv[]){
int res = rp_I2C_InitDevice("/dev/i2c-0",0x50); // Init i2c api.
printf("Init result: %d\n",res);
res = rp_I2C_setForceMode(true); // Set force mode.
printf("Set force mode: %d\n",res);
uint8_t wb[2] = {0,0};
res = rp_I2C_IOCTL_WriteBuffer(wb,2); // Write position for reading.
printf("Write 2 bytes: %d\n",res);
usleep(100000);
int32_t rb[12];
res = rp_I2C_IOCTL_ReadBuffer((uint8_t*)rb,32); // Read 32 bytes from I2C
printf("Read 32 bytes: %d\n",res);
res = rp_I2C_IOCTL_ReadBuffer((uint8_t*)(rb + 8),16); // Read 16 bytes from I2C
printf("Read 16 bytes: %d\n",res);
printf("ADC Ch1 High %d\n",rb[2]);
printf("ADC Ch2 High %d\n",rb[3]);
printf("ADC Ch1 Low %d\n",rb[4]);
printf("ADC Ch2 Low %d\n",rb[5]);
printf("ADC Ch1 Low offset %d\n",rb[6]);
printf("ADC Ch2 Low offset %d\n",rb[7]);
printf("DAC Ch1 %d\n",rb[8]);
printf("DAC Ch2 %d\n",rb[9]);
printf("DAC Ch1 offset %d\n",rb[10]);
printf("DAC Ch2 offset %d\n",rb[11]);
return 0;
}
/* @brief This is a simple application for testing I2C communication on a RedPitaya
*
* (c) Red Pitaya http://www.redpitaya.com
*
* This part of code is written in C programming language.
* Please visit http://en.wikipedia.org/wiki/C_(programming_language)
* for more details on the language used herein.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "rp_hw.h"
#include "rp_hw-calib.h"
int main(int argc, char *argv[]){
// This example shows how to work with EEPROM via I2C
int res = rp_I2C_InitDevice("/dev/i2c-0",0x50); // Init i2c api.
printf("Init result: %d\n",res);
res = rp_I2C_setForceMode(true); // Set force mode.
printf("Set force mode: %d\n",res);
uint8_t wb[2] = {0,0};
res = rp_I2C_IOCTL_WriteBuffer(wb,2); // Write position for reading.
printf("Write 2 bytes: %d\n",res);
usleep(100000);
uint8_t rb[1];
res = rp_I2C_IOCTL_ReadBuffer(rb,1); // Read 1 byte from I2C
printf("Read 1 byte: %d\n",res);
uint8_t df = rb[0];
printf("Data format %d\n",df);
res = rp_I2C_IOCTL_WriteBuffer(wb,2); // Write position for reading.
printf("Write 2 bytes: %d\n",res);
usleep(100000);
rp_calib_params_t calib;
if (df == 5){
rp_calib_params_universal_t data;
uint16_t size = sizeof(data);
res = rp_I2C_IOCTL_ReadBuffer((uint8_t*)&data,size);
printf("Read %d byte: %d\n",size,res);
res = rp_CalibConvertEEPROM((uint8_t*)&data,size,&calib);
printf("Convert calib: %d\n",res);
}else{
rp_eepromWpData_t data;
uint16_t size = sizeof(data);
res = rp_I2C_IOCTL_ReadBuffer((uint8_t*)&data,size);
printf("Read %d byte: %d\n",size,res);
res = rp_CalibConvertEEPROM((uint8_t*)&data,size,&calib);
printf("Convert calib: %d\n",res);
}
rp_CalibPrint(&calib);
return 0;
}
2.3.6.8.2.4. Code - MATLAB®
%% Define Red Pitaya as TCP client object
IP = '192.168.178.56'; % Input IP of your Red Pitaya...
port = 5000;
RP = tcpclient(IP, port);
%% Open connection with your Red Pitaya
RP.ByteOrder = 'big-endian';
configureTerminator(RP,'CR/LF');
writeline(RP,'I2C:DEV80 "/dev/i2c-0"');
writeline(RP,'I2C:FMODE ON'); % set force mode
% EEPROM 24c64 supports reading only 32 bytes of data at a time and only works through IOCTL
writeline(RP,'I2C:IO:W:B2 0,0'); % set read address = 0
b1 = writeread(RP,'I2C:IO:R:B32'); % read 32 bytes from iic
b2 = writeread(RP,'I2C:IO:R:B16'); % read 16 bytes from iic
b_num = str2num(b1(1,2:length(b1)-3));
b_num(33:48) = str2num(b2(1, 2:length(b2)-3));
calib = typecast(uint8(b_num),'int32');
fprintf('ADC Ch1 High %d\n', calib(3));
fprintf('ADC Ch2 High %d\n', calib(4));
fprintf('ADC Ch1 Low %d\n', calib(5));
fprintf('ADC Ch2 Low %d\n', calib(6));
fprintf('ADC Ch1 Low offset %d\n', calib(7));
fprintf('ADC Ch2 Low offset %d\n', calib(8));
fprintf('DAC Ch1 %d\n', calib(9));
fprintf('DAC Ch2 %d\n', calib(10));
fprintf('DAC Ch1 offset %d\n', calib(11));
fprintf('DAC Ch2 offset %d\n', calib(12));
%% Close connection with Red Pitaya
clear RP;
2.3.6.8.2.5. Code - Python
#!/usr/bin/env python3
import sys
import time
from struct import *
import redpitaya_scpi as scpi
rp_s = scpi.scpi(sys.argv[1])
rp_s.tx_txt('I2C:DEV80 "/dev/i2c-0"')
print("Init I2C")
rp_s.tx_txt('I2C:FMODE ON')
print("Set force mode")
# Eeprom 24c64 supports reading only 32 bytes of data at a time and only works through IOCTL
# set read address = 0
rp_s.tx_txt('I2C:IO:W:B2 0,0')
print("Write address for read")
rp_s.tx_txt('I2C:IO:R:B32')
b1 = rp_s.rx_txt().strip('{').strip('}')
rp_s.tx_txt('I2C:IO:R:B16')
b2 = rp_s.rx_txt().strip('{').strip('}')
buff = (b1 + "," + b2).split(",")
byte_array = bytearray(b'')
for s in buff:
byte_array.append(int(s))
calib = [unpack('i', byte_array[i:i+4])[0] for i in range(0, len(byte_array), 4)]
print("ADC Ch1 High", calib[2])
print("ADC Ch2 High", calib[3])
print("ADC Ch1 Low", calib[4])
print("ADC Ch2 Low", calib[5])
print("ADC Ch1 Low offset", calib[6])
print("ADC Ch2 Low offset", calib[7])
print("DAC Ch1", calib[8])
print("DAC Ch2", calib[9])
print("DAC Ch1 offset", calib[10])
print("DAC Ch2 offset", calib[11])
Note
The Python functions are accessible with the latest version of the redpitaya_scpi.py document available on our GitHub. The functions represent a quality-of-life improvement as they combine the SCPI commands in an optimal order. The code should function at approximately the same speed without them.
For further information on functions please consult the redpitaya_scpi.py code.