Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: Problems with IRQ_UART0_STATUS and attachInterruptVector

  1. #1
    Senior Member
    Join Date
    Apr 2013
    Posts
    127

    Problems with IRQ_UART0_STATUS and attachInterruptVector

    Hello,

    I have enabled an trigger event on UART0_S2, the UART_S2_LBKDE Flag, so I attached my ISR routine to it, when the Flag is fired the IRQ_UART0_STATUS does nothing. Even there is nothing inside the ISR routine he should jump in it, it look like IRQ_UART0_STATUS don't look inside UART0_S2.


    Simpified Sketch
    Code:
    #define PRINTBIN(Num) for (uint32_t t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num  & t ? '1' : '0'); // Prints a binary number with leading zeros (Automatic Handling)
    
    //Lin Initailisation
    #define linspeed                19200
    
    int activeBufIndex;
    uint8_t *activeBuf;
    constexpr int max_LinBUS_Datasize = 10;
    
    int pointer = 0;
    
    void uart0isr_status() {
      UART0_S2 |= UART_S2_LBKDIF;
      UART0_S2 |= UART_S2_RXEDGIF;
      pointer++;
    }
    
    void uart0isr_error() {
      UART0_S1 &= ~UART_S1_OR;
      pointer++;
    }
    
    void setup() {
      Serial.begin(115200);
      pinMode(19, OUTPUT);
      LinBUS_begin();
    }
    
    void loop() {
      Serial.print("UART0_S1 ");
      PRINTBIN(UART0_S1);
    
      Serial.print(" UART0_S2 ");
      PRINTBIN(UART0_S2);
      Serial.println();
      
      Serial.println(pointer);
      delay(250);
    }
    
    void LinBUS_begin(void) {
      Serial1.begin(linspeed);
    
      attachInterruptVector(IRQ_UART0_STATUS, uart0isr_status);
      attachInterruptVector(IRQ_UART0_ERROR, uart0isr_error);
    
      // We fill bytes from the buffer in the framing error ISR, so we
      // can set to the same priority.
      NVIC_SET_PRIORITY(IRQ_UART0_ERROR, NVIC_GET_PRIORITY(IRQ_UART0_STATUS));
    
      //UART0_S2 &= ~UART_S2_RXINV;
      //UART0_C1 |= UART_C1_M;
      //UART0_C4 &= ~UART_C4_M10;
      //UART0_C1 |= UART_C1_PE;
      
      // Enable LinBreakdetection on UART0
      UART0_S2 |= UART_S2_LBKDE;
      NVIC_ENABLE_IRQ(IRQ_UART0_STATUS);
      
      // Enable UART0 interrupt on frame error
      //UART0_C3 |= UART_C3_FEIE;
      //UART0_C3 |= UART_C3_ORIE;
      NVIC_ENABLE_IRQ(IRQ_UART0_ERROR);
    }
    Output
    Code:
    12:11:55.173 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.173 -> 0
    12:11:55.173 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.173 -> 0
    12:11:55.173 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.173 -> 0
    12:11:55.173 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.173 -> 0
    12:11:55.173 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.173 -> 0
    12:11:55.173 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.173 -> 0
    12:11:55.173 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.173 -> 0
    12:11:55.405 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.405 -> 0
    12:11:55.675 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.675 -> 0
    12:11:55.929 -> UART0_S1 11001000 UART0_S2 11000010
    12:11:55.929 -> 0
    12:11:56.176 -> UART0_S1 11001000 UART0_S2 11000010
    12:11:56.176 -> 0
    12:11:56.430 -> UART0_S1 11001000 UART0_S2 11000010
    12:11:56.430 -> 0
    12:11:56.678 -> UART0_S1 11001000 UART0_S2 11000010
    Any advice to it? May my I made some mistakes.
    Last edited by Markus_L811; 04-10-2019 at 11:53 AM.

  2. #2
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,419
    The global pointer variable must be declared volatile, since it will be modified within an ISR. After that, at least the pointer should be incremented at each run of the ISR.

  3. #3
    Senior Member
    Join Date
    Apr 2013
    Posts
    127
    Quote Originally Posted by Theremingenieur View Post
    The global pointer variable must be declared volatile, since it will be modified within an ISR. After that, at least the pointer should be incremented at each run of the ISR.
    Unfortunately not
    Code:
    volatile int pointer = 0;
    does make no difference

  4. #4
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,419
    From that, we can already conclude that your ISR is never called.

  5. #5
    Senior Member
    Join Date
    Apr 2013
    Posts
    127
    Quote Originally Posted by Theremingenieur View Post
    From that, we can already conclude that your ISR is never called.
    Since the Flag is called he should
    Code:
    12:11:55.675 -> UART0_S1 11000000 UART0_S2 00000010
    12:11:55.929 -> UART0_S1 11001000 UART0_S2 11000010
    Teensy 3.0 Manuel on Page 1061
    Click image for larger version. 

Name:	LinBRK_Flag.JPG 
Views:	12 
Size:	137.4 KB 
ID:	16386

  6. #6
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    1,973
    try enabling LBKDIE RXEDGIE in UART_BDH

  7. #7
    Senior Member
    Join Date
    Apr 2013
    Posts
    127
    Quote Originally Posted by manitou View Post
    try enabling LBKDIE RXEDGIE in UART_BDH
    I did but it breaks the Sketch, stops may directly before UART0_S2 becomes 11000010

  8. #8
    Senior Member
    Join Date
    Apr 2013
    Posts
    127
    Modified Version:

    Code:
    #define LBKDIE  0x80
    #define RXEDGIE 0x40
    
    #define PRINTBIN(Num) for (uint32_t t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num  & t ? '1' : '0'); // Prints a binary number with leading zeros (Automatic Handling)
    
    //Lin Initailisation
    #define linspeed                19200
    
    int activeBufIndex;
    uint8_t *activeBuf;
    constexpr int max_LinBUS_Datasize = 10;
    
    volatile int pointer = 0;
    
    void uart0isr_status() {
      __disable_irq();
      int b = UART0_D;
      UART0_S2 |= UART_S2_LBKDIF;
      UART0_S2 |= UART_S2_RXEDGIF;
      pointer++;
      __enable_irq();
    }
    
    void uart0isr_error() {
      __disable_irq();
    //  UART0_S1 &= ~UART_S1_OR;
      pointer++;
      __enable_irq();
    }
    
    void setup() {
      Serial.begin(115200);
      pinMode(19, OUTPUT);
      LinBUS_begin();
    }
    
    void loop() {
      Serial.print("UART0_S1 ");
      PRINTBIN(UART0_S1);
    
      Serial.print(" UART0_S2 ");
      PRINTBIN(UART0_S2);
    
      Serial.print(" UART0_BDH ");
      PRINTBIN(UART0_BDH);
      Serial.print(" Pointer ");
      
      Serial.println(pointer);
      delay(250);
    }
    
    void LinBUS_begin(void) {
      Serial1.begin(linspeed);
    
      attachInterruptVector(IRQ_UART0_STATUS, uart0isr_status);
      //attachInterruptVector(IRQ_UART0_ERROR, uart0isr_error);
    
      // We fill bytes from the buffer in the framing error ISR, so we
      // can set to the same priority.
      //NVIC_SET_PRIORITY(IRQ_UART0_ERROR, NVIC_GET_PRIORITY(IRQ_UART0_STATUS));
    
      //UART0_S2 &= ~UART_S2_RXINV;
      //UART0_C1 |= UART_C1_M;
      //UART0_C4 &= ~UART_C4_M10;
      //UART0_C1 |= UART_C1_PE;
      
      // Enable LinBreakdetection on UART0
      //UART0_BDH |= LBKDIE;
      //UART0_BDH |= RXEDGIE;
      UART0_S2 |= UART_S2_LBKDE;
      NVIC_ENABLE_IRQ(IRQ_UART0_STATUS);
      
      // Enable UART0 interrupt on frame error
      //UART0_C3 |= UART_C3_FEIE;
      //UART0_C3 |= UART_C3_ORIE;
      //NVIC_ENABLE_IRQ(IRQ_UART0_ERROR);
    }
    Runs equal to the first until I activate he LBKDIE, it stops there if the LinBreak is detectet imho.

    Code:
    12:39:29.981 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 00000001 Pointer 0
    12:39:30.120 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 00000001 Pointer 0
    12:39:30.502 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 00000001 Pointer 0
    12:39:30.606 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 00000001 Pointer 0
    12:39:30.954 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 00000001 Pointer 0
    12:39:31.127 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 00000001 Pointer 0
    12:39:31.373 -> UART0_S1 11001000 UART0_S2 11000010 UART0_BDH 00000001 Pointer 0
    12:39:31.616 -> UART0_S1 11001000 UART0_S2 11000010 UART0_BDH 00000001 Pointer 0
    ...
    And if LBKDIE is activ:
    Code:
    12:43:12.572 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:12.780 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:13.058 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:13.266 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:13.544 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:13.788 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:14.030 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:14.274 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:14.517 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:14.763 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0
    12:43:15.039 -> UART0_S1 11000000 UART0_S2 00000010 UART0_BDH 10000001 Pointer 0

  9. #9
    Senior Member
    Join Date
    Apr 2013
    Posts
    127
    The Master if asked: Teensy 3.0 and up

    Code:
    //Lin Initailisation
    #define linspeed                19200
    unsigned long Tbit = 1000000/linspeed;
    
    //Tbits Header
    #define breakdelimiter              1
    
    #define syncfieldPIDinterbytedelay  0
    int syncfieldPIDinterbytespace = syncfieldPIDinterbytedelay*Tbit;
    #define breakfieldinterbytedelay    2
    int breakfieldinterbytespace = breakfieldinterbytedelay*Tbit;
    
    //Tbit Response
    #define responsedelay               8
    int responsespace = responsedelay*Tbit;
    #define interbytedelay              0
    int interbytespace = interbytedelay*Tbit;
    
    void setup() {
      Serial.begin(19200);
      Lininit();
    }
    
    void loop() {
      Serial.println("los");
      delay(2000);
      LinBreak();
      delay(2000);
    }
    
    void Lininit() {
      Serial1.begin(linspeed);
      pinMode(0, INPUT_PULLUP);
    }
    
    //working
    void LinBreak() {
    //  // 10 Bits transmitted
    //  UART0_S2 &= ~UART_S2_BRK13;
    //  UART0_C1 &= ~UART_C1_M;
    
    //  // 11 Bits transmitted
    //  UART0_S2 &= ~UART_S2_BRK13;
    //  UART0_C1 |= UART_C1_M;
    //  UART0_C4 &= ~UART_C4_M10;
    
    //  // 12 Bits transmitted
    //  UART0_S2 &= ~UART_S2_BRK13;
    //  UART0_C1 |= UART_C1_M;
    //  UART0_C4 |= UART_C4_M10;
    //  UART0_C1 |= UART_C1_PE;
    
      // 13 Bits transmitted
      UART0_S2 |= UART_S2_BRK13;
      UART0_C1 &= ~UART_C1_M;
    
    //  // 14 Bits transmitted
    //  UART0_S2 |= UART_S2_BRK13;
    //  UART0_C1 |= UART_C1_M;
    
      // Toggle SBK to send Break
      UART0_C2 |= UART_C2_SBK;
      UART0_C2 &= ~UART_C2_SBK;
      Serial1.write(0x55); //Sync
      delayMicroseconds(syncfieldPIDinterbytespace);
      Serial1.write(0x23); // PID
      delayMicroseconds(breakfieldinterbytespace);
      
      Serial1.write(0x41); // Data
    }
    Just connect Master TX to Slave RX for testing

  10. #10
    Senior Member
    Join Date
    Apr 2013
    Posts
    127
    Interesting thing:

    Code:
      // Enable LinBreakdetection on UART0
      UART0_BDH |= LBKDIE;
      UART0_BDH |= RXEDGIE;
      //UART0_S2 |= UART_S2_LBKDE;
      NVIC_ENABLE_IRQ(IRQ_UART0_STATUS);
    Is LBKDIE or RXEDGIE enabled it breaks even if UART_S2_LBKDE is not set.

  11. #11
    Senior Member
    Join Date
    Apr 2013
    Posts
    127

    Post

    The NXP UART-Testfiles looks like this:

    uart_tests_main.c
    Code:
    #include "common.h"
    #include "uart.h"
    #include "mcg.h"
    #include "uart_tests.h"
    
    /* Globals from sysinit.c */
    extern int core_clk_khz;
    extern int core_clk_mhz;
    extern int periph_clk_khz;
    
    /********************************************************************/
    void main (void)
    {
    	char ch;
            int test_failed;
            
      	    printf("\nRunning the UART test project\n\n");
                    
            /* Make sure the clocks are enabled to all UARTs */
           	SIM_SCGC4 |= (SIM_SCGC4_UART0_MASK | SIM_SCGC4_UART1_MASK | SIM_SCGC4_UART2_MASK | SIM_SCGC4_UART3_MASK);
            SIM_SCGC1 |= (SIM_SCGC1_UART4_MASK | SIM_SCGC1_UART5_MASK);
            
            /* Enable a full set of UART signals for each of the UART modules */
     
            /* Enable UART0 functions on PTD */
            PORTD_PCR4 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTD_PCR5 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTD_PCR6 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTD_PCR7 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
    
            /* Enable the UART1 functions on PTE */
            PORTE_PCR0 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTE_PCR1 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTE_PCR2 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTE_PCR3 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
    		
            /* Enable the UART2 functions on PTE */ /* Use for 256 BGA */               
            PORTE_PCR16 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTE_PCR17 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTE_PCR18 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
      	PORTE_PCR19 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            
            /* Enable the UART2 functions on PTD */ /* Use for 144 LQFP */
    /*     PORTD_PCR0 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTD_PCR1 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTD_PCR2 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
      	PORTD_PCR3 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
    */        
    
            /* Enable the UART3 functions on PTC */
            PORTC_PCR16 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTC_PCR17 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTC_PCR18 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTC_PCR19 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            
            /* Enable the UART4 functions on PTC */
            PORTC_PCR12 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTC_PCR13 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTC_PCR14 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTC_PCR15 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            
            /* Enable the UART5 functions on PTE */
            PORTE_PCR8 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTE_PCR9 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTE_PCR10 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            PORTE_PCR11 = PORT_PCR_MUX(0x3); // UART is alt3 function for this pin
            
            /* Enable the ABORT button IRQ, this is needed for some of the low
             * power mode tests. 
             *
             * NOTE: D9 needs to be removed from the board and J43 7-8 must be ON.
             */
            /* Configure the PTA4 pin for its GPIO function */
            PORTA_PCR4 = PORT_PCR_MUX(0x1); // GPIO is alt1 function for this pin
        
            /* Configure the PTA4 pin for rising edge interrupts */
            PORTA_PCR4 |= PORT_PCR_IRQC(0x9); 
        
            /* Enable the associated IRQ in the NVIC */
            enable_irq(87);      
    
     	/* initialize number of failed tests counter to zero */
    	test_failed = 0;
    
            /* Run UART tests */
    
            /* UART register tests */
            test_failed += uart_reg_rst();
             
            /* Call register read/write test with different register values to test.
             * The UART module doesn't have a software reset bit to allow for easily
             * resetting the UART after this test. Since this test changes register
             * values from the defaults and would impact subsequent tests, the 
             * sci_reg_rw test should only be run on its own. These lines should be
             * commented out when running other tests. 
             */
    
            /* This is the start of the functional tests, so stop and initialize
             * all of the UARTs to a default state.
             */
            uart_init (UART0_BASE_PTR, core_clk_khz, TERMINAL_BAUD);                  
            uart_init (UART1_BASE_PTR, core_clk_khz, TERMINAL_BAUD); 
            uart_init (UART2_BASE_PTR, periph_clk_khz, TERMINAL_BAUD); 
            uart_init (UART3_BASE_PTR, periph_clk_khz, TERMINAL_BAUD); 
            uart_init (UART4_BASE_PTR, periph_clk_khz, TERMINAL_BAUD); 
            uart_init (UART5_BASE_PTR, periph_clk_khz, TERMINAL_BAUD);   
         
            test_failed += uart_lin_break_test();
     
    	if (test_failed)
    	{
    		printf("\n\nTEST FAILED!!!\n");
    		printf("\n\n%d test(s) failed.\n", test_failed);
    	}
    	else
    		printf("\n\nAll tests PASS!\n\n");
    
    	while(1)
    	{
    		ch = in_char();
    		out_char(ch);
    	} 
    }
    uart.c
    Code:
    void uart_init (UART_MemMapPtr uartch, int sysclk, int baud)
    {
        register uint16 sbr, brfa;
        uint8 temp;
        
    	/* Enable the clock to the selected UART */    
        if(uartch == UART0_BASE_PTR)
    		SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
        else
        	if (uartch == UART1_BASE_PTR)
    			SIM_SCGC4 |= SIM_SCGC4_UART1_MASK;
        	else
        		if (uartch == UART2_BASE_PTR)
        			SIM_SCGC4 |= SIM_SCGC4_UART2_MASK;
        		else
        			if(uartch == UART3_BASE_PTR)
        				SIM_SCGC4 |= SIM_SCGC4_UART3_MASK;
        			else
        				if(uartch == UART4_BASE_PTR)
        					SIM_SCGC1 |= SIM_SCGC1_UART4_MASK;
        				else
        					SIM_SCGC1 |= SIM_SCGC1_UART5_MASK;
                                    
        /* Make sure that the transmitter and receiver are disabled while we 
         * change settings.
         */
        UART_C2_REG(uartch) &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK );
    
        /* Configure the UART for 8-bit mode, no parity */
        UART_C1_REG(uartch) = 0;	/* We need all default settings, so entire register is cleared */
        
        /* Calculate baud settings */
        sbr = (uint16)((sysclk*1000)/(baud * 16));
            
        /* Save off the current value of the UARTx_BDH except for the SBR field */
        temp = UART_BDH_REG(uartch) & ~(UART_BDH_SBR(0x1F));
        
        UART_BDH_REG(uartch) = temp |  UART_BDH_SBR(((sbr & 0x1F00) >> 8));
        UART_BDL_REG(uartch) = (uint8)(sbr & UART_BDL_SBR_MASK);
        
        /* Determine if a fractional divider is needed to get closer to the baud rate */
        brfa = (((sysclk*32000)/(baud * 16)) - (sbr * 32));
        
        /* Save off the current value of the UARTx_C4 register except for the BRFA field */
        temp = UART_C4_REG(uartch) & ~(UART_C4_BRFA(0x1F));
        
        UART_C4_REG(uartch) = temp |  UART_C4_BRFA(brfa);    
    
        /* Enable receiver and transmitter */
        UART_C2_REG(uartch) |= (UART_C2_TE_MASK | UART_C2_RE_MASK );
    }
    uart_rx_interrupt_tests.c
    Code:
    #include "common.h"
    #include "uart.h"
    #include "uart_tests.h"
    
    /* Globals for counting number of interrupts */
    int num_rdrf_int = 0;
    int num_or_errors = 0;
    int num_rxuf_errors = 0;
    int num_parity_errors = 0;
    int num_nf_errors = 0;
    int num_framing_errors = 0;
    int num_idle_int = 0;
    int num_lin_breaks = 0;
    
    /* Globals from sysinit.c */
    extern int core_clk_khz;
    extern int core_clk_mhz;
    extern int periph_clk_khz;
    ...
    ...
    int uart_lin_break_test()
    {
        UART_MemMapPtr tx_module, rx_module;
        char ch;
        uint32 i;    
        
        /* Make sure the number of LIN break interrupts is zero before starting */
        num_lin_breaks = 0;
        
        printf("\n\nStarting LIN break detect interrupt test.\n");
    
        /* Determine which UART to use as the transmitter for testing. UART2 or UART3
         * could be used. We'll use UART2 as long as it isn't used as the TERM_PORT.
         */
        if (TERM_PORT != UART2_BASE_PTR)
        {      
           tx_module = UART2_BASE_PTR;   // set the module pointer
           
           printf("\nUsing UART2 on the daughter card as the transmitter.");
           printf("\nConnect one end of a blue wire to J4 pin 2 (UART2_TX)");
        }      
        else
        {      
           tx_module = UART3_BASE_PTR;   // set the module pointer
    
           printf("\nUsing UART3 on the daughter card as the transmitter.");
           printf("\nConnect one end of a blue wire to J43 pin 2 (UART3_TX)");
        }
    
        printf("\nPress any key when ready.\n");
        ch = in_char();
        
        /* Determine which UART to use as the receiver for testing. UART4 or UART5
         * could be used. We'll use UART4 as long as it isn't used as the TERM_PORT.
         */
        if (TERM_PORT != UART4_BASE_PTR)
        {      
           rx_module = UART4_BASE_PTR;   // set the module pointer
           
           /* Configure NVIC to enable UART status interrupts for the receiver */
           enable_irq(53);
           
           printf("\nUsing UART4 on the daughter card as the receiver.");
           printf("\nConnect other end of blue wire to J13 pin 2 (UART4_RX)");
        }      
        else
        {      
           rx_module = UART5_BASE_PTR;   // set the module pointer
    
           /* Configure NVIC to enable UART status interrupts for the receiver */
           enable_irq(55);
    
           printf("\nUsing UART5 on the daughter card as the receiver.");
           printf("\nConnect other end of blue wire J9 pin 14 (UART5_RX)");
        }
    
        printf("\nPress any key when ready.\n");
        ch = in_char();
        
        printf("Setup complete. Starting LIN break detect test...\n");
        printf("This test should generate 2 LIN break detect interrupts.\n");
        
        /* Enable LIN break detection mode */
        UART_S2_REG(rx_module) |= UART_S2_LBKDE_MASK;
        
        /* Enable the LIN break detect interrupt */
        UART_BDH_REG(rx_module) |= UART_BDH_LBKDIE_MASK;
    
        /* Test sending a 10-bit break character. This should NOT generate an interrupt. */
        /* Set C2[SBK] bit to queue a break character for transmission */
        UART_C2_REG(tx_module) |= UART_C2_SBK_MASK; 
        
        /* Clear C2[SBK] so that only one break character is sent */
        UART_C2_REG(tx_module) &= ~UART_C2_SBK_MASK;
        
        /* Delay to allow time for interrupt */
        for( i=0; i < 0x1000; i++);    
        
        /* Test sending an 11-bit break character. This should generate an interrupt. */
        /* BRK13 = 0, M = 1, M10 = 0, PE = X  gives you a 11-bit break char */
        UART_C1_REG(tx_module) |= UART_C1_M_MASK;   
    
        /* Set C2[SBK] bit to queue a break character for transmission */
        UART_C2_REG(tx_module) |= UART_C2_SBK_MASK; 
        
        /* Clear C2[SBK] so that only one break character is sent */
        UART_C2_REG(tx_module) &= ~UART_C2_SBK_MASK;
    
        /* Delay to allow time for interrupt */
        for( i=0; i < 0x1000; i++);
        
        /* Configure the receiver for a 12-bit LIN break */
        UART_C1_REG(rx_module) |= UART_C1_M_MASK;
        
        /* Test sending an 11-bit break character. This should generate NOT an interrupt. */
        
        /* BRK13 = 0, M = 1, M10 = 0, PE = X  gives you a 11-bit break char */
        UART_C1_REG(tx_module) |= UART_C1_M_MASK;   
    
        /* Set C2[SBK] bit to queue a break character for transmission */
        UART_C2_REG(tx_module) |= UART_C2_SBK_MASK; 
        
        /* Clear C2[SBK] so that only one break character is sent */
        UART_C2_REG(tx_module) &= ~UART_C2_SBK_MASK;
    
        /* Delay to allow time for interrupt */
        for( i=0; i < 0x1000; i++);
    
    	
        /* Test sending a 12-bit break character. This should generate an interrupt. */
    
        /* BRK13 = 0, M = 1, M10 = 1, PE = 1  gives you a 12-bit break char */
        UART_C4_REG(tx_module) |= UART_C4_M10_MASK;   
        UART_C1_REG(tx_module) |= UART_C1_PE_MASK;   
    
        /* Set C2[SBK] bit to queue a break character for transmission */
        UART_C2_REG(tx_module) |= UART_C2_SBK_MASK; 
        
        /* Clear C2[SBK] so that only one break character is sent */
        UART_C2_REG(tx_module) &= ~UART_C2_SBK_MASK;
        
        /* Delay to allow time for interrupt */
        for( i=0; i < 0x1000; i++);    
        
        
        /* All tests complete. Return to default UART settings */
        UART_C1_REG(rx_module) &= ~UART_C1_M_MASK;
        UART_S2_REG(rx_module) &= ~UART_S2_LBKDE_MASK;
        UART_BDH_REG(rx_module) &= ~UART_BDH_LBKDIE_MASK;
        
        UART_C1_REG(tx_module) &= ~UART_C1_M_MASK;   
        UART_C4_REG(tx_module) &= ~UART_C4_M10_MASK;   
        UART_C1_REG(tx_module) &= ~UART_C1_PE_MASK;       
        
             
        printf("\nNumber of LIN breaks detected during test = %d\n", num_lin_breaks);
    
        return (2 - num_lin_breaks);
    }
    and the ISR
    uart_isr.c
    Code:
    void uart_status_handler(UART_MemMapPtr channel)
    {
        uint8 status, temp;
        
        /* Since the flag clearing mechanism will clear any flags in S1
         * that are set, we have to save off the value of the status register
         * and then check against the saved value to be able to detect all of
         * the flags that were set (if you read the status register over and 
         * over again, then you'll only capture the first one that was set.
         */
        
        /* Read and save the S1 value */
        status = UART_S1_REG(channel);
        
        printf("\nS1= 0x%02x",status);
    
        /* Check to see if the LIN break detect flag is set */
        if (UART_S2_REG(channel) & UART_S2_LBKDIF_MASK)
        {
            printf("\nUART LIN break detected.\n");
            num_lin_breaks++;
    
            /* Write 1 to flag to clear the flag */
            UART_S2_REG(channel) = UART_S2_LBKDIF_MASK;
        }
    }
    I didn't see what are different on my code or, what the UART init from Paul did different.
    Attached Files Attached Files

  12. #12
    Senior Member
    Join Date
    Apr 2013
    Posts
    127
    Deactivating the ILIE Idle Line Interrupt Enable does the trick

    This works
    Code:
    #define LBKDIE  0x80
    
    // Prints a binary number with leading zeros (Automatic Handling)
    #define PRINTBIN(Num) for (uint32_t t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num  & t ? '1' : '0');
    
    //Lin Initailisation
    #define linspeed                19200
    
    volatile int pointer = 0;
    
    void uart0isr_status() {
      uint8_t b;
      uint8_t status = UART0_S1;
    
      /* Check to see if the LIN break detect flag is set */
      if (UART0_S2 & UART_S2_LBKDIF) {
        pointer++;
        /* Write 1 to flag to clear the flag */
        UART0_S2 |= UART_S2_LBKDIF;
      }
    }
    
    void setup() {
      Serial.begin(115200);
      pinMode(19, OUTPUT);
      LinBUS_begin();
    }
    
    void loop() {
      Serial.print("UART0_C1 ");
      PRINTBIN(UART0_C1);
      
      Serial.print(" UART0_C2 ");
      PRINTBIN(UART0_C2);
      
      Serial.print(" UART0_S1 ");
      PRINTBIN(UART0_S1);
      
      Serial.print(" UART0_S2 ");
      PRINTBIN(UART0_S2);
      
      Serial.print(" UART0_BDH ");
      PRINTBIN(UART0_BDH);
      Serial.print(" ");
      
      Serial.println(pointer);
      delay(1000);
    }
    
    void LinBUS_begin(void) {
      Serial1.begin(linspeed);
      UART0_C2 &= ~UART_C2_ILIE;
      UART0_C1 &= ~UART_C1_ILT;
    
      attachInterruptVector(IRQ_UART0_STATUS, uart0isr_status);
    
    //  // 10 Bits transmitted
    //  UART0_S2 &= ~UART_S2_BRK13;
    //  UART0_C1 &= ~UART_C1_M;
    
    //  // 11 Bits transmitted
    //  UART0_S2 &= ~UART_S2_BRK13;
    //  UART0_C1 |= UART_C1_M;
    //  UART0_C4 &= ~UART_C4_M10;
    
    //  // 12 Bits transmitted
    //  UART0_S2 &= ~UART_S2_BRK13;
    //  UART0_C1 |= UART_C1_M;
    //  UART0_C4 |= UART_C4_M10;
    //  UART0_C1 |= UART_C1_PE;
    
      // 13 Bits transmitted
      UART0_S2 |= UART_S2_BRK13;
      UART0_C1 &= ~UART_C1_M;
    
    //  // 14 Bits transmitted
    //  UART0_S2 |= UART_S2_BRK13;
    //  UART0_C1 |= UART_C1_M;
      
      // Enable LinBreakdetection on UART0
      UART0_BDH |= LBKDIE;
      UART0_S2 |= UART_S2_LBKDE;
      NVIC_ENABLE_IRQ(IRQ_UART0_STATUS);
    }

  13. #13
    Senior Member
    Join Date
    Apr 2013
    Posts
    127
    But how do I get now my data after the break.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •