 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		Hi,
So I also met the problem: with PL011 I have to write some bytes into the TX FIFO and then the TX interrupt can be triggered. Otherwise, the interrupt cannot be triggered. But on LPC55S69, the interrupt can be triggered directly.
What's the final explanation for this issue?
Thanks,
Sherry
 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		| See Post 9, 2nd paragraph. | 
| movsr12, 0; initially, turn off the THRE mask ;---------------------------------------; 0:ldrr0, [r3, uStatus]; check status flags bicsr0, r12; but mask unwanted bits | 
| r0=r0 AND NOT(r12)=r0 AND NOT(0)=r0 AND 0xffffffff fffffff=r0 | 
 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		| if (THRE bit) | 
 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		| ;-----------------------------------------------------------------------! ; Sio IrqHandler! ;-----------------------------------------------------------------------! fn UioIrq0 movsr0, 0; channel 0 b.nUioIrqHandler; fe UioIrq0 etc. ;-----------------------------------------------------------------------! ; Sio IrqHandler! ;-----------------------------------------------------------------------! fn UioIrqHandler adrr3, sioTbl; get channel specific details addsr3, r3, r0, lsl 5; tbl+channel*32 ldrr2, [r3, 28]; get ucb ldrr3, [r3, 0]; get peripheral base addr movsr12, 0; initially, turn off the THRE mask ;---------------------------------------; 0:ldrr0, [r3, uStatus]; check status flags bicsr0, r12; but mask unwanted bits ldrr1, [r3, uIntID]; read interrupt status register tstr0, (1<<0); rxRdy bne20f; yup tstr0, (1<<5); txRdy beq9f; nope -- ignore line status ;---------------------------------------; ; transmit next character; ;---------------------------------------; 10:ldrr1, [r2, uTxHead]; head offset ldrr0, [r2, uTxTail]; tail offset cmpr0, r1; any more to xmit? bne12f; yup ;---------------------------------------; 11:ldrr0, [r3, uIrqEnable]; no more chars bicsr0, (1<<1); disable TxRdy strr0, [r3, uIrqEnable]; movsr12, (1<<5); and set mask also b0b; see if more to do ;---------------------------------------; 12:ldrr0, [r2, uTxBase]; buffer base addr ldrbr0, [r0, r1]; get next char strr0, [r3, uTxChar]; xmit addsr1, 1; bump movwr0, txBfSz-1; with wrap andsr1, r0; strr1, [r2, uTxHead]; update head b0b; see if more to do ;---------------------------------------; ; character received; ;---------------------------------------; 20:ldrr1, [r2, uRxBase]; buffer base addr ldrr0, [r2, uRxTail]; tail offset addsr1, r0; now a pointer ldrr0, [r3, uRxChar]; get the character strbr0, [r1]; stash ldrr0, [r2, uRxTail]; tail offset addsr0, 1; bump movwr1, rxBfSz-1; wrap factor andsr0, r1; with wrap strr0, [r2, uRxTail]; update tail b0b; see if more to do ;---------------------------------------; 9:bxlr; return fe UioIrqHandler | 
 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		| 
UxPutBlock(uchar *p, ulong n)
{
  for (; n--; )
  {
    *UxTxBuf++ = *p++; //NB: handle ring buffer wrap
    bufTail++;  // With wrap
  }
  UARTn->IER |= 0x02; // I.e THRE interrupt enable
  NVIC->STIR = ??;  // UARTn periheral ID (5/6/7/8/35 for UARTS 0/1/2/3/4; see UM)
  // This is key!
}
UxIRQ
{
  ...
  if (THRE bit)
  {
    if (head = tail) // all sent?
      UARTn->IER &= ~THREIE;
    else
    {
      ch = *buff+head;
      head ++;
      UARTn->THR = ch;
    }
  }
...
}
 | 
 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		| THRE =11100111111111111 THREIE=00011111111110000 TXD =11111SBBBBBBP1111 ^ ^ ^ a b c | 
| 
void 
uart_putchar(UART *uart, unsigned char c)
{
uint32_t ier = uart->hw->IER;
if (ier & UART_IER_THREINT) {  /* Interrupt enabled */
FIFO_Push(c);
uart->hw->IER |= UART_IER_THREINT;  /* Enable interrupt */
} else {
uart->hw->THR = c;
uart->hw->IER |= UART_IER_THREINT;  /* Enable interrupt */
}
}
 | 
 
					
				
		
 lpcware
		
			lpcware
		
		
		
		
		
		
		
		
	
			
		
		
			
					
		| if (!UART_TxFifo_Full(pUart)) pUart->THR = c; | 
| 
/* Fill FIFO until full or until TX ring buffer is empty */
while ((Chip_UART_ReadLineStatus(pUART) & UART_LSR_THRE) != 0 &&
   RingBuffer_Pop(pRB, &ch)) {
Chip_UART_SendByte(pUART, ch);
}
 | 
