; 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. ; ; This is currently set up to provide only 1 serial port - UART3 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 $label BaseAddr LDR a1, L4_UART3_Log MEND AREA |Asm$$Code|, CODE, READONLY, PIC ; int Ports(void) ; ; Return array of UART port physical addresses. ; HAL_UARTPorts MOV a1, #1 MOV pc, lr ; void StartUp(int port) ; HAL_UARTStartUp BaseAddr MOV a2, #0 STRB a2, [a1, #UART_IER] STRB a2, [a1, #UART_FCR] STRB a2, UARTFCRSoftCopy MOV a2, #OUT2 STRB a2, [a1, #UART_MCR] MOV a2, #WLS_8 STRB a2, [a1, #UART_LCR] MOV pc, lr ; void Shutdown(int port) ; HAL_UARTShutdown BaseAddr MOV a2, #0 STRB a2, [a1, #UART_IER] STRB a2, [a1, #UART_FCR] STRB a2, [a1, #UART_MCR] 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 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 ADD a4, a3, a4, LSL#8 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 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 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 BaseAddr AND a2, a2, #2_11 PHPSEI ip, a3 LDRB a3, 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 BaseAddr PHPSEI ip, a3 LDRB a3, UARTFCRSoftCopy ASSERT FIFOEN=1 AND a4, a3, #FIFOEN CMP a2, #-1 BEQ %FT10 CMP a2, #0 BICEQ a3, a3, #FIFOEN ORRNE a3, a3, #FIFOEN STRB a3, [a1, #UART_FCR] STRB a3, UARTFCRSoftCopy 10 MOV a1, a4 PLP ip MOV pc, lr ; 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 BaseAddr PHPSEI ip, a3 LDRB a3, 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, UARTFCRSoftCopy 20 MOV a1, a4 PLP ip MOV pc, lr ; 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, a3 LDRB a3, [a1, #UART_MCR] CMP a2, #-1 AND a4, a3, #DTR+RTS ; a4 = relevant bits of current MCR BIC a3, a3, #DTR+RTS ; a3 = other bits of current MCR ANDNE a2, a2, #DTR+RTS ; a2 = relevant bits on entry ORRNE a2, a2, a3 STRNEB a2, [a1, #UART_MCR] PLP ip MOV a1, a4 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 MOV a1, #74 MOV pc, lr END