Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: Problems w/ UART

2004-10-08 by peterburdine

> OK, but where in the interrupt?
The first line of code that should always be executed.

> 
> No, switch does not work that way.  It is an exact match, not a bit 
> mask.  And having multiple bits set is not only possible but likely,
at the 
> very least TEMT and THRE are often on simultaneously.
> 
You are correct, I was just being stupid.

> > > This is potentially a problem.  I haven't looked at in detail but
> >you are
> > > using the same buffer routine here as you are in the non-interrupt
> > > code.  The ground is very unstable here.
> >I removed the vectored irq setup, still doesn't work.
> 
> This is not a matter of vectored or not.

If I removed the vectored setup, then there is only one interrupt left
 to call the isr, so there should not be a problem.


I gave up on that and started over, and this is what I think I am
doing.  I start by disabling all interrupts globally and for the uart.
 Then I enable only the RBR interrupt, then the uart vic.  In the main
I print out 123 by using a for loop as a delay.  I setup the rbr isr
to print out '!' if it receives a character.  Now the problem is when
I send 2 characters the processor resets.  Is there something wrong w/
my code?

#include <stdio.h>
#include "../ArmCommon/types.h"
#include "../ArmCommon/LPC22xx.h"
#include "../ArmCommon/LPC2294.h"

#define TX_BUFFER_LENGTH 64

static Uint16 txBytes = 0;
static Uint16 txRdPos = 0;
static Uint16 txWrPos = 0;
static Uint16 txBuffer[TX_BUFFER_LENGTH];

void uart0_config (void);
void uart0_isr (void);
void uart0_sendByte (Uint8);
int putchar(int);
int main (void);
Uint32 irqBackup;

void disableInterrupts (void);
void enableInterrupts (void);

void disableInterrupts (void) {
	irqBackup = VICIntEnable;
	VICIntEnable = 0;
}
void enableInterrupts (void) {
	VICIntEnable = irqBackup;
}

void uart0_config (void) {
	volatile Uint8 x;
	// Setup UART 0
	U0LCR = 0x80; // Enable DLAB
	U0DLL = 0x36; // Setup BGR
	U0DLM = 0x00; // ~57.6 kbps @ 50 Mhz
	U0LCR = 0x03; // Enable UART 0, 8 bits, no parity, 1 stop bit

	// Reset the FIFOs
	U0FCR = 0xC7; // RX FIFO trigger level 8 chars, reset tx and rx fifo,
enable fifos

	// Clear any old irqs
	x = U0LSR;
	x = U0RBR;
	x = U0IIR;
	
	// Setup Interrupts for UART0
	U0IER = 0x1; // Only RBR IRQ on
	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt
	VICVectAddr6 = (Uint32) uart0_isr;
	VICVectCntl6 = 0x20 | 6;
}

void uart0_isr (void) __irq {
	volatile Uint8 x;
	uart0_sendByte('!');

	// Clear IRQ
	x = U0LSR;
	x = U0IIR;
	x = U0RBR;	
	VICVectAddr = 0; 
}

void uart0_sendByte(Uint8 a) {
	// Wait until there is room in the buffer
	while(txBytes == TX_BUFFER_LENGTH);
	if(U0LSR&0x20) { // If the chip buffer is empty, put it there
		U0THR = a;
	}
	else { // Put in software buffer
		disableInterrupts();
		txBuffer[txWrPos] = a;
		txWrPos++;
		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
		txBytes++;
		enableInterrupts();
	}
}

int putchar(int a) {
	uart0_sendByte((int)a);
	return 0;
}

int main (void) {
	Uint16 x;
	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD;
	VPBDIV = 0x1;
	VICIntSelect = 0;	 // Only IRQs, no FIQs
	VICIntEnClr = 0xFFFFFFFF; // Disable all irqs
	uart0_config();
	// Proof that it can send more than one character
	printf("1");
	for(x = 0; x < 1000; x++);
	printf("2");
	for(x = 0; x < 1000; x++);
	printf("3");

	while(1);
}

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.