I'm just getting started with using the Keil uV3 compiler as well as the Phillips lpc2129. The application I am working on requires both UART0 & 1 as well as the I2C and I'm wondering if anyone has some <sample> code for enabling/using interrupts handy for this part that they might could pass along to help me get started. Any links related to writing C code for the lpc2129 would also be appreciated. regards & thanks -mel
The forum complained about the text being too long so I had to split it.... /******************************************************************************/ /* This file is part of the uVision/ARM development tools */ /* Copyright KEIL ELEKTRONIK GmbH 2002-2004 */ /******************************************************************************/ /* */ /* SERIAL.C: Low Level Serial Routines */ /* */ /******************************************************************************/ #include <LPC21xx.H> /* LPC21xx definitions */ #include <stdio.h> #include "serial.h" #define CR 0x0D extern int sendchar (int ch); /* in serial.c */ // // vars shared with the interrupt service routine // char tx0_buffer[1000]; volatile char *tx0_tail = tx0_buffer,*tx0_head = tx0_buffer; volatile unsigned int tx0_count = 0; void uart0 (void) __attribute__ ((interrupt)); // Generate Interrupt void puthexw (int hex) { puthex((hex >>12) & 0xf); puthex((hex >>8) & 0xf); puthex((hex >>4) & 0xf); puthex(hex & 0xf); } void puthex (int hex) { /* Write Hex Digit to Serial Port */ if (hex > 9) putchar('A' + (hex - 10)); else putchar('0' + hex); } void putstr (char *p) { /* Write string */ while (*p) { putchar (*p++); } } void init_serial(enum tBaudRate baud) { /* Initialize Serial Interface */ PINSEL0 = 0x00000005; /* Enable RxD0 and TxD0 */ U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ switch (baud) { case BR_1200: U0DLL = 0x0d; U0DLM = 0x03; break; case BR_2400: U0DLL = 0x86; U0DLM = 0x01; break; case BR_4800: U0DLL = 0xc3; U0DLM = 0x00; break; case BR_9600: U0DLL = 0x61; U0DLM = 0x00; break; case BR_19200: U0DLL = 0x30; U0DLM = 0x00; break; case BR_38400: U0DLL = 0x18; U0DLM = 0x00; break; } U0LCR = 0x03; /* DLAB = 0 */ //U0IER = 0x02; /* enable tx interrupts */ VICVectAddr1 = (unsigned long)uart0; // set interrupt vector in 1 VICVectCntl1 = 0x20 | 6; // use it for uart0 Interrupt VICIntEnable |= 0x00000040; // Enable Uart0 Interrupt } /* implementation of putchar (also used by printf function to output data) */ int sendchar (int ch) /* Write character to Serial Port */ { char tmp; if (ch == '\n') { tmp = CR; add_char_to_tx_buff(&tmp,1); } tmp = (char)ch; add_char_to_tx_buff(&tmp,1); return ch; } int putchar (int ch) /* Write character to Serial Port */ { char tmp; // if (ch == '\n') { // while (!(U0LSR & 0x20)); // U0THR = CR; /* output CR */ // } // while (!(U0LSR & 0x20)); // return (U0THR = ch); if (ch == '\n') { tmp = CR; add_char_to_tx_buff(&tmp,1); } tmp = (char)ch; add_char_to_tx_buff(&tmp,1); return ch; } int getchar (void) { /* Read character from Serial Port */ while (!(U0LSR & 0x01)); return (U0RBR); } // // inserts chars into the tx circular buffer. enables tx ints if required // count has the number of chars to insert // returns 0 if not enough space in the buffer // returns 1 if successful // char add_char_to_tx_buff(char *ch,int count) { if((tx0_count + count) >= sizeof(tx0_buffer) ) { return 0; // not enough space } VICIntEnClr = 0x00000040; // Disable Uart0 Interrupt if (tx0_head == tx0_tail) //if the buffer was empty { if (U0LSR & 0x20) //if the uart is EMPTY { U0IER = 0x02; // enable tx interrupts U0THR = *ch++; //send the first char out the UART count--; } } while (count!= 0) { *tx0_head++ = *ch++; //insert the char into the buffer if (tx0_head >= (tx0_buffer + sizeof(tx0_buffer)) ) { tx0_head = tx0_buffer; //wrap index if req'd } tx0_count++; count--; } VICIntEnable = 0x00000040; // Enable Uart0 Interrupt return 1; } // // uart0 isr routine // void uart0(void) { if (U0LSR & 0x20)//if tx interrupt { if (tx0_head == tx0_tail) //buffer empty? { U0IER &= ~0x02; //disable the tx interrupt } else //we have something to send { tx0_count--; U0THR = *tx0_tail++; if (tx0_tail >= (tx0_buffer + sizeof(tx0_buffer)) ) { tx0_tail = tx0_buffer; //wrap tail buffer } } } VICVectAddr = 0; // Acknowledge Interrupt } // end of file
Thanks for the code, for the most part what I came up with was (about) the same. I am not using printf and therefor have not added syscalls.c to my project. Also adding that file will require some work on my part as I have three different put/get-char calls (et al. putchar_uart0, putchar_uart1, putchar_i2c) but no get/put char as required in syscalls.c. My code is not performing correctly regarding the interrupts for uart1. I'll post the code here and also in a new thread for possible extra help. First of all, here is the main loop...
while(1) { cTemp = getchar_uart1(); if( cTemp ) putchar_uart1( cTemp ); cTemp = 0; }
void u1_interrupt (void) __attribute__ ((interrupt)); /* generate interrupt */ /*************************************************************************/ /************************** interrupt for uart1 ************************/ void u1_interrupt (void) { char intrpt; intrpt = U1IIR; /* reset U1IIR register */ // for now just trying to echo the Rx'd byte back out uart1... intrpt = U1RBR; // clear Rx buffer, and reset interrupt putchar_uart1( intrpt ); VICVectAddr = 0; /* acknowledge interrupt */ }/*end u1_interrupt() */ void init_uart1( void ) { PINSEL0 |= 0x00550000; /* set P0.8, P0.9, P0.10 and P0.11 as TxD1, RxD1, RTS1, CTS1 */ U1LCR = 0x83; /* set DLAB and word size (8bits), defaults for others yield */ /* no parity, one stop bit, and no break */ U1DLL = 0x61; /* yields 9600 Baud */ U1DLM = 0x00; /* explicit initialization - is also the default */ U1LCR &= 0x7f; /* clear DLAB */ /* set up the interrupts */ U1IER = 0x05; /* enable RBR and RLS interrupts */ VICVectAddr1 = (unsigned long) u1_interrupt; /* set interrupt vector */ VICVectCntl1 = 0x20 | 7; /* use VICVectAddr1 for UART1 interrupts */ VICIntEnable = 0x00000080; /* enable uart1 interrupts */ }/* end init_uart1()
I thought it worth mentioning that I can see the Rx Data Ready interrupt triggering when I am single stepping in the debug mode but flow does NOT jump it my ISR. also FYI: with regards to posting code... use the
</per> tags to retain formatting
"</per> tags to retain formatting" That should be < pre > (to start) and < /pre > (to end) - but without the extra spaces. It's clearly shown at the top of the form when you make a post!
excuse my typos... I got the first one correct which was why it wasn't displayed which is also why you put the spaces between the brackets (I hadn't thought of that either)