Hallo.
Erstmal wollte ich mich bedanken, da ich mit hilfe euer Codes erstmal einigermaßen verstanden habe wie der Sensor anzusprechen ist. Leider ist es mir nach einer Woche noch nicht gelungen die Kommunikation zwischen meinem TI 28016, welcher auf nem Olimex Development Board sitzt, und dem BMA020 auf die Beine zu stellen.
Meine µC-Kenntnis sind eher rudimentär und mit dem TI arbeite ich erst seit 3 Wochen. Deshalb habe ich versucht ein fertiges Snippet anzupassen, geschrieben von Brad Griffis 2008.
Das ist dabei rausgekommen:
Code:
//I2C test
#include "DSP280x_Device.h" // DSP280x Headerfile Include File
#include "DSP280x_Examples.h" // DSP280x Examples Include File
// Prototype statements for functions found within this file.
void I2CA_Init(void);
Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length);
Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length);
Uint16 Values[6];
void main(void)
{
InitSysCtrl(); // Step 1. Initialize System Control:
InitI2CGpio(); // Step 2. Initalize GPIO only for I2C functionality
I2CA_Init(); // Step 4. Initialize all the Device Peripherals
for(;;) // Application loop
{
I2C_Write(0x70,0x02,2);
I2C_Read(0x71,Values,6);
} // end of for(;;)
} // end of main
void I2CA_Init(void)
{
// I2caRegs.I2CSAR = 0x38; // Slave address - EEPROM control code
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
I2caRegs.I2CCLKL = 4200; // NOTE: must be non zero
I2caRegs.I2CCLKH = 4200; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x3E; // Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
// I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset, Stop I2C when suspended
// I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
// I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return;
}
Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length)
{
Uint16 i;
while (( I2caRegs.I2CSTR.bit.BB==1 )); //bus busy?
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
I2caRegs.I2CMDR.all = 0; //disable I2C during config
I2caRegs.I2CCNT = length; //number of bytes to be send
I2caRegs.I2CSAR = slvaddr; //setup receiver addr
// Mode settings
I2caRegs.I2CMDR.bit.IRS=1; //I2C module enable
I2caRegs.I2CMDR.bit.STT=1; //If master -> start condition generated
I2caRegs.I2CMDR.bit.STP=1; //If master -> stop condition generated if data counter=0
I2caRegs.I2CMDR.bit.TRX=1; //Transmitter mode
I2caRegs.I2CMDR.bit.MST=1; //Master mode
I2caRegs.I2CMDR.bit.FREE=1; //I2C module runs free
I2caRegs.I2CMDR.bit.RM=1;
/* Transmission*/
for(i=0;i<length;i++)
{
while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.bit.ARDY)); //wait for xdry flag before transmit data or ardy if NACK appears
if (I2caRegs.I2CSTR.bit.NACK==1) //if NACK appears -> SCL=low, STP=0
{
I2caRegs.I2CMDR.all=0; //reset I2C -> SCL not held low
}
I2caRegs.I2CDXR = data;
}
}
Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length)
{
Uint16 i;
while (( I2caRegs.I2CSTR.bit.BB==1 )); //bus busy?
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
I2caRegs.I2CMDR.all = 0; //disable I2C during config
I2caRegs.I2CCNT = length; //number of bytes to be send
I2caRegs.I2CSAR = slvaddr; //setup receiver addr
// Mode settings
I2caRegs.I2CMDR.bit.IRS=1; //I2C module enable
I2caRegs.I2CMDR.bit.STT=1; //If master -> start condition generated
I2caRegs.I2CMDR.bit.STP=1; //If master -> stop condition generated if data counter = 0
I2caRegs.I2CMDR.bit.MST=1; //Master mode
I2caRegs.I2CMDR.bit.FREE=1; //I2C module runs free
I2caRegs.I2CMDR.bit.NACKMOD=1;
/* Reception */
for(i=0;i<length;i++)
{
while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.bit.ARDY)); //wait for xdry flag before transmit data or ardy if NACK appears
if (I2caRegs.I2CSTR.bit.NACK==1) //if NACK appears -> SCL=low, STP=0
{
I2caRegs.I2CMDR.all=0; //reset I2C -> SCL not held low
}
while(I2caRegs.I2CSTR.bit.RRDY==1);
data[i] = I2caRegs.I2CDRR ;
}
}
//EOF
Das Ergebnis hab ich mir mit nem Oszi angeschaut: Nach dem ersten Senden wird SDI auf low gezogen und SCK bleibt high. Wenn ich die
Code:
while (( I2caRegs.I2CSTR.bit.BB==1 ));
in der Schreib- bzw. Lesefunktion auskommentiere kann ich folgendes Bild sehen:
http://img24.imageshack.us/img24/7899/bild0027h.jpg
Meiner laienhaften Meinung nach wird keine Stop Condition erzeugt, weshalb BB immer 1 ist.
Ein Versuch eine I2C-Minimalversion für diese Sache zu schreiben sah so aus:
Code:
//I2C test
#include "DSP280x_Device.h" // DSP280x Headerfile Include File
#include "DSP280x_Examples.h" // DSP280x Examples Include File
// Prototype statements for functions found within this file.
void I2CA_Init(void);
Uint16 Values[6],i;
void main(void)
{
InitSysCtrl(); // Step 1. Initialize System Control:
InitI2CGpio(); // Step 2. Initalize GPIO only for I2C functionality
I2CA_Init(); // Step 4. Initialize all the Device Peripherals:
for(;;) // Application loop
{
//---> Write instruction <--- //
I2caRegs.I2CMDR.bit.STT = 1;
I2caRegs.I2CSAR = 0x70; //Write addr
I2caRegs.I2CCNT = 3; //3bytes=2bytes addr + 1 byte instr
I2caRegs.I2CDXR = 0x02; //instr
I2caRegs.I2CMDR.bit.STP = 1;
// I2caRegs.I2CMDR.all = 0x2620; //Send data to setup EEPROM address
//---> Read values <--- //
I2caRegs.I2CMDR.bit.STT = 1;
I2caRegs.I2CSAR = 0x71; //Read addr
I2caRegs.I2CCNT = 1; //6bytes=2bytes per coordinate
Values[0] = I2caRegs.I2CDRR;
/*for(i=0;i<6;i++)
{
Values[i] = I2caRegs.I2CDRR;
}*/
I2caRegs.I2CMDR.all = 0x2C20; //Send restart as master receiver
I2caRegs.I2CMDR.bit.STP = 1;
} // end of for(;;)
} // end of main
void I2CA_Init(void)
{
// I2caRegs.I2CSAR = 0x38; // Slave address - EEPROM control code
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
I2caRegs.I2CCLKL = 4200; // NOTE: must be non zero
I2caRegs.I2CCLKH = 4200; // 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
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return;
}
//EOF
Führte aber leider auch nicht zum Ergebnis.
Falls es relevant ist ich nutze das Code Composer Studio V4.
Falls jemand hier Erfahrungen mit TI DSPs oder Vorschläge jeglicher Art zu meinen beiden Code-Versuchen hat wäre ich sehr dankbar.
Grüße
Stephan
Lesezeichen