Hi,
I want to implement a code to send data, recieved from 5 sensors, to PC via USB. I used an example program sci_loopback, took a couple of lines from it and put it in the program which captures data from the sensors via I2C.
Before I added the lines using SCI, everything was going well... Every sensor responded as it should have.
But when I added a function responsible for sending data via UART from 2 sensors, the other sensors started giving weird and wrong data.
The funny thing is that when I add the SCI function only to the first sensor, I was able to see the data on RealTerm form COM port and the rest of the sensors worked good as well. But add the SCI function to another sensor - it ruins the rest of data recieved from other sensors.
I suppose it has something to do with I2CDRR register fom which I save data to Uint16 buffer.
The whole code is beneath:
(heared files addede to the project are the same as those from example i2c_eeprom + sci.h obviously)
(some comments are in polish)
/*
temp_LM_1
temp_LM_2
RH_SHT
Bufor_TSL_1
Bufor_TSL_2
*/
#include "DSP28x_Project.h"
void I2CA_Init(void);
void delay(unsigned char);
//interrupt void scia_rx_isr(void);
//interrupt void scia_tx_isr(void);
void scia_loopback_init(void);
void scia_fifo_init(void);
void scia_xmit(int a);
Uint16 Bufor_LM_1[2],Bufor_LM_2[2], Bufor_SHT[3], Bufor_TSL_1[5], Bufor_TSL_2[5];
Uint16 i, licznik, flag, czujnik;
Uint16 temp;
float temp_LM_1, temp_LM_2, RH_SHT;
long WaitTime = 110; // (9.3uS) @ 60Mhz TMS320F28035
void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2803x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the DSP2803x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();
// Setup only the GP I/O only for I2C functionality
InitI2CGpio();
InitSciGpio();
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2803x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2803x_DefaultIsr.c.
// This function is found in DSP2803x_PieVect.c.
InitPieVectTable();
EnableInterrupts();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
// PieVectTable.I2CINT1A = &i2c_int1a_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2803x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
I2CA_Init();
scia_fifo_init(); // Initialize the SCI FIFO
scia_loopback_init(); // Initalize SCI for digital loop back
// Enable interrupts required for this example
// Enable I2C interrupt 1 in the PIE: Group 8 interrupt 1
PieCtrlRegs.PIEIER8.bit.INTx1 = 1;
// Enable CPU INT8 which is connected to PIE group 8
IER |= M_INT8;
EINT;
flag = 0;
licznik = 0;
temp_LM_1 = 0;
temp_LM_2 = 0;
RH_SHT = 0;
czujnik = 1;
//czyszczenie buforow
for (i=0; i<2; i++)
{
Bufor_LM_1[i] = 0x0000;
Bufor_LM_2[i] = 0x0000;
}
for (i=0; i<5; i++)
{
Bufor_TSL_1[i] = 0x0000;
Bufor_TSL_2[i] = 0x0000;
}
for (i=0; i<3; i++)
{
Bufor_SHT[i] = 0x0000;
}
//nieskonczona petla programu
for(;;)
{
if(czujnik == 1)
{
while(czujnik != 2)
{
I2caRegs.I2CSAR = 0x4F; //ustalenie adresu czujnika LM_1
I2caRegs.I2CCNT = 2; //ile bajtow chcemy otrzymać
I2caRegs.I2CMDR.all = 0x2C20; //send restart as master reciver
if(I2caRegs.I2CSTR.bit.RRDY == 1) //register access ready
{
Bufor_LM_1[0] = I2caRegs.I2CDRR; //wypelnianie bufora danymi z czujnika
while(I2caRegs.I2CSTR.bit.RRDY == 0)
{
I2caRegs.I2CMDR.all = 0x2C20;
flag++;
}
Bufor_LM_1[1] = I2caRegs.I2CDRR;
temp_LM_1 = ((Bufor_LM_1[0]*256 + Bufor_LM_1[1])/32)*0.125;
czujnik = 2;
}
}
//czujnik = 2;
}
if(czujnik == 2)
{
while(czujnik != 3)
{
I2caRegs.I2CSAR = 0x48; //ustalenie adresu czujnika LM_2
I2caRegs.I2CCNT = 2; //ile bajtow chcemy otrzymać
I2caRegs.I2CMDR.all = 0x2C20; //send restart as master reciver
if(I2caRegs.I2CSTR.bit.RRDY == 1) //register access ready
{
Bufor_LM_2[0] = I2caRegs.I2CDRR; //wypelnianie bufora danymi z czujnika
while(I2caRegs.I2CSTR.bit.RRDY == 0)//sprawdzenie czy bit zostal odebrany
{
I2caRegs.I2CMDR.all = 0x2C20;
flag++;
}
Bufor_LM_2[1] = I2caRegs.I2CDRR; //wypelnianie bufora danymi z czujnika
temp_LM_2 = ((Bufor_LM_2[0]*256 + Bufor_LM_2[1])/32)*0.125;//obliczenie temp.
czujnik = 3;
}
}
//czujnik = 3;
}
if(czujnik == 3)
{
while(czujnik != 4)
{
I2caRegs.I2CSAR = 0x40; //ustalenie adresu czujnika SHT21
I2caRegs.I2CCNT = 1; //ile bajtow chcemy wyslac
//I2caRegs.I2CDXR = 0x00F3; //komenda pomiar temperatury SHT21
I2caRegs.I2CDXR = 0x00F5; //komenda pomiar wilgotnosci SHT21
I2caRegs.I2CMDR.all = 0x2620; //send start as master transmitter no stop
for(i=0; i<10000; i++) licznik++;
I2caRegs.I2CSAR = 0x40; //ustalenie adresu czujnika SHT21
I2caRegs.I2CCNT = 3; //ile bajtow chcemy odebrac
I2caRegs.I2CMDR.all = 0x2C20;
for(i=0;i<3;i++)
{
while(I2caRegs.I2CSTR.bit.RRDY == 0)//sprawdzenie czy bit zostal odebrany
{
I2caRegs.I2CMDR.all = 0x2C20; //send start as master reciever with stop
flag++;
}
Bufor_SHT[i] = I2caRegs.I2CDRR; //wypelnianie bufora danymi z czujnika
} //1 i 2-dane, 3-Checksum
RH_SHT = (Bufor_SHT[0]*256 + Bufor_SHT[1]-2);
I2caRegs.I2CMDR.all = 0x0032;
czujnik = 4;
}
//czujnik = 4;
}
if(czujnik == 4)
{
while(czujnik != 5)
{
I2caRegs.I2CSAR = 0x49; //ustalenie adresu czujnika TSL_1
I2caRegs.I2CCNT = 1; //ile bajtow chcemy wyslac
I2caRegs.I2CDXR = 0x03; //data byte 3 - turn ON
I2caRegs.I2CMDR.all = 0x6E20; //send start as master transmitter with stop
delay(10);
//ODBIÓR DANYCH
I2caRegs.I2CSAR = 0x49; //ustalenie adresu czujnika TSL_1
I2caRegs.I2CCNT = 1; //ile bajtow chcemy wyslac
I2caRegs.I2CDXR = 0x9B; //
I2caRegs.I2CMDR.all = 0x2620; //send start as master reciever no stop
delay(10);
I2caRegs.I2CSAR = 0x49; //ustalenie adresu czujnika TSL_1
I2caRegs.I2CCNT = 5; //ile bajtow chcemy odebrac
I2caRegs.I2CMDR.all = 0x2C20; //send start as master reciever with stop
for(i=0;i<5;i++)
{
while(I2caRegs.I2CSTR.bit.RRDY != 1)//sprawdzenie czy bit zostal odebrany
{
I2caRegs.I2CMDR.all = 0x2C20; //send start as master reciever with stop
flag++;
}
Bufor_TSL_1[i] = I2caRegs.I2CDRR; //wypelnianie bufora danymi z czujnika
} //1-byte count, 2-5 - Data
czujnik = 5;
}
//czujnik = 5;
}
if(czujnik == 5)
{
while(czujnik != 1)
{
//RAMKA WŁĄCZANIA CZUJNIKA
I2caRegs.I2CSAR = 0x29; //ustalenie adresu czujnika TSL_2
I2caRegs.I2CCNT = 1; //ile bajtow chcemy wyslac
I2caRegs.I2CDXR = 0x03; //data byte 3 - turn ON
I2caRegs.I2CMDR.all = 0x6E20; //send start as master transmitter with stop
delay(10);
//ODBIÓR DANYCH
I2caRegs.I2CSAR = 0x29; //ustalenie adresu czujnika TSL_2
I2caRegs.I2CCNT = 1; //ile bajtow chcemy wyslac
I2caRegs.I2CDXR = 0x9B; //
I2caRegs.I2CMDR.all = 0x2620; //send start as master reciever no stop
delay(10);
I2caRegs.I2CSAR = 0x29; //ustalenie adresu czujnika TSL_2
I2caRegs.I2CCNT = 5; //ile bajtow chcemy odebrac
I2caRegs.I2CMDR.all = 0x2C20; //send start as master reciever with stop
for(i=0;i<5;i++)
{
while(I2caRegs.I2CSTR.bit.RRDY != 1)//sprawdzenie czy bit zostal odebrany
{
I2caRegs.I2CMDR.all = 0x2C20; //send start as master reciever with stop
flag++;
}
Bufor_TSL_2[i] = I2caRegs.I2CDRR; //wypelnianie bufora danymi z czujnika
} //1-byte count, 2-5 - Data
czujnik = 1;
}
//czujnik = 1;
}
licznik++;
}//koniec petli for
}//koniec funkcji main
void delay(unsigned char i)
{
long int k,j;
for(k=0;k<i;k++)
{
for(j=0;j<64000;j++);
}
}
void scia_loopback_init()
{
// Note: Clocks were turned on to the SCIA peripheral
// in the InitSysCtrl() function
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.all =0x0003;
SciaRegs.SCICTL2.bit.TXINTENA =1;
SciaRegs.SCICTL2.bit.RXBKINTENA =1;
SciaRegs.SCIHBAUD =0x0000;
SciaRegs.SCILBAUD =0x00C2; // 9600 BAUD
SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Initalize the SCI FIFO
void scia_fifo_init()
{
SciaRegs.SCIFFTX.all=0xE040;
SciaRegs.SCIFFRX.all=0x2044;
SciaRegs.SCIFFCT.all=0x0;
}
//send byte do PC
void scia_xmit(int a)
{
while(SciaRegs.SCICTL2.bit.TXRDY == 0 || SciaRegs.SCICTL2.bit.TXEMPTY == 0){}
//czekaj jesli bufor transmisji nie jest gotowy lub jest niepusty
SciaRegs.SCITXBUF = a;
//while(I2caRegs.I2CSTR.bit.RRDY == 0){temp = I2caRegs.I2CDRR;}
}
void I2CA_Init(void)
{
// Initialize I2C
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended
return;
}