Autor Tema: DMA con I2C en STM32F103C8  (Leído 240 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado carpoolo

  • PIC10
  • *
  • Mensajes: 14
DMA con I2C en STM32F103C8
« en: 17 de Diciembre de 2019, 12:41:21 »
Buenas! abro este hilo, porque tengo una duda con respecto al DMA, especificamente con el envio via I2C por el DMA, tengo un proyecto en donde quiero escribir a una memoria EEPROM Externa (24FC512 via I2C) usando en DMA, pero la duda principal es: como hago o donde coloco la direccion de la memoria? la cual segun datasheet tengo que colocar 0x50, pero no logro escribir en ella  :oops:, porfavor me echan una mano? Estoy usando MikroC Pro for ARM y sin librerias, quiero primero entenderlo por registros antes de inventar o probar una libreria. Ademas lo estoy haciendo por lenguaje C.

Desconectado carpoolo

  • PIC10
  • *
  • Mensajes: 14
Re:DMA con I2C en STM32F103C8
« Respuesta #1 en: 17 de Diciembre de 2019, 12:52:26 »
Estoy usando una libreria a manera de ejemplo (con la que he trabajado y me ha servido), para comprobar las escrituras.. dejo el codigo del main y de la funcion de la libreria que estoy utilizando.

main:

Código: C
  1. #include "eeprom_unit.h"
  2. unsigned char temp[4];
  3. unsigned char count,b;
  4. char letra = 'H';
  5. unsigned int EEAddres = 5000;
  6.  
  7. void TX1(char c){
  8.   UART1_Write(c);
  9. }
  10.  
  11. void TX_DMA1() iv IVT_INT_DMA1_Channel4 ics ICS_AUTO {
  12.   if(DMA1_ISR.TCIF4 == 1){
  13.     DMA1_IFCR.CGIF4 = 1;
  14.     DMA1_CCR4.EN = 0;
  15.   }
  16. }
  17.  
  18. void Eeprom_DMA_Wr() iv IVT_INT_DMA1_Channel6 ics ICS_AUTO {
  19.   if(DMA1_ISR.TCIF6 == 1){
  20.     DMA1_IFCR.CGIF6 = 1;
  21.     DMA1_CCR4.EN = 0;
  22.   }else if(DMA1_ISR.TEIF6 == 1){
  23.     PrintOut(TX1,"Hubo un Error Escribiendo\r\n");
  24.     DMA1_IFCR.CTEIF6 = 1;
  25.     DMA1_CCR6.EN = 0;
  26.   }
  27. }
  28.  
  29. void Config_Dma1_TX(){
  30.   DMA1_CPAR4 = 0x40013804;  //Direccion del Registro del Uart1
  31.  
  32.   DMA1_CMAR4 = &test;      //La data que se va a mandar
  33.  
  34.   DMA1_CNDTR4 = strlen(&test);         //La cantidad de Datos que va a mandar
  35.  
  36.   DMA1_CCR4.MEM2MEM = 0;    //Modo Memoria a Memoria Deshabilitado
  37.   DMA1_CCR4.MINC = 1;       //Modo Incremento de Memoria
  38.   DMA1_CCR4.CIRC = 1;       //Modo Circular Habilitado
  39.  
  40.   DMA1_CCR4.PL0 = 0;        //Nivel de
  41.   DMA1_CCR4.PL1 = 1;        //Prioridad
  42.  
  43.   DMA1_CCR4.PSIZE0 = 0;      //Tamaño en bit's que
  44.   DMA1_CCR4.PSIZE1 = 0;      // va a recibir el periferico
  45.  
  46.   DMA1_CCR4.MSIZE0 = 0;      //Tamaño en bit's que
  47.   DMA1_CCR4.MSIZE1 = 0;      // va manejar la memoria
  48.  
  49.   DMA1_CCR4.B4 = 1;         // Sentido de la Transmision de la Data (lee desde el Periferico (UART) )
  50.  
  51.   DMA1_CCR4.TCIE = 1;       //Interrupcion por Transferencia Completa
  52.  
  53.   DMA1_CCR4.EN = 1;        //Habilita el Chanel 4 del DMA1
  54. }
  55.  
  56. void Eeprom_DMA_Write(){
  57.  
  58.   DMA1_CPAR6 = 0X40005410;         //Va para el I2C1
  59.  
  60.   DMA1_CMAR6 = &temp;                        //data a enviar
  61.  
  62.   DMA1_CNDTR6 = strlen(&temp);
  63.  
  64.   DMA1_CCR6.MEM2MEM = 0;
  65.  
  66.   DMA1_CCR6.MINC = 1;
  67.  
  68.   delay_ms(20);
  69.  
  70.   DMA1_CCR6.PINC = 0;
  71.  
  72.   DMA1_CCR6.CIRC = 0;
  73.  
  74.   DMA1_CCR4.PL0 = 0;
  75.   DMA1_CCR4.PL1 = 1;
  76.  
  77.   DMA1_CCR6.MSIZE0 = 0;
  78.   DMA1_CCR6.MSIZE1 = 0;
  79.  
  80.   DMA1_CCR6.PSIZE0 = 0;
  81.   DMA1_CCR6.PSIZE1 = 0;
  82.  
  83.   DMA1_CCR6.B4 = 1;
  84.  
  85.   DMA1_CCR6.TCIE = 1;
  86.  
  87.   DMA1_CCR6.TEIE = 1;
  88.  
  89.   DMA1_CCR6.EN = 1;
  90.  
  91. }
  92.  
  93.  
  94. void main(){
  95.   UART1_Init_Advanced(9600, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, &_GPIO_MODULE_USART1_PA9_10);  // Serial UART
  96.   USART1_CR3.DMAT = 1;
  97.   USART1_CR1bits.RXNEIE  = 0;
  98.   delay_ms(100);
  99.   temp[0] = 0xA0;
  100.   temp[2] = lo(EEAddres);
  101.   temp[1] = hi(EEAddres);
  102.   temp[3] = 'I';
  103.   I2C1_Init_Advanced(400000,&_GPIO_MODULE_I2C1_PB67);
  104.   I2C1_CR2.DMAEN = 1;
  105.   I2C1_CR2.LAST = 1;
  106.   RCC_AHBENR.DMA1EN = 1;
  107.   delay_ms(10);
  108.   Eeprom_DMA_Write();
  109.   delay_ms(50);
  110.   PrintOut(TX1,"Sale de la funcion Write\r\n");
  111.   EnableInterrupts();
  112.   NVIC_IntEnable(IVT_INT_DMA1_Channel4);
  113.   b = EEPROM_RdSingle(EEAddres);  //<---- Funcion de la libreia que uso para checar que si escribiera en la EEPROM
  114.   NVIC_IntEnable(IVT_INT_DMA1_Channel6);
  115.   PrintOut(TX1,"Contenido de la direccion: %u y la letra:%c\r\n",EEAddres,b);
  116.   while(1){
  117.  
  118.   }
  119. }

y el codigo de la libreria que uso es:

Código: C
  1. #include <built_in.h>
  2.  
  3. //--------------- Performs 24fC512 Init             0x0000-0xFFFF    0-65536
  4. void EEPROM_Init() {
  5. //UART1_WRITE_TEXT("\r\nEEPROM...");
  6.   I2C1_Init_Advanced(400000,&_GPIO_MODULE_I2C1_PB67);      //Maximo 1mhz 400khz 100khz
  7.   delay_ms(20);
  8. //UART1_WRITE_TEXT("Activado\r\n");
  9. }
  10.  
  11.  
  12. //--------------- Writes data to 24C02 EEPROM - signle location
  13. void EEPROM_WrSingle(unsigned int wAddr, char wData) {
  14.   char data_[4];
  15.   data_[1] = lo(wAddr);
  16.   data_[0] = hi(wAddr);
  17.   data_[2] = wData; //wData;
  18.   I2C1_Start(); // issue I2C start signal
  19.   I2C1_Write(0x50,data_,3,END_MODE_STOP);
  20.   delay_ms(50);
  21. }//~
  22.  
  23. //--------------- Reads data from 24C02 EEPROM - single location (random)
  24. char EEPROM_RdSingle(unsigned int rAddr) {
  25.   char data_[4];
  26.   data_[1] = lo(rAddr);
  27.   data_[0] = hi(rAddr);
  28.   I2C1_Start();              // issue I2C start signal
  29.   I2C1_Write(0x50,data_,2,END_MODE_RESTART);
  30.   I2C1_Read(0x50,data_,1,END_MODE_STOP);
  31.   delay_ms(1);
  32.   return data_[0];
  33. }//~
  34.  


 

anything