Problem s UART RxD u LPC2106
r.vanhara@post.cz
r.vanhara@post.cz
Úterý Únor 13 22:42:05 CET 2007
Ano, uklada se to do bufferu.
Kod je vytahnut z nejakeho projektu. Procital jsem to snad "tisickrat", zkousel jsem si napsat i vlastni, ale chova se to porad stejne.
Pokud jsem si vycital promenntou "uart0_rx_insert_idx", tak se po kazdem prichodu paketu jakekoliv delky inkrementuje pouze o 1 (mela by se inkrementovat o delku prichoziho paketu).
Prijde mi to spis, ze jsem nekde zapomel inicializovat nejaky registr....
Nebo nemuze to byt treba v nastaveni kompileru? Pouzivam Rowley.
Takto vypada Init + Interrupt:
void uart0Init(UINT16 baud, UINT8 mode, UINT8 fmode)
{
// set port pins for UART0
PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
U0IER = 0x00; // disable all interrupts
U0IIR; // clear interrupt ID
U0RBR; // clear receive register
U0LSR; // clear line status register
// set the baudrate
U0LCR = ULCR_DLAB_ENABLE; // select divisor latches
U0DLL = (UINT8)baud; // set for baud low byte
U0DLM = (UINT8)(baud >> 8); // set for baud high byte
// set the number of characters and other
// user specified operating parameters
U0LCR = (mode & ~ULCR_DLAB_ENABLE);
U0FCR = fmode;
// initialize the interrupt vector
VICIntSelect &= ~VIC_BIT(VIC_UART0); // UART0 selected as IRQ
VICIntEnable = VIC_BIT(VIC_UART0); // UART0 interrupt enabled
VICVectCntl0 = VIC_ENABLE | VIC_UART0;
VICVectAddr0 = (UINT32)uart0ISR; // address of the ISR
// initialize the transmit data queue
uart0_tx_extract_idx = uart0_tx_insert_idx = 0;
uart0_tx_running = 0;
// initialize the receive data queue
uart0_rx_extract_idx = uart0_rx_insert_idx = 0;
// enable receiver interrupts
U0IER = UIER_ERBFI;
}
void uart0ISR(void)
{
UINT8 iid;
// perform proper ISR entry so thumb-interwork works properly
ISR_ENTRY();
// loop until not more interrupt sources
while (((iid = U0IIR) & UIIR_NO_INT) == 0)
{
// identify & process the highest priority interrupt
switch (iid & UIIR_ID_MASK)
{
case UIIR_RLS_INT: // Receive Line Status
U0LSR; // read LSR to clear
break;
#ifdef UART0_RX_INT_MODE
case UIIR_CTI_INT: // Character Timeout Indicator
case UIIR_RDA_INT: // Receive Data Available
do
{
UINT16 temp;
// calc next insert index & store character
temp = (uart0_rx_insert_idx + 1) % UART0_RX_BUFFER_SIZE;
uart0_rx_buffer[uart0_rx_insert_idx] = U0RBR;
// check for more room in queue
if (temp != uart0_rx_extract_idx)
uart0_rx_insert_idx = temp; // update insert index
}
while (U0LSR & ULSR_RDR);
break;
#endif
#ifdef UART0_TX_INT_MODE
case UIIR_THRE_INT: // Transmit Holding Register Empty
while (U0LSR & ULSR_THRE)
{
// check if more data to send
if (uart0_tx_insert_idx != uart0_tx_extract_idx)
{
U0THR = uart0_tx_buffer[uart0_tx_extract_idx++];
uart0_tx_extract_idx %= UART0_TX_BUFFER_SIZE;
}
else
{
// no
uart0_tx_running = 0; // clear running flag
break;
}
}
break;
#endif // UART0_TX_INT_MODE
default: // Unknown
U0LSR;
U0RBR;
break;
}
}
VICVectAddr = 0x00000000; // clear this interrupt from the VIC
ISR_EXIT(); // recover registers and return
}
Další informace o konferenci Hw-list