/*
* File: MAIN_PIC32MZ.c
* Author: Carlos
*
* Created on 8 de diciembre de 2014, 09:57 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <xc.h>
#include <proc/p32mz2048ecg100.h>
#include <sys/attribs.h>
#include <stdint.h>
#define MIPS 100.0
#define FCY 100000000
#define BAUDIOS_9600 9600
#define _9600_BAUDIOS (FCY/(4*(unsigned long)BAUDIOS_9600))-1
#pragma config DEBUG = OFF
#pragma config JTAGEN = OFF
#pragma config ICESEL = ICS_PGx2
#pragma config TRCEN = ON
#pragma config BOOTISA = MIPS32
#pragma config FECCCON = OFF_UNLOCKED
#pragma config FSLEEP = OFF
#pragma config DBGPER = PG_ALL
#pragma config EJTAGBEN = NORMAL
#pragma config CP = OFF
// DEVCFG1
#pragma config FNOSC = SPLL
#pragma config DMTINTV = WIN_127_128
#pragma config FSOSCEN = OFF
#pragma config IESO = OFF
#pragma config POSCMOD = OFF
#pragma config OSCIOFNC = OFF
#pragma config FCKSM = CSDCMD
#pragma config WDTPS = PS1048576
#pragma config WDTSPGM = STOP
#pragma config FWDTEN = OFF
#pragma config WINDIS = NORMAL
#pragma config FWDTWINSZ = WINSZ_25
#pragma config DMTCNT = DMT31
#pragma config FDMTEN = OFF
// DEVCFG2
#pragma config FPLLIDIV = DIV_1
#pragma config FPLLRNG = RANGE_5_10_MHZ
#pragma config FPLLICLK = PLL_FRC
#pragma config FPLLMULT = MUL_50
#pragma config FPLLODIV = DIV_2
#pragma config UPLLFSEL = FREQ_24MHZ
#pragma config UPLLEN = OFF
// DEVCFG3
#pragma config USERID = 0xffff
#pragma config FMIIEN = OFF
#pragma config FETHIO = OFF
#pragma config PGL1WAY = ON
#pragma config PMDL1WAY = OFF
#pragma config IOL1WAY = OFF
#pragma config FUSBIDIO = OFF
// BF1SEQ0
#pragma config TSEQ = 0xffff
#pragma config CSEQ = 0xffff
unsigned char contador = 0;
char str_TX_UART[100];
unsigned char flag_T3 = 0;
unsigned char flag_T5 = 0;
unsigned char flag_T7 = 0;
unsigned char flag_T9 = 0;
unsigned char flag_U2 = 0;
unsigned char dat_U2 = 0;
unsigned char flag_Iext0 = 0;
unsigned char flag_Iext1 = 0;
unsigned char flag_Iext2 = 0;
unsigned char flag_Iext3 = 0;
unsigned char flag_Iext4 = 0;
void code_basura(void);
void init_PORTS(void);
void out_CLK(void);
void init_timer32(void);
//void __attribute__((vector(_TIMER_3_VECTOR), interrupt(ipl1), nomips16)) Timer3Handler(void);
void __ISR(_TIMER_3_VECTOR, ipl1) T3_Interrupt(void);
//void __ISR_AT_VECTOR(_TIMER_3_VECTOR, ipl3) T3_Interrupt(void);
void calculo_frecuencia(unsigned int val_frec);
//void __attribute__((vector(_UART2_RX_VECTOR), interrupt(ipl1), nomips16)) U2RXHandler(void);//
void __ISR(_UART2_RX_VECTOR, ipl1)U2RXHandler(void);
void UART2Init(unsigned short baudios);
void UART2PutChar(char ch);
void UART2PrintString(char *str);
//void __attribute__((vector(_TIMER_5_VECTOR), interrupt(ipl1), nomips16)) Timer5Handler(void);
void __ISR(_TIMER_5_VECTOR, ipl1) T5_Interrupt(void);
void TimerInit(void);
void __ISR(_TIMER_7_VECTOR, ipl1) T7_Interrupt(void);
void __ISR(_TIMER_9_VECTOR, ipl1) T9_Interrupt(void);
void __ISR(_EXTERNAL_2_VECTOR, ipl1) Int2_Interrupt(void);
void init_IExt0(void);
void init_IExt1(void);
void init_IExt2(void);
void init_IExt3(void);
void init_IExt4(void);
int main() {
// PB7DIVbits.ON = 1; //// CLOCK PB3 ENABLE PARA TIMER
// PB7DIVbits.PBDIV = 2; //// DIVIDE LOS 200Mhz ENTRE 2 Y LOGRA 100Mhz
PRECONbits.PFMWS = 2; ///2 ESTADOS DE ESPERA PARA CACHE SEGUN TABLA 36-13 PIC32MZ 166 < SYSCLK <= 200
PRECONbits.PREFEN = 2;
/* 11 = Enable predictive prefetch for any address
10 = Enable predictive prefetch for CPU instructions and CPU data
01 = Enable predictive prefetch for CPU instructions only
00 = Disable predictive prefetch
*/
out_CLK();
init_PORTS();
UART2Init(_9600_BAUDIOS);
sprintf(str_TX_UART
, "Iniciando Sistema\r\n"); UART2PrintString(str_TX_UART);
sprintf(str_TX_UART
, "PIC32MZ2048ECG100 I/PT\r\n"); UART2PrintString(str_TX_UART);
sprintf(str_TX_UART
, "Uart2 Init\r\n"); UART2PrintString(str_TX_UART);
sprintf(str_TX_UART
, " 9600 Baudios\r\n"); UART2PrintString(str_TX_UART);
sprintf(str_TX_UART
, "Timer3 Init\r\n"); UART2PrintString(str_TX_UART);
init_timer32();
calculo_frecuencia(10);
TimerInit();
PR4 = PR2; // Period register
PR5 = PR3; // Period register
PR6 = PR2; // Period register
PR7 = PR3; // Period register
PR8 = PR2; // Period register
PR9 = PR3; // Period register
init_IExt0();
init_IExt1();
init_IExt2();
init_IExt3();
init_IExt4();
INTCONbits.MVEC = 1; /// MULTIVECTOR INTERRUPCIONES
__builtin_enable_interrupts();
while (1) {
if(IFS4bits.U2RXIF) { ///CODGIO QUE SE EJECUTA DIRECTAMENTE SIN EJECUTAR CODIGO DE INTERRUPCION
sprintf(str_TX_UART
, "UART: %c\r\n",U2RXREG
);UART2PrintString
(str_TX_UART
); IFS4bits.U2RXIF = 0;
}
if (flag_U2) { ///CODIGO QUE DEBE EJECUTARSE RESULTADO DEL CODIGO DE LA INTERRUPCION
flag_U2 = 0;
sprintf(str_TX_UART
, "UART: \r\n");UART2PrintString
(str_TX_UART
); }
if (flag_T3) {
flag_T3 = 0;
sprintf(str_TX_UART
, "Timer 3\r\n"); UART2PrintString(str_TX_UART);
}//
if (flag_T5) {
flag_T5 = 0;
sprintf(str_TX_UART
, "Timer 5\r\n"); UART2PrintString(str_TX_UART);
}//
if (flag_T7) {
flag_T7 = 0;
sprintf(str_TX_UART
, "Timer 7\r\n"); UART2PrintString(str_TX_UART);
}//
if (flag_T9) {
flag_T9 = 0;
sprintf(str_TX_UART
, "Timer 9\r\n"); UART2PrintString(str_TX_UART);
}//
if (flag_Iext0) {
flag_Iext0 = 0;
UART2PrintString(str_TX_UART);
}
if (flag_Iext1) {
flag_Iext1 = 0;
UART2PrintString(str_TX_UART);
}
if (flag_Iext2) {
flag_Iext2 = 0;
UART2PrintString(str_TX_UART);
}
if (flag_Iext3) {
flag_Iext3 = 0;
UART2PrintString(str_TX_UART);
}
if (flag_Iext4) {
flag_Iext4 = 0;
UART2PrintString(str_TX_UART);
}
}//
return (EXIT_SUCCESS);
}//
void code_basura(void) ///CODIGO USADO PARA CUANDO HAY POCAS INSTRUCCIONES EN MAIN PRINCIPAL, LAS INTERRUPCIONES PUEDAN EJECUTARSE NORMALMENTE
{
switch (contador) {
/////contador = 0;
case 0:contador++;
break;
case 1:contador++;
break;
case 2:contador++;
break;
case 3:contador++;
break;
case 4:contador++;
break;
case 5:contador++;
break;
case 6:contador++;
break;
case 7:contador++;
break;
case 8:contador++;
break;
case 9:contador++;
break;
case 10:contador++;
break;
case 11:contador++;
break;
case 12:contador++;
break;
case 13:contador++;
break;
case 14:contador++;
break;
case 15:contador++;
break;
case 16:contador++;
break;
case 17:contador++;
break;
case 18:contador++;
break;
case 19:contador++;
break;
case 20:contador++;
break;
case 21:contador++;
break;
case 22:contador++;
break;
case 23:contador = 0;
break;
}
}
void init_PORTS(void) {
PB4DIVbits.ON = 1; //// CLOCK PB4 ENABLE PARA GPIO's
PB4DIVbits.PBDIV = 2; //// DIVIDE LOS 200Mhz ENTRE 2 Y LOGRA 100Mhz
ANSELA = 0;
ODCA = 0;
CNPUA = 0;
CNPDA = 0;
TRISA = 0;
LATA = 0;
ANSELB = 0;
ODCB = 0;
CNPUB = 0;
CNPDB = 0;
TRISB = 0;
LATB = 0;
ANSELC = 0;
ODCC = 0;
CNPUC = 0;
CNPDC = 0;
TRISC = 0;
LATC = 0;
ANSELD = 0;
ODCD = 0;
CNPUD = 0;
CNPDD = 0;
TRISD = 0;
LATD = 0;
ANSELE = 0;
ODCE = 0;
CNPUE = 0;
CNPDE = 0;
TRISE = 0;
LATE = 0;
ANSELF = 0;
ODCF = 0;
CNPUF = 0;
CNPDF = 0;
TRISF = 0;
LATF = 0;
ANSELG = 0;
ODCG = 0;
CNPUG = 0;
CNPDG = 0;
TRISG = 0;
LATG = 0;
}//
void out_CLK(void) {
RPD2Rbits.RPD2R = 0b1101; //// SALIDA DE REFCLKO4 POR EL PORT D2
//CNCONDbits.ON = 0;
REFO4TRIMbits.ROTRIM = 0;
REFO4CONbits.RODIV = 100; //// DIVIDE LOS 200Mhz PARA OBTENER 1Mhz Y PODER MEDIRLO CON ANALIZADOR
REFO4CONbits.OE = 1; //// OUTPUT ENABLED
REFO4CONbits.ROSEL = 7; //// FUENTE DE CLOCK PLL
REFO4CONbits.ON = 1; //// HABILITADO EN MODULO
RPB0Rbits.RPB0R = 0b1111; //// SALIDA DE REFCLKO3 POR EL PORT B0
//CNCONDbits.ON = 0;
REFO3TRIMbits.ROTRIM = 0;
REFO3CONbits.RODIV = 100; //// DIVIDE LOS 200Mhz PARA OBTENER 1Mhz Y PODER MEDIRLO CON ANALIZADOR
REFO3CONbits.OE = 1; //// OUTPUT ENABLED
REFO3CONbits.ROSEL = 7; //// FUENTE DE CLOCK PLL
REFO3CONbits.ON = 1; //// HABILITADO EN MODULO
}
void __ISR(_TIMER_3_VECTOR, ipl1) T3_Interrupt(void) {
flag_T3 = 1;
IFS0bits.T3IF = 0;
}
void __ISR(_UART2_RX_VECTOR, ipl1)U2RXHandler(void) {
flag_U2 = 1; //
U2TXREG = U2RXREG; //while(!U2STAbits.TRMT); flag_U2 = 1;
IFS4bits.U2RXIF = 0;
}
void calculo_frecuencia(unsigned int val_frec) {
if (!val_frec)val_frec = 1;
sprintf(str_TX_UART
, " %u Hz\r\n", val_frec
); UART2PrintString(str_TX_UART);
val_frec = 1000000 / val_frec;
val_frec *= MIPS;
val_frec *= 10;
sprintf(str_TX_UART
, "val_frec %u\r\n", val_frec
); UART2PrintString(str_TX_UART);
PR2 = val_frec & 0x0000FFFF; ///cargo los 16 bits bajos
PR3 = (val_frec >> 16) & 0x0000FFFF; ///cargo los 16 bits altos
TMR2 = 0;
TMR3 = 0;
}//
void init_timer32(void)////timer2 y timer3 forman timer32
{
PB3DIVbits.ON = 1; //// CLOCK PB3 ENABLE PARA TIMER
PB3DIVbits.PBDIV = 2; //// DIVIDE LOS 200Mhz ENTRE 2 Y LOGRA 100Mhz
T2CONbits.TON = 0; // Stop timer
T3CONbits.TON = 0; // Stop timer
TMR2 = 0; // Clear contenst of the TMR4
T2CONbits.T32 = 1; // 32-bit timer
T2CONbits.TCKPS = 0; // Divide by 8
T2CONbits.TCS = 0; // Internal clock
IPC3bits.T3IP = 1; // Set priority level = 1
IPC3bits.T3IS = 1; // Set sub-priority level = 1
IFS0bits.T3IF = 0; // Clear the Timer4 interrupt status flag
IEC0bits.T3IE = 1; // Enable Timer5 interrupts
T2CONbits.TON = 1; // Start timer
T6CONbits.TON = 0; // Stop timer
T7CONbits.TON = 0; // Stop timer
TMR6 = 0; // Clear contenst of the TMR4
T6CONbits.T32 = 1; // 32-bit timer
T6CONbits.TCKPS = 0; // Divide by 8
T6CONbits.TCS = 0; // Internal clock
IPC8bits.T7IP = 1; // Set priority level = 1
IPC8bits.T7IS = 1; // Set sub-priority level = 1
IFS1bits.T7IF = 0; // Clear the Timer4 interrupt status flag
IEC1bits.T7IE = 1; // Enable Timer5 interrupts
T6CONbits.TON = 1; // Start timer
T8CONbits.TON = 0; // Stop timer
T9CONbits.TON = 0; // Stop timer
TMR8 = 0; // Clear contenst of the TMR4
T8CONbits.T32 = 1; // 32-bit timer
T8CONbits.TCKPS = 0; // Divide by 8
T8CONbits.TCS = 0; // Internal clock
IPC10bits.T9IP = 1; // Set priority level = 1
IPC10bits.T9IS = 1; // Set sub-priority level = 1
IFS1bits.T9IF = 0; // Clear the Timer4 interrupt status flag
IEC1bits.T9IE = 1; // Enable Timer5 interrupts
T8CONbits.TON = 1; // Start timer
}//
void UART2Init(unsigned short baudios) {
TRISDbits.TRISD4 = 1;
RPB2Rbits.RPB2R = 0b0010; //// PPS UART2TX
U2RXRbits.U2RXR = 0b0100; //// RX2 EN PIND4
PB2DIVbits.ON = 1; //// CLOCK PB2 ENABLE PARA UART
PB2DIVbits.PBDIV = 2; //// DIVIDE LOS 200Mhz ENTRE 2 Y LOGRA 100Mhz
U2BRG = baudios;
U2STA = 0;
U2MODE = 0;
U2MODEbits.BRGH = 1;
U2STAbits.URXEN = 1;
U2STAbits.UTXEN = 1;
U2STAbits.URXISEL = 0;
IPC36bits.U2EIP = 1;
IPC36bits.U2EIS = 1;
IFS4bits.U2RXIF = 0;
IEC4bits.U2RXIE = 1;
U2MODEbits.ON = 1;
}//
void UART2PrintString(char *str) {
unsigned char c;
while ((c = *str++))
UART2PutChar(c);
}//
void UART2PutChar(char ch) {
U2TXREG = ch;
Nop();
while (!U2STAbits.TRMT);
}//
void TimerInit(void) {
T4CONbits.TON = 0; // Stop timer
T5CONbits.TON = 0; // Stop timer
TMR4 = 0; // Clear contenst of the TMR4
T4CONbits.T32 = 1; // 32-bit timer
T4CONbits.TCKPS = 0; // Divide by 8
PR4 = 1000; // Period register
T4CONbits.TCS = 0; // Internal clock
IPC6bits.T5IP = 1; // Set priority level = 1
IPC6bits.T5IS = 1; // Set sub-priority level = 1
IFS0bits.T5IF = 0; // Clear the Timer4 interrupt status flag
IEC0bits.T5IE = 1; // Enable Timer5 interrupts
//asm volatile("ei"); // Assembler interrupts enable
T4CONbits.TON = 1; // Start timer
}
void __ISR(_TIMER_5_VECTOR, ipl1) T5_Interrupt(void) {
flag_T5 = 1;
LATBbits.LATB3 = ~LATBbits.LATB3;
IFS0bits.T5IF = 0; //Clear flag
}
void __ISR(_TIMER_7_VECTOR, ipl1) T7_Interrupt(void) {
flag_T7 = 1;
IFS1bits.T7IF = 0; //Clear flag
}
void __ISR(_TIMER_9_VECTOR, ipl1) T9_Interrupt(void) {
flag_T9 = 1;
IFS1bits.T9IF = 0; //Clear flag
}
void __ISR(_EXTERNAL_0_VECTOR, ipl1) Int0_Interrupt(void) {
flag_Iext0 = 1;
IFS0bits.INT0IF = 0; //Clear flag
}
void __ISR(_EXTERNAL_1_VECTOR, ipl1) Int1_Interrupt(void) {
flag_Iext1 = 1;
IFS0bits.INT1IF = 0; //Clear flag
}
void __ISR(_EXTERNAL_2_VECTOR, ipl1) Int2_Interrupt(void) {
flag_Iext2 = 1;
IFS0bits.INT2IF = 0; //Clear flag
}
void __ISR(_EXTERNAL_3_VECTOR, ipl1) Int3_Interrupt(void) {
flag_Iext3 = 1;
IFS0bits.INT3IF = 0; //Clear flag
}
void __ISR(_EXTERNAL_4_VECTOR, ipl1) Int4_Interrupt(void) {
flag_Iext4 = 1;
IFS0bits.INT4IF = 0; //Clear flag
}
void init_IExt0(void) {
TRISDbits.TRISD0 = 1;
IPC0bits.INT0IP = 1;
IPC0bits.INT0IS = 1;
//INT0Rbits.INT0R = 1; ///PORTG9 ENTRADA INTEX2
IFS0bits.INT0IF = 0;
IEC0bits.INT0IE = 1;
}
void init_IExt1(void) {
TRISGbits.TRISG9 = 1;
IPC2bits.INT1IP = 1;
IPC2bits.INT1IS = 1;
INT1Rbits.INT1R = 1; ///PORTG9 ENTRADA INTEX2
IFS0bits.INT1IF = 0;
IEC0bits.INT1IE = 1;
}
void init_IExt2(void) {
TRISGbits.TRISG6 = 1;
IPC3bits.INT2IP = 1;
IPC3bits.INT2IS = 1;
INT2Rbits.INT2R = 1; ///PORTG6 ENTRADA INTEX2
IFS0bits.INT2IF = 0;
IEC0bits.INT2IE = 1;
}
void init_IExt3(void) {
TRISGbits.TRISG8 = 1;
IPC4bits.INT3IP = 1;
IPC4bits.INT3IS = 1;
INT3Rbits.INT3R = 1; ///PORTG8 ENTRADA INTEX2
IFS0bits.INT3IF = 0;
IEC0bits.INT3IE = 1;
}
void init_IExt4(void) {
TRISGbits.TRISG7 = 1;
IPC5bits.INT4IP = 1;
IPC5bits.INT4IS = 1;
INT4Rbits.INT4R = 1; ///PORTG7 ENTRADA INTEX2
IFS0bits.INT4IF = 0;
IEC0bits.INT4IE = 1;
}