Autor Tema: Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY  (Leído 336 veces)

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

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3138
Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« en: 16 de Febrero de 2017, 10:24:04 »
Mi primer proyecto con PIC32MZ.... todo en el sitio de Microhip apunta a que el camino a seguir es usar Harmony... pero el paradigma de máquinas de estado en el que se basa Harmony hace que la aplicación sea demasiado lenta.

¿Alternativas? Las PLIB no existen para PIC32MZ, así que no queda más remedio que programar "a pelo".

Encuentro este mini-curso (muy recomendable), con el que comienzo a dar los primeros pasos:
http://www.cnblogs.com/geekygeek/tag/PIC32MZ%20tutorial/

Ahora tengo que comunicar mi PIC32MZ con un esclavo I2C y antes de ponerme a reinventar la rueda, me pregunto si alguien podría proporcionarme algún ejemplo.

Gracias.

Desconectado manwenwe

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1705
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #1 en: 16 de Febrero de 2017, 11:40:40 »
Jelou,

prueba con estas funciones (el init es para 400khz, si no recuerdo mal, con un reloj de periféricos de 100Mhz; puedes cambiarlo fácilmente):

Código: [Seleccionar]
void I2C_Init (void){
       
    I2C2BRG = 0x70; //112.6 rounded to 112d
    I2C2CONbits.I2CEN = 1;
           
    return;
}

unsigned char EEPROM_Read_Byte (unsigned short address){
     
    I2C2CONbits.SEN = 1;
    while(I2C2CONbits.SEN);
    I2C2TRN = 0xA0; //Control Byte
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2TRN = (unsigned char) ((address>>8)&0x00FF); // address high
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2TRN = (unsigned char) (address&0x00FF); // address low
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2CONbits.RSEN = 1;
    while(I2C2CONbits.RSEN);
    I2C2TRN = 0xA1; //Control Byte
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2CONbits.RCEN = 1;
    while(I2C2CONbits.RCEN);
    I2C2CONbits.ACKDT = 1;
    I2C2CONbits.ACKEN = 1;
    while(I2C2CONbits.ACKEN);
    I2C2CONbits.PEN = 1;
    while(I2C2CONbits.PEN);
       
    return I2C2RCV;
 
}

void EEPROM_Sequential_Read (unsigned short address, unsigned short bytes,  unsigned char *buffer){
   
    unsigned int i;
   
    *buffer = EEPROM_Read_Byte (address);
   
    I2C2CONbits.SEN = 1;
    while(I2C2CONbits.SEN);
    I2C2TRN = 0xA1; //Control Byte
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
   
    for(i=1;i<bytes;i++){
       
        I2C2CONbits.RCEN = 1;
        while(I2C2CONbits.RCEN);
        I2C2CONbits.ACKDT = 0;
        I2C2CONbits.ACKEN = 1;
        while(I2C2CONbits.ACKEN);
        *(buffer+i) = I2C2RCV;
       
    }
   
    I2C2CONbits.RCEN = 1; //Dummy read to end transmission.
    while(I2C2CONbits.RCEN);
    I2C2CONbits.ACKDT = 1;
    I2C2CONbits.ACKEN = 1;
    while(I2C2CONbits.ACKEN);
    I2C2CONbits.PEN = 1;
    while(I2C2CONbits.PEN);
   
    return;
   
}

void EEPROM_Write_Byte (unsigned short address, unsigned char byte){
   
    I2C2CONbits.SEN = 1;
    while(I2C2CONbits.SEN);
    I2C2TRN = 0xA0; //Control Byte
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2TRN = (unsigned char) ((address>>8)&0x00FF); // address high
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2TRN = (unsigned char) (address&0x00FF); // address low
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2TRN = byte;
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2CONbits.PEN = 1;
    while(I2C2CONbits.PEN);
    APP_TMR_DelayMS(EEPROM_WRITE_DELAY);
       
    return;   
   
}

void EEPROM_Page_Write(unsigned short address, unsigned char *buffer){
   
    unsigned char i;
    unsigned char aux_buffer[EEPROM_PAGE_SIZE];
    bool writting_error = false;
   
    I2C2CONbits.SEN = 1;
    while(I2C2CONbits.SEN);
    I2C2TRN = 0xA0; //Control Byte
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2TRN = (unsigned char) ((address>>8)&0x00FF); // address high
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    I2C2TRN = (unsigned char) (address&0x00FF); // address low
    while(I2C2STATbits.TRSTAT);
    while(I2C2STATbits.ACKSTAT);
    for(i=0;i<EEPROM_PAGE_SIZE;i++){
        I2C2TRN = *(buffer+i);
        while(I2C2STATbits.TRSTAT);
        while(I2C2STATbits.ACKSTAT);           
    }
    I2C2CONbits.PEN = 1;
    while(I2C2CONbits.PEN);
    APP_TMR_DelayMS(EEPROM_WRITE_DELAY);
   
    EEPROM_Sequential_Read (address, EEPROM_PAGE_SIZE,  aux_buffer);
    for(i=0;i<EEPROM_PAGE_SIZE;i++)
        if((*(buffer+i)) != aux_buffer[i])
            writting_error = true;
    if(writting_error == true)
        for(i=0;i<EEPROM_PAGE_SIZE;i++)
            EEPROM_Write_Byte ((address+i), *(buffer+i));
                 
    return;   
   
}

Las hice porque tengo poca paciencia y cuando el driver de harmony o plib no van a la primera me voy a los registros jeje. Son para EEPROM pero si las modificas un poco te valen para cualquier otro dispositivo. Están probadas.

Saludos!





Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Conectado planeta9999

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2171
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #2 en: 16 de Febrero de 2017, 13:42:17 »
.

¿ No te has planteado irte a otra familia de micros ?.
Programar a pelo para un 32 bits, me parece una locura.

No llegué a probar nunca Harmony, porque ya había dejado los PIC, supuse que sería un buen generador de código. Yo ahora trabajo solo con STM32 y Kinetis, y aquí si que tienes un fantástico generador, CubeMx para STM32 y KDS para Kinetis, ambos basados en Eclipse, todo GRATUITO incluido el compilador de C/C++ basado en GCC. Tienes infinidad de librerías para todo, que se pueden añadir y configurar desde el generador, con bloques de código delimitados dedicados exclusivamente al código del usuario, de manera que en todo momento puedes reconfigurar cualquier cosa desde el generador, respetando y manteniendo tu código. Además los micros y las placas de evaluación son baratísimos, más aún si acudes a los chinos.
« Última modificación: 16 de Febrero de 2017, 13:45:12 por planeta9999 »

Desconectado manwenwe

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1705
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #3 en: 16 de Febrero de 2017, 16:19:34 »
Umm, he hecho alguna cosa con Kinetis pero en este proyecto se necesitaban librerías gráficas y las de Freescale (las gratuitas) son muy malas: ahí Microchip se salva. No lo hago todo con registros pero tampoco me molesta: aprendí hace 15 años ensamblador, hace 12 C para PICs... estoy acostumbrado a usar registros; puede parecer arcaico pero es la única forma que conozco de "tener todo lo que pasa controlado". Evidentemente no se me ocurre usar registros para USB, ethernet, etc. que son periféricos complejos pero I2C, ADC, RTC, TIMER, etc. es bastante rápido...

Saludos!
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3138
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #4 en: 17 de Febrero de 2017, 04:58:44 »
Gracias manwenwe, les echaré un vistazo este finde.

La verdad es que no estaba nada decidido por usar un PIC32MZ, porque son muy lentos en atender las interrupciones (interrupt latency), pero mi alternativa era un STM32F407 que, por desgracia, no tenía sufiente memoria SRAM (190kb versus 512kb).

Además, cuando estuve evaluando el STM32F407, el IDE más apropiado que encontré era uno francés (no recuerdo ahora el nombre), y tuve la impresión de que no estaba demasiado bien integrado con CubeMX (imagino que las cosas habrán cambiado en el año que ha pasado desde que hice estas pruebas).


Desconectado manwenwe

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1705
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #5 en: 17 de Febrero de 2017, 05:12:07 »
Me explicas lo de la latencia de las interrupciones? Tengo en mente un proyecto donde va a ser crítico y no sabía si usar un MZ o un Kinetis: el MZ se supone que  es un poquitín más rápido y con Kinetis tengo poca experiencia....
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Conectado planeta9999

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2171
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #6 en: 17 de Febrero de 2017, 06:13:02 »
Gracias manwenwe, les echaré un vistazo este finde.

La verdad es que no estaba nada decidido por usar un PIC32MZ, porque son muy lentos en atender las interrupciones (interrupt latency), pero mi alternativa era un STM32F407 que, por desgracia, no tenía sufiente memoria SRAM (190kb versus 512kb).

Pilla un F427 o una serie más alta y arreglado, hasta un F7 (Cortex M7) si fuera necesario. Tienes mucho para elegir, mira en la web de ST, tienes un selector de micros por familias y características.


Citar
Además, cuando estuve evaluando el STM32F407, el IDE más apropiado que encontré era uno francés (no recuerdo ahora el nombre), y tuve la impresión de que no estaba demasiado bien integrado con CubeMX (imagino que las cosas habrán cambiado en el año que ha pasado desde que hice estas pruebas).

Si, eso ha cambiado mucho, puedes usar Eclipse con el plugin AC6 y Cubemx integrado, es una auténtica maravilla. Hay montones de librerías que se integran en Cubemx, para configurar gráficamente y generar código automáticamente.

¿ Eres consciente de que el compilador XC32 para los PIC32 cuesta sobre los 1200 Euros, y que la demo no permite usar la optimización, relegando el compilador a prácticas muy básicas ?. Hablas de usar un micro con 512K de RAM, osea que vas a hacer desarrollos serios, y eso implica si o si tener que comprar el compilador XC32.

El compilador C/C++ para los ARM es completamente gratuito, sin limitaciones. Además hay unos cuantos fabricantes de micros ARM, puedes portar el código entre ellos con mucha facilidad.

« Última modificación: 17 de Febrero de 2017, 06:22:10 por planeta9999 »

Desconectado manwenwe

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1705
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #7 en: 17 de Febrero de 2017, 15:13:45 »
La verdad es que no estaba nada decidido por usar un PIC32MZ, porque son muy lentos en atender las interrupciones (interrupt latency), pero mi alternativa era un STM32F407 que, por desgracia, no tenía sufiente memoria SRAM (190kb versus 512kb).

Explicame lo de las interrupciones poooooorfaaaa :oops: jejeje
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3138
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #8 en: 17 de Febrero de 2017, 15:23:00 »
Básicamente es que el PIC32MZ, cuando se produce una interrupción, tiene que almacenar un montón de registros, y lo hace mendiante software, antes de ejecutar el código que hemos asignado a rutina de la interrupción, mientras que en los ARM son muchos menos registros y además se hace por hardware casi todo.
En otras palabras: se produce una interrupción, el pic32MZ invierte un montón de ciclos en conservar el contexto y, después, atiende la rutina.

Está mejor explicado aquí:
http://www.microchip.com/forums/m904370.aspx

Citar
With interrupt latency it's no contest. The PIC32 has twice as many registers as an ARM Cortex-M and saving all of them during an interrupt is both time consuming and a manual operation (the chip doesn't automatically save any of them on an interrupt). The Cortex-M parts not only have half as many registers, but the chip automatically saves a subset of them on an interrupt. The chip and the compiler cooperate to the extent that it's not necessary to do anything special when writing interrupt handlers -- they can be simple C functions, unlike on the PIC32 series where you need to use special wrappers using non-standard C constructs such as __attribute__((interrupt(IPL3SOFT), vector(_SPI2_TX_VECTOR))) in front of each interrupt handler to generate the code to save registers and to generate the return from interrupt instruction at the end of the function.

Desconectado manwenwe

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1705
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #9 en: 17 de Febrero de 2017, 15:35:20 »
Gracias :-),

¿pero eso es en los MX o los MZ?. Estoy mirando en la hoja de datos de los MZ y comentan esto:

(p115)

The Interrupt Controller module includes the following features:
•Up to 213 interrupt sources and vectors with dedicated programmable offsets, eliminating the need for redirection
•Single and multi-vector mode operations
•Five external interrupts with edge polarity control
•Interrupt proximity timer
•Seven user-selectable priority levels for each vector
•Four user-selectable subpriority levels within each priority
•Seven shadow register sets that can be used for any priority level, eliminating software context switch and reducing interrupt latency
•Software can generate any interrupt

¿Mienten?

Saludos!
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3138
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #10 en: 17 de Febrero de 2017, 15:37:51 »
Es para los MZ (y para los MX aún peor).
Por lo que he leído, los resultados incluso usando los shadows son pobres.
Por ejemplo: http://www.microchip.com/forums/m908770.aspx

Desconectado manwenwe

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1705
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #11 en: 17 de Febrero de 2017, 15:49:09 »
Ok gracias! La aplicación que tengo en mente tiene que ser muy rápida pero no tiene una gran cantidad de código: de hecho puedo meter casi todo código dentro de los "ISR handlers" sin tener que restaurar el contexto para gestionar lo que tengo que hacer. Pincharé el osciloscopio con una única interrupción de máxima prioridad y miraré el retraso desde una interrupción de GPIO hata cambiar el valor de otro GPIO dentro de la interrupción que es lo que a mi me preocupa.

Saludos!
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado manwenwe

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1705
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #12 en: 17 de Febrero de 2017, 16:12:51 »
Conocíais estos que son multicore?

http://www.xmos.com/download/private/XS1-L4A-64-TQ48-Datasheet%281.3%29.pdf

Tienen el mejor precio respecto a MIPS. Luego habrá que ver como se aprovechan los cores...
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3138
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #13 en: 19 de Febrero de 2017, 06:49:02 »
Tienen muy buena pinta... lo que no me queda muy claro es si los que tienen usb y además más 512kb de ram están disponibles en un empaquetado sencillo de soldar.

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3138
Re:Ayuda I2C con PIC32MZ y xc32, pero sin HARMONY
« Respuesta #14 en: 19 de Febrero de 2017, 07:00:29 »
Una duda manwenwe, ¿qué include pones para que te reconozca los nombres de los registros?
Copiando y pegando tu código me da el error:

main.c: In function 'I2C_Init':
main.c:5495:5: error: 'I2C2BRG' undeclared (first use in this function)