Forum: Mikrocontroller und Digitale Elektronik STM32 I2C DMA with EMBOS events


von Hansi (Gast)


Lesenswert?

Hallo Zusammen

Ich habe einen I2C treiber der mittels DMA Bytes sended und empfängt. 
Das ganze ist mit interrupts gelöst, also einerseits diese Event 
Interrupts des I2C modules und den DMA Interrupts. Nun möchte ich aber 
dass der Task in der I2C routine nicht mittels eines whiles warten muss 
sondern sich schlafen legt und auf ein event wartet. Leider funktioniert 
dann das ganze nicht mehr und ich weiss nicht wo das Problem liegt. Ich 
schicke das Event aus der I2C_EVT ISR routine. Hoffe ihr könnt mir 
helfen.

1
RETCODE I2Cdrv_DMASendData(void* pBuffer, UINT8 NumByteToWrite, UINT8 addr)
2
{
3
4
  /* Check I2C Semaphore */
5
  OS_Use(&sema);
6
7
8
  /* Wait while the bus is busy */
9
  while(I2C_GetFlagStatus(i2cDev, I2C_FLAG_BUSY));
10
11
  I2C_AcknowledgeConfig(i2cDev, DISABLE);
12
13
  // Reconfigure DMA
14
  dmaCfg.DMA_BufferSize = NumByteToWrite;
15
  DMA_DeInit(TxChannel);
16
  DMA_Init(TxChannel, &dmaCfg);
17
  
18
  DMA_ITConfig(TxChannel, DMA_IT_TC, ENABLE);
19
  I2C_ITConfig(i2cDev, I2C_IT_EVT, ENABLE);
20
  I2C_DMACmd(i2cDev, ENABLE);
21
  // Start
22
  I2C_GenerateSTART(i2cDev, ENABLE);
23
24
  
25
  // Wait EOT iterrupt or I2C Error Status Flags Interrupt
26
  OS_EVENT_Wait(&event);
27
28
29
  /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
30
  while ((i2cDev->CR1&0x200) == 0x200);
31
32
  OS_Unuse(&sema);
33
34
  return NO_ERROR;
35
}
36
37
38
void I2Cdrv_DMA_TX_ISR()
39
{
40
  DMA_Cmd(TxChannel, DISABLE);
41
  DMA_ClearFlag(dmaTxFlag);
42
}
43
44
45
void I2Cdrv_EV1_ISR()
46
{
47
48
  switch (I2C_GetLastEvent(i2cDev))
49
  {
50
    case I2C_EVENT_MASTER_MODE_SELECT:                 /* EV5 */
51
52
      if( Send_Receive )
53
      {
54
        // Send slave Address for write
55
        I2C_Send7bitAddress(i2cDev, Addr, I2C_Direction_Transmitter);
56
      }
57
      else
58
      {
59
        // Send slave Address for read
60
        I2C_Send7bitAddress(i2cDev, Addr, I2C_Direction_Receiver);
61
      }
62
      break;
63
64
      /* Test on I2C1 EV6 and first EV8 and clear them */
65
    case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
66
67
      DMA_Cmd(TxChannel, ENABLE);
68
      break;
69
70
      // EV8
71
    case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
72
      break;
73
74
    case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
75
    // I2C STOP Condition
76
    i2cDev->CR1 |= 0x200;
77
    // Avoid additional BTF interrupt
78
    I2C_ITConfig(i2cDev, I2C_IT_EVT, DISABLE);
79
    // Signal that Transfer is finished
80
    OS_EVENT_Set(&event);
81
      break;
82
83
    case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
84
      // Start receiving Data over DMA
85
      DMA_Cmd(RxChannel, ENABLE);
86
      break;
87
88
    default:
89
      break;
90
  }
91
92
}

von Hansi (Gast)


Lesenswert?

Niemand der helfen kann? Werde noch wahnsinnig weil das nicht 
funktioniert....

von (prx) A. K. (prx)


Lesenswert?

Vielleicht weil dein EMBOS hier nicht allzu verbreitet ist?

Von anderen RTOS Kernels kenne ich allerdings die Eigenheit, dass man in 
ISRs nicht alle APIs verwenden darf, oder nur speziell dafür 
vorgesehene.

von Hansi (Gast)


Lesenswert?

Ja das könnte sein, aber das OS ist nicht entscheidend, klappt es bei 
jemandem mit anderem OS?

Das API sollte nicht das Problem sein, laut Manual ist es erlaubt diese 
Funktionen aus ISRs zu verwenden...

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.