summaryrefslogtreecommitdiffstats
path: root/I2CSPI.c
diff options
context:
space:
mode:
Diffstat (limited to 'I2CSPI.c')
-rw-r--r--I2CSPI.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/I2CSPI.c b/I2CSPI.c
new file mode 100644
index 0000000..e911792
--- /dev/null
+++ b/I2CSPI.c
@@ -0,0 +1,243 @@
+/*
+ * I2CSPI.c - algorithms to interface generic I2C/SPI devices
+ * Copyright (C) 2010-2022 Alberto Maccioni
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
+ * or see <http://www.gnu.org/licenses/>
+ */
+
+
+//configure for GUI or command-line
+#include "common.h"
+#ifdef __GTK_H__
+#define _GTKGUI
+#endif
+
+
+#ifdef _GTKGUI
+ #define printM(id) PrintMessageI2C(id);
+#else
+ #define printM(id) printf(id);
+#endif
+
+#define CS 8
+#define HLD 16
+
+void I2CReceive(int mode,int speed,int N,BYTE *buffer)
+// I2C/SPI receive
+// mode:
+// 0 = I2C 8bit
+// 1 = I2C 16bit
+// 2 = SPI 00
+// 3 = SPI 01
+// 4 = SPI 10
+// 5 = SPI 11
+// speed:
+// 0 = 100 kbps
+// 1 = 200 kbps
+// 2 = 300/400 kbps (SPI/I2C)
+// 3 = 500/800 kbps (SPI/I2C)
+{
+ int j=0;
+ if(N<0) N=0;
+ if(N>60) N=60;
+ if(mode<0) mode=0;
+ if(mode>5) mode=5;
+ if(speed<0) speed=0;
+ if(speed>3) speed=3;
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"I2C-SPI receive\tmode=%d\tspeed=%d\n",mode,speed);
+ }
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(mode<2){ //I2C mode
+ bufferU[j++]=I2C_INIT;
+ bufferU[j++]=(speed<<3)+(speed>0?0x40:0); //enable slew control if >100k
+ }
+ else{ //SPI mode
+ bufferU[j++]=EXT_PORT; //CS=1
+ bufferU[j++]=CS;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT; //CS=0
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=speed+((mode-2)<<2);
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(mode==0){ //I2C read
+ bufferU[j++]=I2C_READ;
+ bufferU[j++]=N>(DIMBUF-4)?DIMBUF-4:N;
+ bufferU[j++]=buffer[0]; //Control byte
+ bufferU[j++]=buffer[1]; //Address;
+ }
+ else if(mode==1){ //I2C read 16bit
+ bufferU[j++]=I2C_READ2;
+ bufferU[j++]=N>(DIMBUF-4)?DIMBUF-4:N;
+ bufferU[j++]=buffer[0]; //Control byte
+ bufferU[j++]=buffer[1]; //Address H;
+ bufferU[j++]=buffer[2]; //Address L;
+ }
+ else if(mode>=2){ //SPI read
+ bufferU[j++]=SPI_READ;
+ bufferU[j++]=N>(DIMBUF-5)?DIMBUF-5:N;
+ bufferU[j++]=EXT_PORT; //CS=1
+ bufferU[j++]=CS;
+ bufferU[j++]=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(10);
+ if(saveLog){
+ CloseLogFile();
+ }
+ if(bufferI[0]==I2C_READ||bufferI[0]==I2C_READ2||bufferI[0]==SPI_READ){
+ if(bufferI[1]==0xFD){
+ printM(strings[S_I2CAckErr]); //"acknowledge error"
+ }
+ else if(bufferI[1]>0xFA){
+ printM(strings[S_InsErr]); //"unknown instruction"
+ }
+ else{
+ char str[1024]="";
+ char t[16]="";
+ int i;
+ if(mode==0) sprintf(str,"> %02X %02X\r\n",bufferU[2],bufferU[3]);
+ else if(mode==1) sprintf(str,"> %02X %02X\r\n",bufferU[2],bufferU[3]);
+ strcat(str,"< ");
+ for(i=0;i<bufferI[1];i++){
+ sprintf(t,"%02X ",bufferI[i+2]);
+ strcat(str,t);
+ if(i&&i%16==15){
+ strcat(str,"\r\n");
+ }
+ }
+ strcat(str,"\r\n");
+ printM(str);
+ fflush(stdout);
+ }
+ }
+ else printM(strings[S_ComErr]);
+}
+
+void I2CSend(int mode,int speed,int N,BYTE *buffer)
+{
+// I2C/SPI send
+// mode:
+// 0 = I2C 8bit
+// 1 = I2C 16bit
+// 2 = SPI 00
+// 3 = SPI 01
+// 4 = SPI 10
+// 5 = SPI 11
+// speed:
+// 0 = 100 kbps
+// 1 = 200 kbps
+// 2 = 300/400 kbps (SPI/I2C)
+// 3 = 500/800 kbps (SPI/I2C)
+ int i,j=0;
+ if(N<0) N=0;
+ if(N>57) N=57;
+ if(mode<0) mode=0;
+ if(mode>5) mode=5;
+ if(speed<0) speed=0;
+ if(speed>3) speed=3;
+ if(saveLog){
+ OpenLogFile(); //"Log.txt"
+ fprintf(logfile,"I2C-SPI send\tmode=%d\tspeed=%d\n",mode,speed);
+ }
+ bufferU[j++]=VREG_DIS; //Disable HV reg
+ bufferU[j++]=EN_VPP_VCC; //VDD
+ bufferU[j++]=0x1;
+ if(mode<2){ //I2C mode
+ bufferU[j++]=I2C_INIT;
+ bufferU[j++]=(speed<<3)+(speed>0?0x40:0); //enable slew control if >100k
+ }
+ else{ //SPI mode
+ bufferU[j++]=EXT_PORT; //CS=1
+ bufferU[j++]=CS;
+ bufferU[j++]=0;
+ bufferU[j++]=EXT_PORT; //CS=0
+ bufferU[j++]=0;
+ bufferU[j++]=0;
+ bufferU[j++]=SPI_INIT;
+ bufferU[j++]=speed+((mode-2)<<2);
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(2);
+ j=0;
+ if(mode==0){ //I2C write
+ bufferU[j++]=I2C_WRITE;
+ bufferU[j++]=N>(DIMBUF-5)?DIMBUF-5:N;
+ bufferU[j++]=buffer[0]; //Control byte
+ bufferU[j++]=buffer[1]; //Address
+ for(i=0;i<bufferU[1];i++) bufferU[j++]=buffer[i+2];
+ }
+ else if(mode==1){ //I2C write 16bit
+ bufferU[j++]=I2C_WRITE;
+ bufferU[j++]=N+1>(DIMBUF-5)?DIMBUF-5:N+1;
+ bufferU[j++]=buffer[0]; //Control byte
+ bufferU[j++]=buffer[1]; //Address
+ bufferU[j++]=buffer[2]; //Address L
+ for(i=0;i<bufferU[1]-1;i++) bufferU[j++]=buffer[i+3];
+ }
+ if(mode>=2){ //SPI write
+ bufferU[j++]=SPI_WRITE;
+ bufferU[j++]=N>(DIMBUF-5)?DIMBUF-5:N;
+ for(i=0;i<bufferU[1];i++) bufferU[j++]=buffer[i];
+ bufferU[j++]=EXT_PORT; //CS=1
+ bufferU[j++]=CS;
+ bufferU[j++]=0;
+ }
+ bufferU[j++]=FLUSH;
+ for(;j<DIMBUF;j++) bufferU[j]=0x0;
+ PacketIO(20);
+ if(saveLog){
+ CloseLogFile();
+ }
+ if(bufferI[0]==I2C_WRITE||bufferI[0]==SPI_WRITE){
+ if(bufferI[1]==0xFD){
+ printM(strings[S_I2CAckErr]); //"acknowledge error"
+ }
+ else if(bufferI[1]>0xFA){
+ printM(strings[S_InsErr]); //"unknown instruction"
+ }
+ else{
+ char str[1024];
+ char t[16];
+ int n=2;
+ int i;
+ sprintf(str,"> ");
+ if(mode<2) n=4;
+ for(i=0;i<bufferU[1];i++){
+ sprintf(t,"%02X ",(BYTE)bufferU[i+n]);
+ strcat(str,t);
+ if(i&&i%16==15){
+ strcat(str,"\r\n");
+ }
+ }
+ strcat(str,"\r\n");
+ printM(str);
+ }
+ }
+ else printM(strings[S_ComErr]); //"communication error \r\n"
+}
+