STM32L152RB problem s interruptom na I2C

nesvacil@posys.cz nesvacil na posys.eu
Pondělí Září 16 08:53:02 CEST 2013


Zdravim,
dival jste se na nejake starsi priklady od ST ? Me tam zarazi spousta while cekacich casti, prave proto si rikam, zda to ma vyznam z hlediska casu CPU vubec delat pres hw i2c u ST32F1.. .
Navic nektere slave IO na sbernici se trosku rovnaji na CLK I2C tj. pokud by jste to udelal v nejake hlavni smycce misto delay-while, tak by to taky nemuselo fungovat nebo ne ?

Status I2C_Master_BufferWrite(I2C_TypeDef* I2Cx, uint8_t* pBuffer,  uint32_t NumByteToWrite, I2C_ProgrammingModel Mode, uint8_t SlaveAddress )

{

     __IO uint32_t temp = 0;
     __IO uint32_t Timeout = 0;

     /* Enable Error IT (used in all modes: DMA, Polling and Interrupts */
     I2Cx->CR2 |= I2C_IT_ERR;
     if (Mode == DMA)  /* I2Cx Master Transmission using DMA */
     {
         Timeout = 0xFFFF;
         /* Configure the DMA channel for I2Cx transmission */
         I2C_DMAConfig (I2Cx, pBuffer, NumByteToWrite, I2C_DIRECTION_TX);
         /* Enable the I2Cx DMA requests */
         I2Cx->CR2 |= CR2_DMAEN_Set;
         /* Send START condition */
         I2Cx->CR1 |= CR1_START_Set;
         /* Wait until SB flag is set: EV5 */
         while ((I2Cx->SR1&0x0001) != 0x0001)
         {
             if (Timeout-- == 0)
                 return Error;
         }
         Timeout = 0xFFFF;
         /* Send slave address */
         /* Reset the address bit0 for write */
         SlaveAddress &= OAR1_ADD0_Reset;
         Address = SlaveAddress;
         /* Send the slave address */
         I2Cx->DR = Address;
         /* Wait until ADDR is set: EV6 */
         while ((I2Cx->SR1&0x0002) != 0x0002)
         {
             if (Timeout-- == 0)
                 return Error;
         }

         /* Clear ADDR flag by reading SR2 register */
         temp = I2Cx->SR2;
         if (I2Cx == I2C1)
         {
             /* Wait until DMA end of transfer */
             while (!DMA_GetFlagStatus(DMA1_FLAG_TC6));
             /* Disable the DMA1 Channel 6 */
             DMA_Cmd(I2C1_DMA_CHANNEL_TX, DISABLE);
             /* Clear the DMA Transfer complete flag */
             DMA_ClearFlag(DMA1_FLAG_TC6);
         }
         else  /* I2Cx = I2C2 */
         {
             /* Wait until DMA end of transfer */
             while (!DMA_GetFlagStatus(DMA1_FLAG_TC4));
             /* Disable the DMA1 Channel 4 */
             DMA_Cmd(I2C2_DMA_CHANNEL_TX, DISABLE);
             /* Clear the DMA Transfer complete flag */
             DMA_ClearFlag(DMA1_FLAG_TC4);
         }

         /* EV8_2: Wait until BTF is set before programming the STOP */
         while ((I2Cx->SR1 & 0x00004) != 0x000004);
         /* Program the STOP */
         I2Cx->CR1 |= CR1_STOP_Set;
         /* Make sure that the STOP bit is cleared by Hardware */
         while ((I2Cx->CR1&0x200) == 0x200);

     }
     else if (Mode == Polling) /* I2Cx Master Transmission using Polling */
     {

         Timeout = 0xFFFF;
         /* Send START condition */
         I2Cx->CR1 |= CR1_START_Set;
         /* Wait until SB flag is set: EV5 */
         while ((I2Cx->SR1&0x0001) != 0x0001)
         {
             if (Timeout-- == 0)
                 return Error;
         }

         /* Send slave address */
         /* Reset the address bit0 for write*/
         SlaveAddress &= OAR1_ADD0_Reset;
         Address = SlaveAddress;
         /* Send the slave address */
         I2Cx->DR = Address;
         Timeout = 0xFFFF;
         /* Wait until ADDR is set: EV6 */
         while ((I2Cx->SR1 &0x0002) != 0x0002)
         {
             if (Timeout-- == 0)
                 return Error;
         }

         /* Clear ADDR flag by reading SR2 register */
         temp = I2Cx->SR2;
         /* Write the first data in DR register (EV8_1) */
         I2Cx->DR = *pBuffer;
         /* Increment */
         pBuffer++;
         /* Decrement the number of bytes to be written */
         NumByteToWrite--;
         /* While there is data to be written */
         while (NumByteToWrite--)
         {
             /* Poll on BTF to receive data because in polling mode we can not guarantee the
               EV8 software sequence is managed before the current byte transfer completes */
             while ((I2Cx->SR1 & 0x00004) != 0x000004);
             /* Send the current byte */
             I2Cx->DR = *pBuffer;
             /* Point to the next byte to be written */
             pBuffer++;
         }
         /* EV8_2: Wait until BTF is set before programming the STOP */
         while ((I2Cx->SR1 & 0x00004) != 0x000004);
         /* Send STOP condition */
         I2Cx->CR1 |= CR1_STOP_Set;
         /* Make sure that the STOP bit is cleared by Hardware */
         while ((I2Cx->CR1&0x200) == 0x200);

     }

     else /* I2Cx Master Transmission using Interrupt with highest priority in the application */

     {
         /* Enable EVT IT*/
         I2Cx->CR2 |= I2C_IT_EVT;
         /* Enable BUF IT */
         I2Cx->CR2 |= I2C_IT_BUF;
         /* Set the I2C direction to Transmission */
         I2CDirection = I2C_DIRECTION_TX;
         SlaveAddress &= OAR1_ADD0_Reset;
         Address = SlaveAddress;
         if (I2Cx == I2C1)    NumbOfBytes1 = NumByteToWrite;
         else NumbOfBytes2 = NumByteToWrite;
         /* Send START condition */
         I2Cx->CR1 |= CR1_START_Set;
         /* Wait until the START condition is generated on the bus: the START bit is cleared by hardware */
         while ((I2Cx->CR1&0x100) == 0x100);
         /* Wait until BUSY flag is reset: a STOP has been generated on the bus signaling the end
         of transmission */
         while ((I2Cx->SR2 &0x0002) == 0x0002);
     }

     return Success;

}

Jirka

Dne 16. 9. 2013 1:26, Stano napsal(a):
> DMA pouzivam pre prenos viac nez 1 byte, pre jeden byte pouzivam IRQ.
> V ST je kniznica CPAL, ta pouziva DMA aj IRQ. Dival som sa donej ale nemozem povedat ze ju ovladam do posledneho riadku, je totiz postavena na makrach a pisana takym stylom ze kym sa dostanete k informacii do akeho registra to vlastne zapisuje a co 
> zapisuje prejdete mnoho a mnoho definicii a definicii definicii...
> Povedal by som ze ked sa snaha o abstraktnost prezenie vedie to k maximalne necitatelnemu kodu, zial tato kniznica je toho prikladom.
>
> A odpoved na vasu otazku, ta periferia na F1/L1 o ktorej je tento thread je naozaj problematicka ale skusal som aj I2C na F0/F3 a to bola priam radost. Ta mi prisla naozaj user fiendly. Pokial sa nejedna len o 1..2 byte HW periferia urcite zmysel 
> ma. A na tej F0/F3 STM aj na ten jeden byte.
>
> nesvacil na posys.cz  wrote / napísal(a):
>> Zdravim,
>> v DMA rezimu prenasite vice jak jeden  byte ? Tak to je popsano v Err... .
>> Jinak pouzivame SW implementaci I2C prave z duvodu vsech moznych chyb I2C.
>>
>> Pokud vim, tak v knihovnach od ST jsou rutiny na DMA prenos, ty to zablokuji jen do doby vyslani startu na I2C ci prvniho byte... ? Dival jste se tam ?
>>
>> Docela by me taky zajimalo, zda nekdo provozuje produkcni I2C s hw implmenetaci ST. A zda to ma vyznam pro komunikaci jednoho ci dvou bytu v prenosu ... ?
>>
>> Jirka
>>
>>
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list



Další informace o konferenci Hw-list