Forum: Digitale Signalverarbeitung / DSP / Machine Learning TMS320F2806 I2C Frage


von Dennis (Gast)


Lesenswert?

Hallo, ich versuche Kommunikation über I2C herzustellen. Benutze den 
erwähnten uC und MCP4017 als Slave. Der MCP4017 ist ein Potentiometer 
und hat eine feste Adresse von 0101111. Zum testen wollte ich erstmal 
einfach ein "Read" Befehl and den Chip senden und habe ein paar 
Breakpoints in meine Interrupt Funktion eingefügt um zu sehen ob diese 
überhaupt aufgerufen wird, dann wüsste ich zumindest, dass mein 
Request/Sendebefehl funktionieren tut. Hier ein paar Zeilen Code zur 
Initialisierung,
1
// I2C initialization
2
void I2CA_Init(void)
3
{
4
   // Initialize I2C
5
   //0101111(1) last 1 represents part of slave address but also a Read //command    
6
   I2caRegs.I2CSAR = 0x005F;    // Slave address
7
  
8
   I2caRegs.I2CPSC.all = 9;    // Prescaler - need 7-12 Mhz on module clk
9
  
10
   I2caRegs.I2CCLKL = 10;      // NOTE: must be non zero
11
   I2caRegs.I2CCLKH = 5;      // NOTE: must be non zero
12
   I2caRegs.I2CIER.all = 0x24;    // Enable SCD & ARDY interrupts
13
14
   I2caRegs.I2CMDR.all = 0x0020;  // Take I2C out of reset
15
                     // Stop I2C when suspended
16
17
   I2caRegs.I2CFFTX.all = 0x6000;  // Enable FIFO mode and TXFIFO
18
   I2caRegs.I2CFFRX.all = 0x2040;  // Enable RXFIFO, clear RXFFINT,
19
20
   return;
21
}
22
23
24
25
// Initialization of Input/Output ports
26
void init_gpio(void)
27
{
28
29
// GPIO-32 - PIN FUNCTION = I2C SDA
30
  GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;// Enable pull-up for GPIO32 (SDAA)
31
  GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;  // Asynch input GPIO32 (SDAA)
32
   GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;//0;  // 0=GPIO,  1=I2C-SDA,  2=SYNCI,  3=ADCSOCA
33
   //GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;    // 1=OUTput,  0=INput 
34
35
// GPIO-33 - PIN FUNCTION = I2C SCL
36
GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;     // Enable pull-up for GPIO33 (SCLA)
37
 GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;  // Asynch input GPIO33 (SCLA)
38
   GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;//0;  // 0=GPIO,  1=I2C-SCL,  2=SYNCO,  3=ADCSOCB
39
   //GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1;    // 1=OUTput,  0=INput 
40
   
41
}
42
43
44
//deactivate ADC intrrupt for test, activate I2C interrupt  
45
   I2c_interrupt_init()
46
{
47
  // Disable CPU interrupts
48
         DINT;
49
   
50
    // Disable CPU interrupts and clear all CPU interrupt //flags:
51
       IER = 0x0000;
52
       IFR = 0x0000;
53
    
54
    // Initialize the PIE vector table with pointers to the //shell Interrupt
55
    // Service Routines (ISR).
56
    // This will populate the entire table, even if the //interrupt
57
    // is not used in this example.  This is useful for debug //purposes.
58
    // The shell ISR routines are found in //DSP280x_DefaultIsr.c.
59
    // This function is found in DSP280x_PieVect.c.
60
    //   InitPieVectTable();
61
    
62
    
63
    // Enable the PIE Vector Table
64
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;  
65
    
66
    // Interrupts that are used in this example are re-mapped //to
67
    // ISR functions found within this file.
68
       EALLOW;  // This is needed to write to EALLOW //protected registers
69
       PieVectTable.I2CINT1A = &i2c_int1a_isr;
70
       EDIS;   // This is needed to disable write to EALLOW //protected registers
71
  
72
    
73
    // Enable I2C interrupt 1 in the PIE: Group 8 interrupt 1
74
       PieCtrlRegs.PIEIER8.bit.INTx1 = 1;
75
    
76
    // Enable CPU INT8 which is connected to PIE group 8
77
       IER |= M_INT8;
78
       EINT;
79
}
80
81
82
// Endlosschleife
83
for(;;)
84
{
85
  if(i2c_sent == 0)
86
       I2C_communication();
87
}
88
89
void I2C_communication()
90
{
91
92
  i2c_sent = 1;
93
    // Send slave address with 1 as last bit for Read command
94
    // 0101111(1) == 0x5F
95
    I2caRegs.I2CSAR = I2C_READ_SLAVE_ADDRESS;
96
}
97
98
interrupt void i2c_int1a_isr(void)     // I2C-A
99
{
100
   Uint16 IntSource;//, i;
101
102
   // Read interrupt source
103
   IntSource = I2caRegs.I2CISRC.all;
104
105
   // Interrupt source = stop condition detected
106
   if(IntSource == I2C_SCD_ISRC)
107
   {
108
      // If completed message was writing data, reset msg to inactive state
109
      if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_WRITE_BUSY)
110
      {
111
         CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;
112
      }
113
   }
114
else if(IntSource == I2C_ARDY_ISRC)
115
   {
116
       // NACK a no-acknowledge bit was sent during the //acknowledge 
117
       // cycle on the I2C-bus.
118
      if(I2caRegs.I2CSTR.bit.NACK == 1)
119
      {
120
        // STP has been set by the device to generate a STOP condition 
121
        // when the internal data counter of the I2C module counts down to //0
122
         I2caRegs.I2CMDR.bit.STP = 1;
123
         // (1) NACK bit received. The hardware detects that a //no-acknowledge 
124
         // (NACK) bit has been received. Note: While the I2C module //performs 
125
         // a general call transfer, NACK is 1, even if one or more slaves
126
     // send acknowledgment.
127
         I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
128
      }
129
      else if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
130
      {
131
         CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_RESTART;
132
      }
133
   }  // end of register access ready
134
135
   else
136
   {
137
      // Generate some error due to invalid interrupt source
138
      asm("   ESTOP0");
139
   }
140
141
  i2c_sent = 0;
142
  
143
   // Enable future I2C (PIE Group 8) interrupts
144
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
145
}

Danke

von Paulchen Panther (Gast)


Lesenswert?

Hi!

Ich sehe keine Frage....

auf jeden Fall würde ich nach dem senden in der Endlosschleife for(;;) 
eine Pause von ein paar ms machen. (Länger als ein Byte). Wie sehen die 
Signale auf SCL und SDA aus?

von Paulchen Panther (Gast)


Lesenswert?

Noch ein Tipp:

die CPU Familie heißt C2000 => eine Suche nach "ti c2000 i2c" kann auch 
ein paar funktionierende Codebeispiele zeigen, die du dann anpassen 
kannst.

von Paulchen Panther (Gast)


Lesenswert?

Und ich würde es erst mal ohne Interrupts programmieren.

von Dennis M. (Firma: Buckeljunge) (dennism)


Lesenswert?

Hallo, ich habe jetzt versucht den Code zu vereinfachen um das ganze 
noch mal zu testen. Anstatt Interrupts einzubauen versuche ich den 
RXFIFO zu überprüfen um zu sehen ob Daten empfangen worden sind. Die 
Sendefunktion wird ausgeführt, kriege aber keine Rückmeldung von meinem 
Chip. Habe ich eventuell was übersehen???

1
//wird als erstes aufgerufen
2
3
void I2CA_Init(void)
4
{
5
   // Initialize I2C
6
   //0101111(1) = 0x5F
7
   //0101111 = 0x2F
8
   I2caRegs.I2CSAR = 0x005F;//0x0050;    // Slave address - EEPROM control code
9
10
   #if (CPU_FRQ_100MHZ)
11
     I2caRegs.I2CPSC.all = 9;    // Prescaler - need 7-12 Mhz on module clk
12
   #endif
13
   #if (CPU_FRQ_60MHZ)
14
     I2caRegs.I2CPSC.all = 6;    // Prescaler - need 7-12 Mhz on module clk
15
   #endif
16
   I2caRegs.I2CCLKL = 10;      // NOTE: must be non zero
17
   I2caRegs.I2CCLKH = 5;      // NOTE: must be non zero
18
   //I2caRegs.I2CIER.all = 0x24;    // Enable SCD & ARDY interrupts
19
20
   I2caRegs.I2CMDR.all = 0x0020;  // Take I2C out of reset
21
                     // Stop I2C when suspended
22
23
   I2caRegs.I2CFFTX.all = 0x6000;  // Enable FIFO mode and TXFIFO
24
   I2caRegs.I2CFFRX.all = 0x2040;  // Enable RXFIFO, clear RXFFINT,
25
26
   return;
27
}
28
29
//******************************************************
30
//Hier sende ich meine Anfrage
31
unsigned int I2CA_ReadData_2(void)
32
{
33
  if (I2caRegs.I2CMDR.bit.STP == 1)
34
     {
35
        return 1;
36
     }
37
   
38
   // Slave address 0101111 plus 1 for read -> 0101111(1) = 0x5F as address
39
   I2caRegs.I2CSAR = i2c_slave_address;
40
   
41
     if (I2caRegs.I2CSTR.bit.BB == 1)
42
     {
43
       return 2;
44
     }
45
46
    I2caRegs.I2CCNT = 0;
47
    
48
    I2caRegs.I2CMDR.all = 0x2620;      // Send data to setup EEPROM address
49
   
50
    var = 2;
51
   
52
    return 3;
53
    
54
}
55
56
57
//*******************************************************
58
// Endless loop
59
 for(;;)
60
   {
61
     
62
                // Check if data in rxbuffer
63
       if(I2caRegs.I2CFFRX.bit.RXFFST)
64
       {
65
         checkRxfifo = I2caRegs.I2CDRR;
66
         checkRxfifo_2 = checkRxfifo;
67
       }
68
       
69
       
70
       if(var == 1) 
71
       {
72
         return_readData = I2CA_ReadData_2();
73
         return_readData = return_readData;
74
       }
75
   }

Danke
Gruß

von Dennis M. (Firma: Buckeljunge) (dennism)


Lesenswert?

Ich glaube jetzt funzt es. Ich hatte das W/R Bit ans Ende meiner Salve 
Adresse drangehängt. R/W wird aber im I2CMDR festgelegt.

Gruß
Dennis

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.