MPC5604P UART Interrupt

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MPC5604P UART Interrupt

1,885 Views
xuuurraa
Contributor II

Hi, I am looking how to configure a receive interrupt in MPC5604P. I wanna an interrupt each data recepcion.

This is part of my code:

void UART_ReceiveComplete()
{
LINFLEX_0.UARTSR.R = 0x00000004; //clear interrupt flag

Toggle_LedErr();

/* wait until Slave response to the LIN header has been receive successfully */

while(0 == LINFLEX_0.LINSR.B.DRF) {} /* track LIN Status for errors */
receiveBuffer[0] = LINFLEX_0.BDRL.B.DATA0; //copy received data to receiveBuffer
receiveBuffer[1] = LINFLEX_0.BDRL.B.DATA1; //copy received data to receiveBuffer
receiveBuffer[2] = LINFLEX_0.BDRL.B.DATA2; //copy received data to receiveBuffer
receiveBuffer[3] = LINFLEX_0.BDRL.B.DATA3; //copy received data to receiveBuffer
receiveBuffer[4] = LINFLEX_0.BDRM.B.DATA4; //copy received data to receiveBuffer
receiveBuffer[5] = LINFLEX_0.BDRM.B.DATA5; //copy received data to receiveBuffer
receiveBuffer[6] = LINFLEX_0.BDRM.B.DATA6; //copy received data to receiveBuffer
receiveBuffer[7] = LINFLEX_0.BDRM.B.DATA7; //copy received data to receiveBuffer

counterRX++;
/* clear RMB, HRF, DRF and DTF flags */
LINFLEX_0.LINSR.R = 0x0207;
}

static void init_LinFLEX_0_UART (void)
{
// config LINLFEX

/* enter INIT mode */
LINFLEX_0.LINCR1.R = 0x0081; /* SLEEP=0, INIT=1 */

/* wait for the INIT mode */
while (0x1000 != (LINFLEX_0.LINSR.R & 0xF000)) {}

/* configure pads */
SIU.PCR[18].R = 0x0604; /* Configure pad PB2 for AF1 func: LIN0TX */
SIU.PCR[19].R = 0x0100; /* Configure pad PB3 for LIN0RX */

LINFLEX_0.UARTCR.R = 0x0001; /* set the UART bit first to be able to write the other bits */

LINFLEX_0.UARTCR.R = 0x0033; /* 8bit data, no parity, Tx and Rx enabled, UART mode */
/* Transmit buffer size = 1 (TDFL = 0 */
/* Receive buffer size = 1 (RDFL = 0) */

LINFLEX_0.UARTSR.B.SZF = 1; // clear SZF flag
LINFLEX_0.UARTSR.B.DRF = 1; // clear data reception completed flag

/* configure baudrate 9600 */
LINFLEX_0.LINIBRR.R = 416; // 9600 Baud
LINFLEX_0.LINFBRR.R = 11; //(Registres en p.679 de "MPC5604P Microcontroller Reference Manual" Rev.4m
//Table 22-1. "Error calculation for programmed baud rates")
/* enter NORMAL mode */
LINFLEX_0.LINCR1.R = 0x0080; // INIT=0
LINFLEX_0.LINIER.B.DRIE = 1; //Receive interrupt enable 
}

int main(void)
{
volatile int i = 0;
uint8_t dummy = 0;
//int32_t dummy2;

/* INITIALITATIONS */
SYSTEM_Initialize();
Set_LedErr();
INTC_InstallINTCInterruptHandler(UART_ReceiveComplete,79,5); //Read UART Interrupt

Clr_LedErr();
Set_LedAlim();

RS485_Receive(); //RS-485 in mode Receive

/* Loop forever */
for (;;)
{

   //dummy2 = Read_UART();
   //for(i=0;i<3200000;i++){} // Wait 500 ms
   //Send_UART(dummy); // Send 8 bits data
   dummy++;
   //dummy2 = ReceiveData(dummy3);
}
}

Thanks.

8 Replies

1,306 Views
martin_kovar
NXP Employee
NXP Employee

Hello,

please see the project in the post attachment. It is not created for MPC5604P, but LINFlex module is the same.

If you have any other questions, please feel free to write me back.

Regards,

Martin

0 Kudos

1,306 Views
tanmayeesapre
Contributor II

Hi Martin,

I am trying to get interrupt based UART working on MPC5643L. Attached is the project from code warrior. I can see that the Rx buffer is being written to, however I never enter the ISR function for the Rx.

The LINFlex modules are similar. I have updated the IRQ numbers and the LinFlexD register names as per my board. I am sending data via putty. Is there something wrong with my project?

Thanks,

Tanmayee

0 Kudos

1,306 Views
martin_kovar
NXP Employee
NXP Employee

Hello,

i checked your project, but I do not see interrupt enable in LinFlexD_0 module. There is DRIE bit LINIER register, which must be set to 1.

Regards,

Martin

1,306 Views
xuuurraa
Contributor II

I have tried to implement some of the code posted for MPC5604P, but not work. Then I tried to configure only the recieve interruption, but still not working.

I´m using new codeWarrior, version 10.5.

This is my last code:

#include "MPC5604P.h"
#include "IntcInterrupts.h"

int counterTX = 0;
int counterRX = 0;
char receiveBuffer[20];

/*------------------------Funció InitCMU_0----------------------------------------------------
* Es configura el Clock Monitor Unit per a complir l'especificacio:
* Monitor FXOSC>FIRC/4 (4Mhz); withou FMPLL monitor
* FXOSC=8Mhz i FIRC=
*
* 16Mhz;
* (Registres en p.112 de "MPC5604P Microcontroller Reference Manual" Rev.4)
--------------------------------------------------------------------------------------------*/
void InitCMU_0(void)
{
CGM.CMU_0_CSR.R = 0x00000004;
}

/*------------------------Funció InitModesAndClks-------------------------------------------*
* S'habiliten els modes DRUN, RUN0, SAFE i RESET.
* El rellotge del sistema és del tipus FMPLL, aconseguint 64Mz a partir d'un cristall de 8MHz
* Es configuren els periferics per treballar en el mode RUN0
* (Registres en p.141 de "MPC5604P Microcontroller Reference Manual" Rev.4)
* => Mode Entry Module (ME)
* (Registres en p.120 de "MPC5604P Microcontroller Reference Manual" Rev.4)
* => Clock Generation Module (CGM)
--------------------------------------------------------------------------------------------*/

void InitModesAndClks(void)
{
ME.MER.R = 0x0000001D; // Enable DRUN, RUN0, SAFE, RESET modes
// Initialize PLL before turning it on:

CGM.FMPLL[0].CR.R = 0x02400100; // 8 MHz xtal: Set PLL0 to 64 MHz

ME.RUN[0].R = 0x001F0074; // RUN0 cfg: 16MHzIRCON,OSC0ON,PLL0ON,syclk=PLL

ME.RUNPC[0].R = 0x00000010; // Peri. Cfg. 0 settings: only run in RUN0 mode
ME.RUNPC[1].R = 0x00000010; /* Peri. Cfg. 1 settings: only run in RUN0 mode */
ME.PCTL[16].R = 0x0000; // FlexCAN0: select ME.RUNPC[0]
ME.PCTL[4].R = 0x0000; // DSPI0: select ME.RUNPC[0]
ME.PCTL[32].R = 0x01; // ADC 0: select ME.RUNPC[1] ??????????

// Mode Transition to enter RUN0 mode:
ME.MCTL.R = 0x40005AF0; // Enter RUN0 Mode & Key
ME.MCTL.R = 0x4000A50F; // Enter RUN0 Mode & Inverted Key

while (ME.IS.B.I_MTC != 1) {} // Wait for mode transition to complete
ME.IS.R = 0x00000001; // Clear Transition flag
}

/*------------------------Funció DisableWatchdog----------------------------------------------
* (Registres en p.954 de "MPC5604P Microcontroller Reference Manual" Rev.4)
--------------------------------------------------------------------------------------------*/
void DisableWatchdog(void)
{
SWT.SR.R = 0x0000c520; // Write keys to clear soft lock bit
SWT.SR.R = 0x0000d928;
SWT.CR.R = 0x8000010A; // Clear watchdog enable (WEN)
}

/*------------------------- initPeroClckGen Function-----------------------------------------
*
------------------------------------------------------------------------------------------*/
void initPeriClkGen(void) {
CGM.AC2SC.R = 0x04000000; /* MPC56xxP Safety Port: Select PLL0 for aux clk 0 */
CGM.AC2DC.R = 0x80000000; /* MPC56xxP Safety Port: Enable aux clk 0 div by 1 */

CGM.AC0SC.R = 0x04000000; /* MPC56xxP ADC: Select PLL0 for aux clk 0 */
CGM.AC0DC.R = 0x80000000; /* MPC56xxP ADC: Enable aux clk 0 div by 1 */
}


void LIN0_Init()
{
volatile int i = 0;

LINFLEX_0.LINCR1.B.INIT = 1;
LINFLEX_0.LINCR1.B.SLEEP = 0;

LINFLEX_0.LINIBRR.R = 0x000001A0; //baud rate 9600b/s (fsys 64MHz)
LINFLEX_0.LINFBRR.R = 0x0000000B;

LINFLEX_0.UARTCR.B.UART = 1; //enable UART mode
LINFLEX_0.UARTCR.B.WL = 1; //set 8-bit data

LINFLEX_0.UARTCR.B.RXEN = 1; //enable transmitter
LINFLEX_0.UARTCR.B.RDFL = 0b00; //set transmitter buffer (1)

LINFLEX_0.LINIER.B.DRIE = 1; //Receive interrupt enable

LINFLEX_0.LINCR1.B.INIT = 0; //disable init mode
for(i ; i < 5000; i++){} //wait fo apply settings
}

void LIN0_ReceiveComplete()
{
LINFLEX_0.UARTSR.R = 0x00000004; //clear interrupt flag

receiveBuffer[counterRX] = (char)LINFLEX_0.BDRM.B.DATA4; //copy received data to receiveBuffer

counterRX++;
}


int main(void)
{
volatile int dummy = 0;

InitCMU_0(); // 8 MHz OSC requires non-default CMU_0 init
InitModesAndClks(); // Initialize mode entries
DisableWatchdog(); // Disable watchdog
initPeriClkGen();

LIN0_Init();

//SIU.PCR[19].R = 0x0100; //LIN0 RX B3
SIU.PCR[23].R = 0x0100; //LIN0 RX B7

INTC_InstallINTCInterruptHandler(LIN0_ReceiveComplete,79,5);

INTC.CPR.R = 0;

/* Loop forever */
for (;;)
{
dummy++;
counterRX=counterRX; //To see counterRX when debugg
}
}

0 Kudos

1,306 Views
martin_kovar
NXP Employee
NXP Employee

Hello,

what board you use? Have you your own design or you use NXP EVB?

How do you check receive function? Do you have the microcontroller connected to computer or to another microcontroller?

Please write me back more details.

Regards,

Martin

0 Kudos

1,306 Views
xuuurraa
Contributor II

Hi,
I am not using a board, I have my own design, I´m using a SPC5604PGVQ6 connected to communication RS-485. The microcontroller is connected to PC with a USB-RS485, or sometimes connected to another microcontroller, now I am trying communication between two microcontrollers. In old codes I tried to read with software request and works fine, but I would like do it with an interruption. If you want more details please feel free to ask me back.

This images is a part of my project.

pastedImage_2.png

pastedImage_1.png

0 Kudos

1,306 Views
martin_kovar
NXP Employee
NXP Employee

Hello,

the information about software request is very important for me. Which target you use RAM or FLASH?

If you use RAM target, you have to define following macro to the RAM.prefix file place in Prefix folder in your project:

#define CALL_USR_INIT 1

pastedImage_1.png

Regards,

Martin

1,306 Views
xuuurraa
Contributor II

Thank you very very much. WORKS!!!

Regards,

Xurra