; Copyright 2009 Castle Technology Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; EXPORT HAL_UARTPorts EXPORT HAL_UARTStartUp EXPORT HAL_UARTShutdown EXPORT HAL_UARTFeatures EXPORT HAL_UARTReceiveByte EXPORT HAL_UARTTransmitByte EXPORT HAL_UARTLineStatus EXPORT HAL_UARTInterruptEnable EXPORT HAL_UARTRate EXPORT HAL_UARTFormat EXPORT HAL_UARTFIFOSize EXPORT HAL_UARTFIFOClear EXPORT HAL_UARTFIFOEnable EXPORT HAL_UARTFIFOThreshold EXPORT HAL_UARTInterruptID EXPORT HAL_UARTBreak EXPORT HAL_UARTModemControl EXPORT HAL_UARTModemStatus EXPORT HAL_UARTDevice GET Hdr:ListOpts GET Hdr:Macros GET Hdr:System GET Hdr:Machine.<Machine> GET Hdr:ImageSize.<ImageSize> GET Hdr:Proc GET Hdr:OSEntries GET hdr.omap3530 GET hdr.StaticWS GET hdr.UART ; Put base address into the a1, given port number in a1 MACRO BaseAddr ADD a1, sb, a1, LSL #2 LDR a1, [a1, #BoardConfig_HALUART] MEND AREA |Asm$$Code|, CODE, READONLY, PIC ; int Ports(void) ; ; Return array of UART port physical addresses. ; HAL_UARTPorts LDRB a1, [sb, #BoardConfig_NumUART] MOV pc, lr ; void Shutdown(int port) ; HAL_UARTShutdown ; Just reuse the startup code ; void StartUp(int port) ; HAL_UARTStartUp ADD a3, sb, a1 BaseAddr ; Perform soft reset MOV a2, #2 STRB a2, [a1, #UART_SYSC] 10 LDRB a2, [a1, #UART_SYSS] TST a2, #1 BEQ %BT10 ; Autoidle, smart idle MOV a2, #1+(2<<3) STRB a2, [a1, #UART_SYSC] MOV a2, #0 STRB a2, [a3, #:INDEX:UARTFCRSoftCopy] MOV a2, #OUT2 STRB a2, [a1, #UART_MCR] MOV a2, #WLS_8 STRB a2, [a1, #UART_LCR] MOV pc, lr ; int Features(int port) ; ; Bit 0: FIFOs available ; Bit 1: DMA available ; Bit 2: Modem lines available ; HAL_UARTFeatures MOV a1, #2_101 MOV pc, lr ; int ReceiveByte(int port, int *status) ; ; Returns the next byte from the FIFO (if enabled) or the holding register. ; If status is non-NULL, the line status associated with the byte is ; read (see LineStatus). The return value is only meaningful if a ; received byte is available (bit 0 of *status will be set). ; HAL_UARTReceiveByte BaseAddr TEQ a2, #0 LDRNEB a3, [a1, #UART_LSR] ; Read int state if returning status LDRB a1, [a1, #UART_RBR] STRNE a3, [a2] MOV pc, lr ; void TransmitByte(int port, int byte) ; HAL_UARTTransmitByte BaseAddr STRB a2, [a1, #UART_THR] MOV pc, lr ; int LineStatus(int port) ; ; Bit 0: Receiver Data Ready ; Bit 1: Overrun Error ; Bit 2: Parity Error ; Bit 3: Framing Error ; Bit 4: Break Error ; Bit 5: Transmitter Holding Register Empty ; Bit 6: Transmitter Empty (including FIFO) ; Bit 7: FIFO contains a Parity, Framing or Break error ; ; Parity, Framing and Break errors are associated with each byte received. ; Whether the values reported here are associated with the last byte ; read using ReceiveByte or with the next byte to be read is undefined. ; You should request the status using ReceiveByte to ensure accurate ; identification of bytes with errors. ; ; Error bits are cleared whenever status is read, using either LineStatus ; or ReceiveByte with status non-NULL. ; HAL_UARTLineStatus BaseAddr LDRB a1, [a1, #UART_LSR] MOV pc, lr ; int InterruptEnable(int port, int eor, int mask) ; ; Enables interrupts. Bits are: ; ; Bit 0: Received Data Available (and Character Timeout) ; Bit 1: Transmitter Holding Register Empty ; Bit 2: Received Line Status ; Bit 3: Modem Status ; ; Returns previous state. ; HAL_UARTInterruptEnable BaseAddr PHPSEI ip, a4 LDRB a4, [a1, #UART_IER] AND a3, a4, a3 EOR a3, a2, a3 STRB a3, [a1, #UART_IER] PLP ip MOV a1, a4 MOV pc, lr ; int Rate(int port, int baud16) ; ; Sets the rate, in units of 1/16 of a baud. Returns the previous rate. ; Use -1 to read. ; HAL_UARTRate Entry "v1,v3" BaseAddr PHPSEI ip, a4 MOV v1, #7 STRB v1, [a1, #UART_MDR1] ; Disable UART LDRB v3, [a1, #UART_LCR] ORR a4, v3, #DLAB ; Access divisor latch registers STRB a4, [a1, #UART_LCR] LDRB a3, [a1, #UART_DLL] ; Read the current baud rate LDRB a4, [a1, #UART_DLM] LDR v1, =UARTCLK ADDS a4, a3, a4, LSL#8 BEQ %FT05 ; Skip divide if no baud programmed yet DivRem a3, v1, a4, lr ; a3 now contains baud rate * 16 CMP v1, a4, LSR#1 ; If the remainder is greater than 1/2 ADDGE a3, a3, #1 ; the divisor, round up 05 CMN a2, #1 ; Don't write if we're reading! BEQ %FT10 ; We need to program 48MHz / (16 * baud rate) LDR v1, =UARTCLK ; This was corrupted by the above DIVREM DivRem a4, v1, a2, lr CMP v1, a2, LSR#1 ; If the remainder is greater than 1/2 ADDGE a4, a4, #1 ; the divisor, round up STRB a4, [a1, #UART_DLL] MOV a4, a4, LSR#8 STRB a4, [a1, #UART_DLM] 10 STRB v3, [a1, #UART_LCR] ; Turn off divisor latch access MOV v3, #0 STRB v3, [a1, #UART_MDR1] ; Restart UART MOV a1, a3 ; Return previous state PLP ip EXIT ; int Format(int port, int format) ; ; Bits 0-1: Bits per word 0=>5, 1=>6, 2=>7, 3=>8 ; Bit 2: Stop length 0=>1, 1=>2 (1.5 if 5 bits) ; Bit 3: Parity enabled ; Bits 4-5: Parity: 0 => Odd (or disabled) ; 1 => Even ; 2 => Mark (parity bit = 1) ; 3 => Space (parity bit = 0) ; ; Returns previous format. -1 to read. ; HAL_UARTFormatMask * SPA+EPS+PEN+STP+WLS HAL_UARTFormat BaseAddr PHPSEI ip, a3 LDRB a3, [a1, #UART_LCR] CMP a2, #-1 AND a4, a3, #HAL_UARTFormatMask ; a4 = relevant bits of current LCR BIC a3, a3, #HAL_UARTFormatMask ; a3 = other bits of current LCR ANDNE a2, a2, #HAL_UARTFormatMask ; a2 = relevant bits on entry ORRNE a2, a2, a3 STRNEB a2, [a1, #UART_LCR] PLP ip MOV a1, a4 MOV pc, lr ; void FIFOSize(int port, int *rx, int *tx) ; ; Returns the size of the RX and TX FIFOs. Either parameter may be NULL. ; Note that the size of the TX FIFO is the total amount of data that can ; be sent immediately when the Transmitter Holding Register Empty ; status holds. (So an unusual UART that had a transmit threshold ; should return total FIFO size minus threshold). ; HAL_UARTFIFOSize BaseAddr MOV a1, #64 TEQ a2, #0 STRNE a1, [a2] TEQ a3, #0 STRNE a1, [a3] MOV pc, lr ; void FIFOClear(int port, int flags) ; ; Clears the input FIFO (if bit 0 set) and the output FIFO (if bit 1 set). ; HAL_UARTFIFOClear ADD a4, sb, a1 BaseAddr AND a2, a2, #2_11 PHPSEI ip, a3 LDRB a3, [a4, #:INDEX:UARTFCRSoftCopy] ORR a3, a3, a2, LSL #1 STRB a3, [a1, #UART_FCR] PLP ip MOV pc, lr ; int FIFOEnable(int port, int enable) ; ; Enables or disables the RX and TX FIFOs: 0 => disable, 1 => enable ; -1 => read status. Returns previous status. ; HAL_UARTFIFOEnable Entry "v1-v2" ADD v1, sb, a1 BaseAddr PHPSEI ip, a3 LDRB a3, [v1, #:INDEX:UARTFCRSoftCopy] ASSERT FIFOEN=1 AND a4, a3, #FIFOEN CMP a2, #-1 BEQ %FT10 CMP a2, #0 BICEQ a2, a3, #FIFOEN ORRNE a2, a3, #FIFOEN CMP a2, a3 BEQ %FT10 ; Must disable the baud clock to flush the FIFO STRB a2, [v1, #:INDEX:UARTFCRSoftCopy] MOV lr, #7 STRB lr, [a1, #UART_MDR1] ; Disable UART LDRB v2, [a1, #UART_LCR] ORR a3, v2, #DLAB ; Access divisor latch registers STRB a3, [a1, #UART_LCR] LDRB a3, [a1, #UART_DLL] ; Read the current baud rate LDRB v1, [a1, #UART_DLM] MOV lr, #0 STRB lr, [a1, #UART_DLL] ; Stop the clock STRB lr, [a1, #UART_DLM] STRB a2, [a1, #UART_FCR] ; Configure FIFO STRB a3, [a1, #UART_DLL] ; Restart clock STRB v1, [a1, #UART_DLM] STRB v2, [a1, #UART_LCR] ; Restore operational mode STRB lr, [a1, #UART_MDR1] ; Restart UART 10 MOV a1, a4 PLP ip EXIT ; int FIFOThreshold(int port, int threshold) ; ; Sets the receive threshold level for the FIFO RX interrupt. For OMAP3530 ; this is 8, 16, 56 or 60 bytes. Returns previous value. -1 to read. ; HAL_UARTFIFOThreshold Entry "v1" ADD v1, sb, a1 BaseAddr PHPSEI ip, a3 LDRB a3, [v1, #:INDEX:UARTFCRSoftCopy] ANDS a4, a3, #FIFOTHR BIC a3, a3, #FIFOTHR ASSERT FIFOTHR_8 = 0 MOVEQ a4, #8 BEQ %FT10 CMP a4, #FIFOTHR_56 MOVLO a4, #16 MOVEQ a4, #56 MOVHI a4, #60 10 CMP a2, #-1 BEQ %FT20 CMP a2, #16 ADDGE a3, a3, #FIFOTHR_16 CMP a2, #56 ADDGE a3, a3, #FIFOTHR_56-FIFOTHR_16 CMP a2, #60 ADDGE a3, a3, #FIFOTHR_60-FIFOTHR_56 STRB a3, [a1, #UART_FCR] STRB a3, [v1, #:INDEX:UARTFCRSoftCopy] 20 MOV a1, a4 PLP ip EXIT ; int InterruptID(int port) ; ; Returns the highest priority interrupt currently asserted. In order ; of priority: ; ; 3 => Receiver Line Status (Cleared by ReceiveByte) ; 2 => Received Data Available (Cleared by reading enough data) ; 6 => Character Timeout (received data waiting) ; 1 => Transmitter Holding Register Empty (Cleared by this call) ; 0 => Modem Status (Cleared by ModemStatus) ; -1 => No Interrupt ; ; The Modem Status interrupt occurs when the CTS, DSR or DCD inputs ; change, or when RI goes from high to low (ie bits 0 to 3 of ModemStatus ; are set). ; HAL_UARTInterruptID BaseAddr LDRB a4, [a1, #UART_IIR] TST a4, #1 MOVEQ a1, a4, LSR #1 ANDEQ a1, a1, #7 MOVNE a1, #-1 MOV pc, lr ; int Break(int port, int enable) ; ; Activates (1) or deactivates (0) a break condition. -1 to read, ; returns previous state. ; HAL_UARTBreak BaseAddr PHPSEI ip, a3 LDRB a3, [a1, #UART_LCR] ANDS a4, a3, #BCR MOVNE a4, #1 CMP a2, #-1 BEQ %FT10 CMP a2, #0 BICEQ a3, a3, #BCR ORRNE a3, a3, #BCR STRB a3, [a1, #UART_LCR] 10 MOV a1, a4 PLP ip MOV pc, lr ; int ModemControl(int port, int eor, int mask) ; ; Modifies the modem control outputs. ; ; Bit 0: DTR ; Bit 1: RTS ; ; Note that these are logical outputs, although the physical pins may be ; inverted. So 1 indicates a request to send. Returns previous state. ; Needs to clear the modem interrupt status. ; HAL_UARTModemControl BaseAddr PHPSEI ip, a4 LDRB a4, [a1, #UART_MCR] CMP a2, #-1 ORR a3, a3, #256-(DTR+RTS) ; Only allow DTR+RTS to be modified AND a2, a2, #DTR+RTS ANDNE a3, a3, a4 EORNE a3, a3, a2 STRNEB a3, [a1, #UART_MCR] PLP ip AND a1, a4, #DTR+RTS MOV pc, lr ; int ModemStatus(int port) ; ; Reads the modem status inputs. ; ; Bit 0: CTS changed since last call ; Bit 1: DSR changed since last call ; Bit 2: RI changed from high to low since last call ; Bit 3: DCD changed since last call ; Bit 4: CTS ; Bit 5: DSR ; Bit 6: RI ; Bit 7: DCD ; ; Note that these are logical inputs, although the physical pins may be ; inverted. So 1 indicates a Clear To Send condition. This must also clear ; the modem interrupt status. ; HAL_UARTModemStatus BaseAddr LDRB a1, [a1, #UART_MSR] MOV pc, lr ; int Device(int port) ; ; Return the device number allocated to the UART port ; HAL_UARTDevice ADD a1, sb, a1 LDRB a1, [a1, #BoardConfig_HALUARTIRQ] MOV pc, lr END