Forum: Digitale Signalverarbeitung / DSP / Machine Learning I2C-Kommunikationsproblem zwischen TI 28016 und Sensor BMA020


von Stephan (Gast)


Lesenswert?

Hallo.

Ich versuche seit einer Woche vergeblich die I2C-Kommunikation zwischen 
meinem TI 28016, welcher auf nem Olimex Development Board sitzt, und 
einem  BMA020 Beschleunigungssensor herzustellen. Laut Datenblatt zum 
Sensor sind dafür "nur" folgende Schritte notwendig:

- Befehl 0x02 an Adresse 0x70 (fixe Sensoradresse 0x38 plus RW=0) senden
- 6 Byte (Messergebnisse) von Adresse 0x71 (fixe Sensoradresse 0x38 plus 
RW=1) auslesen

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:
1
//I2C test 
2
3
#include "DSP280x_Device.h"     // DSP280x Headerfile Include File
4
#include "DSP280x_Examples.h"   // DSP280x Examples Include File
5
6
// Prototype statements for functions found within this file.
7
void   I2CA_Init(void);
8
Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length);
9
Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length);
10
11
Uint16 Values[6];
12
13
void main(void)
14
{
15
   InitSysCtrl();  // Step 1. Initialize System Control:
16
   InitI2CGpio();  // Step 2. Initalize GPIO only for I2C functionality
17
   I2CA_Init();    // Step 4. Initialize all the Device Peripherals
18
19
   for(;;)    // Application loop
20
   {   
21
     I2C_Write(0x70,0x02,2);
22
     I2C_Read(0x71,Values,6);
23
   }   // end of for(;;)
24
}   // end of main
25
26
27
void I2CA_Init(void)
28
{
29
//   I2caRegs.I2CSAR = 0x38;    // Slave address - EEPROM control code
30
   I2caRegs.I2CPSC.all = 6;    // Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
31
   I2caRegs.I2CCLKL = 4200;    // NOTE: must be non zero
32
   I2caRegs.I2CCLKH = 4200;    // NOTE: must be non zero
33
   I2caRegs.I2CIER.all = 0x3E;    // Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
34
//   I2caRegs.I2CMDR.all = 0x0020;  // Take I2C out of reset, Stop I2C when suspended
35
//   I2caRegs.I2CFFTX.all = 0x6000;  // Enable FIFO mode and TXFIFO
36
//   I2caRegs.I2CFFRX.all = 0x2040;  // Enable RXFIFO, clear RXFFINT,
37
   return;
38
}
39
40
Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length)
41
{
42
   Uint16 i;
43
   while (( I2caRegs.I2CSTR.bit.BB==1 ));  //bus busy?
44
   if (I2caRegs.I2CSTR.bit.BB == 1)
45
   {
46
      return I2C_BUS_BUSY_ERROR;
47
   }
48
  I2caRegs.I2CMDR.all = 0;  //disable I2C during config
49
  I2caRegs.I2CCNT = length;  //number of bytes to be send
50
  I2caRegs.I2CSAR = slvaddr;  //setup receiver addr
51
//  Mode settings
52
  I2caRegs.I2CMDR.bit.IRS=1;  //I2C module enable              
53
  I2caRegs.I2CMDR.bit.STT=1;  //If master -> start condition generated
54
  I2caRegs.I2CMDR.bit.STP=1;  //If master -> stop condition generated if data counter=0
55
  I2caRegs.I2CMDR.bit.TRX=1;  //Transmitter mode
56
  I2caRegs.I2CMDR.bit.MST=1;  //Master mode
57
  I2caRegs.I2CMDR.bit.FREE=1;  //I2C module runs free
58
  I2caRegs.I2CMDR.bit.RM=1;  
59
  
60
  /* Transmission*/
61
  for(i=0;i<length;i++)
62
  {
63
    while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.bit.ARDY));  //wait for xdry flag before transmit data or ardy if NACK appears
64
    if (I2caRegs.I2CSTR.bit.NACK==1)        //if NACK appears -> SCL=low, STP=0
65
    {
66
      I2caRegs.I2CMDR.all=0;          //reset I2C -> SCL not held low
67
    }
68
    I2caRegs.I2CDXR = data;
69
  }
70
}
71
72
Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length)
73
{
74
  Uint16 i;
75
  while (( I2caRegs.I2CSTR.bit.BB==1 ));    //bus busy?
76
   if (I2caRegs.I2CSTR.bit.BB == 1)
77
   {
78
      return I2C_BUS_BUSY_ERROR;
79
   }
80
  I2caRegs.I2CMDR.all = 0;      //disable I2C during config
81
  I2caRegs.I2CCNT = length;      //number of bytes to be send
82
  I2caRegs.I2CSAR = slvaddr;      //setup receiver addr
83
//  Mode settings
84
  I2caRegs.I2CMDR.bit.IRS=1;      //I2C module enable              
85
  I2caRegs.I2CMDR.bit.STT=1;      //If master -> start condition generated
86
  I2caRegs.I2CMDR.bit.STP=1;      //If master -> stop condition generated if data counter = 0
87
  I2caRegs.I2CMDR.bit.MST=1;      //Master mode
88
  I2caRegs.I2CMDR.bit.FREE=1;       //I2C module runs free
89
  I2caRegs.I2CMDR.bit.NACKMOD=1;
90
91
  /* Reception */
92
  for(i=0;i<length;i++)
93
  {
94
    while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.bit.ARDY));  //wait for xdry flag before transmit data or ardy if NACK appears
95
    if (I2caRegs.I2CSTR.bit.NACK==1)        //if NACK appears -> SCL=low, STP=0
96
    {
97
      I2caRegs.I2CMDR.all=0;          //reset I2C -> SCL not held low
98
    }
99
    while(I2caRegs.I2CSTR.bit.RRDY==1);
100
    data[i] = I2caRegs.I2CDRR ;
101
  }
102
}
103
104
//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
1
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. Obwohl ich dachte dass ich das mit setzen von 
STP eingestellt hab.

Ein Versuch eine I2C-Minimalversion für diese Sache zu schreiben sah so 
aus:
1
//I2C test 
2
3
4
#include "DSP280x_Device.h"     // DSP280x Headerfile Include File
5
#include "DSP280x_Examples.h"   // DSP280x Examples Include File
6
7
// Prototype statements for functions found within this file.
8
void   I2CA_Init(void);
9
10
Uint16 Values[6],i;
11
12
13
void main(void)
14
{
15
   InitSysCtrl();      // Step 1. Initialize System Control:
16
   InitI2CGpio();      // Step 2. Initalize GPIO only for I2C functionality
17
   I2CA_Init();        // Step 4. Initialize all the Device Peripherals:
18
19
20
   for(;;)          // Application loop
21
   {
22
             //---> Write instruction <--- //
23
      I2caRegs.I2CMDR.bit.STT = 1;
24
      I2caRegs.I2CSAR = 0x70;        //Write addr
25
      I2caRegs.I2CCNT = 3;        //3bytes=2bytes addr + 1 byte instr
26
      I2caRegs.I2CDXR = 0x02;        //instr
27
      I2caRegs.I2CMDR.bit.STP = 1; 
28
//      I2caRegs.I2CMDR.all = 0x2620;    //Send data to setup EEPROM address
29
30
      
31
      //---> Read values <--- //
32
      I2caRegs.I2CMDR.bit.STT = 1;
33
      I2caRegs.I2CSAR = 0x71;        //Read addr
34
      I2caRegs.I2CCNT = 1;        //6bytes=2bytes per coordinate
35
      Values[0] = I2caRegs.I2CDRR;
36
      /*for(i=0;i<6;i++)
37
      {
38
        Values[i] = I2caRegs.I2CDRR;
39
      }*/
40
      I2caRegs.I2CMDR.all = 0x2C20;      //Send restart as master receiver
41
       I2caRegs.I2CMDR.bit.STP = 1;          
42
   }   // end of for(;;)
43
}   // end of main
44
45
46
void I2CA_Init(void)
47
{
48
//   I2caRegs.I2CSAR = 0x38;      // Slave address - EEPROM control code
49
   I2caRegs.I2CPSC.all = 6;      // Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
50
   I2caRegs.I2CCLKL = 4200;      // NOTE: must be non zero
51
   I2caRegs.I2CCLKH = 4200;      // NOTE: must be non zero
52
   I2caRegs.I2CIER.all = 0x24;    // Enable SCD & ARDY interrupts
53
   I2caRegs.I2CMDR.all = 0x0020;  // Take I2C out of reset, Stop I2C when suspended
54
   I2caRegs.I2CFFTX.all = 0x6000;  // Enable FIFO mode and TXFIFO
55
   I2caRegs.I2CFFRX.all = 0x2040;  // Enable RXFIFO, clear RXFFINT,
56
   return;
57
}
58
59
//EOF
Führte aber leider auch nicht zum Ergebnis.

Falls jemand hier Erfahrungen mit TI DSPs/I2C oder Vorschläge jeglicher 
Art zu meinen beiden Code-Versuchen hat wäre ich sehr dankbar.

Grüße
Stephan

von Stephan (Gast)


Lesenswert?

habs jetzt hinbekommen und falls mal jemand den BMA020 mit TI C2000 DSPs 
nutzen will poste ich mal meinen, durchaus verbesserungswürdigen, Code, 
welcher im Roboternetz gepostete Codeschnipsel enthält.
1
//I2C test 
2
3
#include "DSP280x_Device.h"     // DSP280x Headerfile Include File
4
#include "DSP280x_Examples.h"   // DSP280x Examples Include File
5
6
// Prototype statements for functions found within this file.
7
void   I2CA_Init(void);
8
9
int Values[6]={0,0,0,0,0,0};
10
Uint16 instr=0x02;
11
int i,dx=0,dy=0,dz=0;
12
double D2G,gx=0,gy=0,gz=0;
13
14
void main(void)
15
{
16
   InitSysCtrl();      // Step 1. Initialize System Control:
17
   InitI2CGpio();      // Step 2. Initalize GPIO only for I2C functionality
18
   I2CA_Init();        // Step 4. Initialize all the Device Peripherals
19
   
20
   D2G=0.00390625;      // 4g/1024
21
   
22
   for(;;)          // Application loop
23
     {  
24
       I2caRegs.I2CSAR = 0x38;             //Set slave address
25
       I2caRegs.I2CCNT = 1;             //Set count to 5 characters plus 2 address bytes
26
       I2caRegs.I2CDXR = 0x02;            //Send eeprom high address            
27
       I2caRegs.I2CMDR.bit.TRX = 1;         //Set to Transmit mode
28
       I2caRegs.I2CMDR.bit.MST = 1;         //Set to Master mode
29
       I2caRegs.I2CMDR.bit.FREE = 1;        //Run in FREE mode
30
       I2caRegs.I2CMDR.bit.STP = 1;         //Stop when internal counter becomes 0
31
       I2caRegs.I2CMDR.bit.STT = 1;         //Send the start bit, transmission will follow
32
        
33
    
34
       while(I2caRegs.I2CSTR.bit.XRDY == 0){};     //Do nothing till data is shifted out
35
       I2caRegs.I2CCNT = 6;              //read 6 bytes from eeprom
36
       I2caRegs.I2CMDR.bit.TRX = 0;         //Set to Recieve mode
37
       I2caRegs.I2CMDR.bit.MST = 1;         //Set to Master mode
38
       I2caRegs.I2CMDR.bit.FREE = 1;        //Run in FREE mode
39
       I2caRegs.I2CMDR.bit.STP = 1;         //Stop when internal counter becomes 0
40
       I2caRegs.I2CMDR.bit.STT = 1;         //Repeated start, Reception will follow
41
       for(i = 0; i < 6; i++)
42
         {
43
           while(I2caRegs.I2CSTR.bit.RRDY == 0){};   //I2CDRR not ready to read?
44
           Values[i] = I2caRegs.I2CDRR;
45
         }
46
       DELAY_US(100);                //wait for new data provided
47
       dx=Values[0];                //dataadaptation by malthy & Sternthaler
48
       dx=(dx|((Values[1]<<8))>>6);
49
       gx=dx*D2G;
50
       dy=Values[2];
51
       dy=(dx|((Values[3]<<8))>>6);
52
       gy=dy*D2G;
53
    dz=Values[4];
54
       dz=(dx|((Values[5]<<8))>>6);
55
       gz=dz*D2G;
56
                         
57
   }   // end of for(;;)
58
}   // end of main
59
60
61
void I2CA_Init(void)
62
{
63
   I2caRegs.I2CSAR = 0x38;      // Slave address - EEPROM control code
64
   I2caRegs.I2CPSC.all = 6;      // Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
65
   I2caRegs.I2CCLKL = 42;      // NOTE: must be non zero
66
   I2caRegs.I2CCLKH = 21;      // NOTE: must be non zero
67
   I2caRegs.I2CIER.all = 0x3E;    // Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
68
   I2caRegs.I2CMDR.bit.IRS = 1;    // Take I2C out of reset, Stop I2C when suspended
69
   I2caRegs.I2CFFTX.all = 0x0000;  // Enable FIFO mode and TXFIFO
70
   I2caRegs.I2CFFRX.all = 0x0000;  // Enable RXFIFO, clear RXFFINT,
71
   return;
72
}
73
74
//EOF

An der Stelle nochmals danke an die "Code-Sponsoren".

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.