STM32F051 I2C slave problem

Guest #3774188
Rate this post
• ▲ useful
▼ not useful
Hi,

I have in a STM32F051k project a problem with the I2C as Slave.

I send from an AVR:
Start/address Wr/command/repStart/address RD/ ... read information /
Stop)
The read information is command/count/data.

Exact once everything is ok but then I come
Seldom times to the point for sending the count, but never again to 
sending the data.

Most comments are in German, sorry.
1
#define OUT_STATE_NC       0
2
#define OUT_STATE_CMD      1
3
#define OUT_STATE_LENGTH   2
4
#define OUT_STATE_DATA     3
5

6

7
unsigned char Info[128]; 
8
unsigned char State[64]; 
9

10
__IO unsigned char InputCounter;
11
__IO unsigned char OutputCounter;
12
__IO unsigned char Output_State;
13
__IO unsigned char Data_Out_Max;
14

15
__IO unsigned char data_in[MAXBYTES+1]; 
16
unsigned char *pData_Out;   /* Pointer auf die Ausgabe Daten */
17

18
unsigned char Data_Cmd;
19

20
TBOOL bRecStart;
21

22
volatile TBOOL new_data; /* 1 = neue daten */
23

24
__IO uint16_t IIC_Direction;
25

26

27
void I2C1_IRQHandler(void)
28
{
29
   if (I2C_GetITStatus(I2C1,I2C_IT_ADDR)) //  meine Adresse erkannt?
30
   {
31
      I2C_ClearITPendingBit (I2C1,I2C_IT_ADDR);
32

33
      // Start
34
      IIC_Direction = I2C_GetTransferDirection(I2C1);
35
      if (IIC_Direction == I2C_Direction_Transmitter) // IIC Write ?   AVR -> ARM
36
      {
37
         InputCounter = 0;
38
         OutputCounter = 0;
39
         Data_Out_Max = 0;
40
         Output_State = OUT_STATE_NC;
41
         bRecStart = TRUE; /* setze flag; System ist am empfangen */
42
      }
43
      else // IIC Read ARM -> AVR
44
      {
45
         if (InputCounter == 1) /* nur die Register Adresse vorher empfangen?*/
46
         {
47
            Output_State = OUT_STATE_CMD;
48
            Data_Cmd = data_in[0];
49
            switch (data_in[0])
50
            {
51
            case B_GET_INFO:
52
               pData_Out = (unsigned char *)&Info;
53
               Data_Out_Max = sizeof (Info);
54
               break;
55
            case B_GET_STATUS:
56
               pData_Out = (unsigned char *)&State;
57
               Data_Out_Max = sizeof (State);
58
               break;
59
            default :
60
               Data_Out_Max = 0;
61
               break;
62
            }
63
         }
64
         else
65
         {
66
            Output_State = OUT_STATE_NC;
67
         }
68
         OutputCounter = 0;
69
         InputCounter = 0;
70
      }
71
   }
72
   else if (I2C_GetITStatus(I2C1,I2C_IT_STOPF)) // Stopp erkannt?
73
   {
74
      I2C_ClearITPendingBit (I2C1,I2C_IT_STOPF);
75

76
      // Stop
77
      Data_Out_Max = 0;
78
      OutputCounter = 0;
79
      Output_State = OUT_STATE_NC;
80

81
      if (bRecStart != FALSE)
82
      {
83
         if (InputCounter == MAXBYTES) /*   alle daten empfangen ?*/
84
         {
85
            new_data = TRUE;
86
         }
87
      } /* else ->> komme aus nicht def. zustand */
88

89
      bRecStart = FALSE; /* loesche flag, Daten Empfang laeuft */
90
   }
91
   else  if (I2C_GetITStatus(I2C1,I2C_IT_RXNE)) //  was empfangen?
92
   {
93
      uint8_t In_Datum;
94

95
      In_Datum = I2C_ReceiveData(I2C1);
96

97
      if (InputCounter >= MAXBYTES) /* zu viele Daten empfangen ? */
98
      {
99
         bRecStart = FALSE; /* loesche flag, Daten Empfang laeuft */
100
      }
101
      else /* Kann noch Daten empfangen ! */
102
      {
103
         if (bRecStart == TRUE) /* laeuft Daten Empfang ? */
104
         {
105
            data_in[InputCounter] = In_Datum; // das sind die Daten -> also speichern
106
            InputCounter++;
107
         }
108
      }
109
      Data_Out_Max = 0;
110
      Output_State = OUT_STATE_NC;
111

112
      //I2C_ClearITPendingBit (I2C1,I2C_IT_RXNE); // macht das auslesen schon
113
   }   
114
   else   if (I2C_GetITStatus(I2C1,I2C_IT_TXIS)) //  gesendet ?
115
   {
116
      I2C_ClearITPendingBit (I2C1,I2C_IT_TXIS);
117

118
      switch(Output_State)
119
      {
120
      case OUT_STATE_CMD:
121
         I2C_SendData(I2C1, Data_Cmd);    // 1. Byte ist der Befehl zu dem die Daten passen
122
         Output_State = OUT_STATE_LENGTH;
123
         break;
124
      case OUT_STATE_LENGTH:
125
         I2C_SendData(I2C1, Data_Out_Max); // 2. Byte ist die Laenge
126
         Output_State = OUT_STATE_DATA;
127
         break;
128
      case OUT_STATE_DATA:
129
         if (OutputCounter < Data_Out_Max)  // Kann ich noch Daten senden?
130
         {
131
            I2C_SendData(I2C1, (*pData_Out));
132
            pData_Out++;
133
            OutputCounter++;
134

135
            if (OutputCounter >= Data_Out_Max)  // Kann ich noch Daten senden?
136
            {
137
                Output_State = OUT_STATE_NC;
138
            }
139
         }
140
         else
141
         {
142
            Output_State = OUT_STATE_NC;
143
            I2C_SendData(I2C1, 0); // sende NULL -> es wird zu viel abgefragt!
144
         }
145
         break;
146
      case OUT_STATE_NC:
147
      default:
148
          I2C_SendData(I2C1, 0); // sende NULL -> es wird mist abgefragt!
149
         break;
150
      }
151
   }
152
    else  if (I2C_GetITStatus(I2C1,I2C_IT_NACKF)) //  erkannt?
153
   {
154
      I2C_ClearITPendingBit (I2C1,I2C_IT_NACKF);
155
   }
156
   else   if (  (I2C_GetITStatus(I2C1,I2C_IT_BERR)) //  Fehler erkannt?
157
      || (I2C_GetITStatus(I2C1,I2C_IT_ARLO)) //  Fehler erkannt?
158
      )
159
   {
160
      // Sollte nicht passieren
161
      InputCounter = 0;
162
      OutputCounter = 0;
163
      Data_Out_Max = 0;
164

165
      I2C_ClearITPendingBit (I2C1,I2C_IT_BERR);
166
      I2C_ClearITPendingBit (I2C1,I2C_IT_ARLO);
167
   }
168
}
169

170

171

172
void Twi_Init(void)
173
{
174
   I2C_InitTypeDef  I2C_InitStructure;
175
   NVIC_InitTypeDef NVIC_InitStructure;
176
   GPIO_InitTypeDef  GPIO_InitStructure;
177

178
   InputCounter = 0x00;
179
   Data_Cmd = B_GET_NC;
180
   bRecStart = FALSE; /* loesche flag, daten empfang laeuft */
181

182
   // Ausgabe blockieren
183
   Data_Out_Max = 0;
184
   OutputCounter = 0;
185
   Output_State = OUT_STATE_NC;
186

187
   I2C_DeInit(I2C1);
188
   
189
  /*!< I2C Periph clock enable */
190
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
191

192
   /*!<  GPIO clock enable */
193
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
194

195
   RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
196

197
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1);
198
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1);
199

200
     /* Configure I2C pins:  SDA & SCL  ----------------------------*/
201
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
202
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
203
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
204
   GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
205
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
206
   GPIO_Init(GPIOB, &GPIO_InitStructure);
207

208
   /*!< I2C Init */
209
   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
210
   I2C_InitStructure.I2C_Timing = 100000;
211
   I2C_InitStructure.I2C_DigitalFilter = 0;
212
   I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
213
   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
214
   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
215
   I2C_InitStructure.I2C_OwnAddress1 = MYADDR;
216
   I2C_Init(I2C1, &I2C_InitStructure);
217

218
   /* Enable I2C event interrupt */
219
   I2C_ITConfig(I2C1, (I2C_IT_ERRI | I2C_IT_STOPI | I2C_IT_ADDRI | I2C_IT_RXI  | I2C_IT_TXI), ENABLE); // I2C_IT_NACKI 
220

221
  /* Configure the I2C event priority */
222
   NVIC_InitStructure.NVIC_IRQChannel = I2C1_IRQn;
223
   NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
224
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
225
   NVIC_Init(&NVIC_InitStructure);
226

227
  I2C_Cmd(I2C1, ENABLE);/* I2C ENABLE */
228
}

Regards,
Klaus

Reply

Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.

Formatting
  • [c]C-Code[/c]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.