-/* $Id$ */\r
-/*\r
- * Copyright (c) 2005 Arched Rock Corporation \r
- * All rights reserved. \r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are\r
- * met:\r
- * Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * \r
- * Neither the name of the Arched Rock Corporation nor the names of its\r
- * contributors may be used to endorse or promote products derived from\r
- * this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARCHED\r
- * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\r
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\r
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\r
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
- * DAMAGE.\r
- */\r
-/*\r
- * Intel Open Source License\r
- *\r
- * Copyright (c) 2002 Intel Corporation\r
- * All rights reserved.\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are\r
- * met:\r
- *\r
- * Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * Neither the name of the Intel Corporation nor the names of its\r
- * contributors may be used to endorse or promote products derived from\r
- * this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- *\r
- */\r
-/**\r
- * Implements the UartByte, UartStream and HalPXA27xSerialPacket interface \r
- * for a PXA27x UART. \r
- * \r
- *\r
- * @param defaultRate Default baud rate for the serial port. \r
- *\r
- *\r
- * @author Phil Buonadonna\r
- */\r
-\r
-#include "pxa27x_serial.h"\r
-\r
-generic module HalPXA27xSerialP(uint32_t defaultRate)\r
-{\r
- provides {\r
- interface Init;\r
- interface StdControl;\r
- interface UartByte;\r
- interface UartStream;\r
- interface HalPXA27xSerialPacket;\r
- interface HalPXA27xSerialCntl;\r
- }\r
- uses {\r
- interface Init as UARTInit;\r
- interface HplPXA27xUART as UART;\r
- interface HplPXA27xDMAChnl as RxDMA;\r
- interface HplPXA27xDMAChnl as TxDMA;\r
- interface HplPXA27xDMAInfo as UARTRxDMAInfo;\r
- interface HplPXA27xDMAInfo as UARTTxDMAInfo;\r
- }\r
-}\r
-\r
-implementation \r
-{\r
-\r
- uint8_t *txCurrentBuf, *rxCurrentBuf;\r
- uint32_t txCurrentLen, rxCurrentLen, rxCurrentIdx;\r
- uint32_t gulFCRShadow;\r
- bool gbUsingUartStreamSendIF = FALSE;\r
- bool gbUsingUartStreamRcvIF = FALSE;\r
- bool gbRcvByteEvtEnabled = TRUE;\r
-\r
- command error_t Init.init() {\r
- error_t error = SUCCESS;\r
-\r
- atomic {\r
- call UARTInit.init();\r
- txCurrentBuf = rxCurrentBuf = NULL;\r
- gbUsingUartStreamSendIF = FALSE;\r
- gbUsingUartStreamRcvIF = FALSE;\r
- gbRcvByteEvtEnabled = TRUE;\r
- gulFCRShadow = (FCR_TRFIFOE | FCR_ITL(0)); // FIFO Mode, 1 byte Rx threshold\r
- }\r
- call TxDMA.setMap(call UARTTxDMAInfo.getMapIndex());\r
- call RxDMA.setMap(call UARTRxDMAInfo.getMapIndex());\r
- call TxDMA.setDALGNbit(TRUE);\r
- call RxDMA.setDALGNbit(TRUE);\r
-\r
- error = call HalPXA27xSerialCntl.configPort(defaultRate,8,NONE,1,FALSE);\r
- \r
- atomic {call UART.setFCR(gulFCRShadow);}\r
- return error;\r
- }\r
-\r
- command error_t StdControl.start() {\r
- atomic {\r
- call UART.setIER(IER_UUE | IER_RAVIE);\r
- }\r
- return SUCCESS;\r
- }\r
-\r
- command error_t StdControl.stop() {\r
- atomic {\r
- call UART.setIER(0);\r
- }\r
- return SUCCESS;\r
- }\r
-\r
- async command error_t UartByte.send(uint8_t data) {\r
- atomic call UART.setTHR(data);\r
- while ((call UART.getLSR() & LSR_TEMT) == 0);\r
- return SUCCESS;\r
- }\r
-\r
- async command error_t UartByte.receive( uint8_t *data, uint8_t timeout) {\r
- error_t error = FAIL;\r
- uint8_t t;\r
- for (t = 0; t < timeout; t++) {\r
- if (call UART.getLSR() & LSR_DR) {\r
- *data = call UART.getRBR();\r
- error = SUCCESS;\r
- break;\r
- }\r
- }\r
- return error;\r
- }\r
-\r
- async command error_t UartStream.send( uint8_t* buf, uint16_t len ) {\r
- error_t error;\r
- atomic gbUsingUartStreamSendIF = TRUE;\r
- error = call HalPXA27xSerialPacket.send(buf,len);\r
- if (error) {\r
- atomic gbUsingUartStreamSendIF = FALSE;\r
- }\r
- return error;\r
- }\r
-\r
-\r
- async command error_t UartStream.enableReceiveInterrupt() {\r
- error_t error = SUCCESS;\r
- atomic {\r
- if (rxCurrentBuf == NULL) {\r
- call UART.setIER(call UART.getIER() | IER_RAVIE);\r
- }\r
- gbRcvByteEvtEnabled = TRUE;\r
- }\r
- return SUCCESS;\r
- }\r
-\r
- async command error_t UartStream.disableReceiveInterrupt() {\r
- atomic {\r
- // Check to make sure a short stream/packet call isn't in progress\r
- if ((rxCurrentBuf == NULL) || (rxCurrentLen >= 8)) {\r
- call UART.setIER(call UART.getIER() & ~IER_RAVIE);\r
- }\r
- gbRcvByteEvtEnabled = FALSE;\r
- }\r
- return SUCCESS;\r
- }\r
-\r
- async command error_t UartStream.receive( uint8_t* buf, uint16_t len ) {\r
- error_t error;\r
- atomic gbUsingUartStreamRcvIF = TRUE;\r
- error = call HalPXA27xSerialPacket.receive(buf,len,0);\r
- if (error) {\r
- atomic gbUsingUartStreamRcvIF = FALSE;\r
- }\r
- return error;\r
- }\r
- \r
- async command error_t HalPXA27xSerialPacket.send(uint8_t *buf, uint16_t len) {\r
- uint32_t txAddr;\r
- uint32_t DMAFlags;\r
- error_t error = SUCCESS;\r
-\r
- atomic {\r
- if (txCurrentBuf == NULL) {\r
- txCurrentBuf = buf;\r
- txCurrentLen = len;\r
- }\r
- else {\r
- error = FAIL;\r
- }\r
- }\r
-\r
- if (error) \r
- return error;\r
- \r
- if (len < 8) {\r
- uint16_t i;\r
- // Use PIO. Invariant: FIFO is empty\r
- atomic {\r
- gulFCRShadow |= FCR_TIL;\r
- call UART.setFCR(gulFCRShadow); \r
- }\r
- for (i = 0;i < len;i++) {\r
- call UART.setTHR(buf[i]);\r
- }\r
- atomic call UART.setIER(call UART.getIER() | IER_TIE);\r
- }\r
- else {\r
- // Use DMA\r
- DMAFlags = (DCMD_FLOWTRG | DCMD_BURST8 | DCMD_WIDTH1 | DCMD_ENDIRQEN\r
- | DCMD_LEN(len) );\r
- \r
- txAddr = (uint32_t) buf;\r
- DMAFlags |= DCMD_INCSRCADDR;\r
- \r
- call TxDMA.setDCSR(DCSR_NODESCFETCH);\r
- call TxDMA.setDSADR(txAddr);\r
- call TxDMA.setDTADR(call UARTTxDMAInfo.getAddr());\r
- call TxDMA.setDCMD(DMAFlags);\r
- \r
- atomic {\r
- call UART.setIER(call UART.getIER() | IER_DMAE);\r
- }\r
-\r
- call TxDMA.setDCSR(DCSR_RUN | DCSR_NODESCFETCH);\r
- }\r
- return error;\r
- }\r
-\r
-\r
- async command error_t HalPXA27xSerialPacket.receive(uint8_t *buf, uint16_t len, \r
- uint16_t timeout) {\r
- uint32_t rxAddr;\r
- uint32_t DMAFlags;\r
- error_t error = SUCCESS;\r
-\r
- atomic {\r
- if (rxCurrentBuf == NULL) {\r
- rxCurrentBuf = buf;\r
- rxCurrentLen = len;\r
- rxCurrentIdx = 0;\r
- }\r
- else {\r
- error = FAIL;\r
- }\r
- }\r
-\r
- if (error) \r
- return error;\r
-\r
- if (len < 8) {\r
- // Use PIO. Invariant: FIFO is empty\r
- atomic {\r
- gulFCRShadow = ((gulFCRShadow & ~(FCR_ITL(3))) | FCR_ITL(0));\r
- call UART.setFCR(gulFCRShadow); \r
- call UART.setIER(call UART.getIER() | IER_RAVIE);\r
- }\r
- }\r
- else {\r
- // Use DMA\r
- DMAFlags = (DCMD_FLOWSRC | DCMD_BURST8 | DCMD_WIDTH1 | DCMD_ENDIRQEN\r
- | DCMD_LEN(len) );\r
- \r
- rxAddr = (uint32_t) buf;\r
- DMAFlags |= DCMD_INCTRGADDR;\r
- \r
- call RxDMA.setDCSR(DCSR_NODESCFETCH);\r
- call RxDMA.setDTADR(rxAddr);\r
- call RxDMA.setDSADR(call UARTRxDMAInfo.getAddr());\r
- call RxDMA.setDCMD(DMAFlags);\r
-\r
- atomic {\r
- gulFCRShadow = ((gulFCRShadow & ~(FCR_ITL(3))) | FCR_ITL(1));\r
- call UART.setFCR(gulFCRShadow); \r
- call UART.setIER((call UART.getIER() & ~IER_RAVIE) | IER_DMAE);\r
- }\r
-\r
- call RxDMA.setDCSR(DCSR_RUN | DCSR_NODESCFETCH);\r
- }\r
- return error;\r
- }\r
- \r
- void DispatchStreamRcvSignal() {\r
- uint8_t *pBuf = rxCurrentBuf;\r
- uint16_t len = rxCurrentLen;\r
- rxCurrentBuf = NULL;\r
- if (gbUsingUartStreamRcvIF) {\r
- gbUsingUartStreamRcvIF = FALSE;\r
- signal UartStream.receiveDone(pBuf, len, SUCCESS);\r
- }\r
- else {\r
- pBuf = signal HalPXA27xSerialPacket.receiveDone(pBuf, len, SUCCESS);\r
- if (pBuf) {\r
- call HalPXA27xSerialPacket.receive(pBuf,len,0);\r
- }\r
- }\r
- return;\r
- }\r
-\r
- void DispatchStreamSendSignal() {\r
- uint8_t *pBuf = txCurrentBuf;\r
- uint16_t len = txCurrentLen;\r
- txCurrentBuf = NULL;\r
- if (gbUsingUartStreamSendIF) {\r
- gbUsingUartStreamSendIF = FALSE;\r
- signal UartStream.sendDone(pBuf, len, SUCCESS);\r
- }\r
- else {\r
- pBuf = signal HalPXA27xSerialPacket.sendDone(pBuf, len, SUCCESS);\r
- if (pBuf) {\r
- call HalPXA27xSerialPacket.send(pBuf,len);\r
- }\r
- }\r
- return;\r
- }\r
-\r
- async event void RxDMA.interruptDMA() {\r
- call RxDMA.setDCMD(0);\r
- call RxDMA.setDCSR(DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR);\r
- DispatchStreamRcvSignal();\r
- if (gbRcvByteEvtEnabled) \r
- call UART.setIER(call UART.getIER() | IER_RAVIE);\r
- return;\r
- }\r
-\r
- async event void TxDMA.interruptDMA() {\r
- call TxDMA.setDCMD(0);\r
- call TxDMA.setDCSR(DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR);\r
- DispatchStreamSendSignal();\r
- return;\r
- }\r
-\r
-\r
- async command error_t HalPXA27xSerialCntl.configPort(uint32_t baudrate, \r
- uint8_t databits, \r
- uart_parity_t parity, \r
- uint8_t stopbits, \r
- bool flow_cntl) {\r
- uint32_t uiDivisor;\r
- uint32_t valLCR = 0;\r
- uint32_t valMCR = MCR_OUT2;\r
- \r
- uiDivisor = 921600/baudrate;\r
- // Check for invalid baud rate divisor value.\r
- // XXX - Eventually could use '0' to imply auto rate detection\r
- if ((uiDivisor & 0xFFFF0000) || (uiDivisor == 0)) {\r
- return EINVAL;\r
- }\r
-\r
- if ((databits > 8 || databits < 5)) {\r
- return EINVAL;\r
- }\r
- valLCR |= LCR_WLS((databits-5));\r
-\r
- switch (parity) {\r
- case EVEN: \r
- valLCR |= LCR_EPS;\r
- // Fall through to enable\r
- case ODD:\r
- valLCR |= LCR_PEN;\r
- break;\r
- case NONE:\r
- break;\r
- default:\r
- return EINVAL;\r
- break;\r
- }\r
- \r
- if ((stopbits > 2) || (stopbits < 1)) {\r
- return EINVAL;\r
- }\r
- else if (stopbits == 2) {\r
- valLCR |= LCR_STB;\r
- }\r
-\r
- if (flow_cntl) {\r
- valMCR |= MCR_AFE;\r
- }\r
-\r
- atomic {\r
- call UART.setDLL((uiDivisor & 0xFF));\r
- call UART.setDLH(((uiDivisor >> 8) & 0xFF));\r
- call UART.setLCR(valLCR);\r
- call UART.setMCR(valMCR);\r
- }\r
- \r
- return SUCCESS;\r
- }\r
- \r
- async command error_t HalPXA27xSerialCntl.flushPort() {\r
-\r
- atomic {\r
- call UART.setFCR(gulFCRShadow | FCR_RESETTF | FCR_RESETRF);\r
- }\r
-\r
- return SUCCESS;\r
- }\r
- \r
- async event void UART.interruptUART() {\r
- uint8_t error, intSource;\r
- uint8_t ucByte;\r
-\r
- intSource = call UART.getIIR();\r
- intSource &= IIR_IID_MASK;\r
- intSource = intSource >> 1;\r
- \r
- switch (intSource) {\r
- case 0: // MODEM STATUS\r
- break;\r
- case 1: // TRANSMIT FIFO\r
- call UART.setIER(call UART.getIER() & ~IER_TIE);\r
- DispatchStreamSendSignal();\r
- break;\r
- case 2: // RECEIVE FIFO data available\r
- while (call UART.getLSR() & LSR_DR) {\r
- ucByte = call UART.getRBR();\r
-\r
- if (rxCurrentBuf != NULL) {\r
- rxCurrentBuf[rxCurrentIdx] = ucByte;\r
- rxCurrentIdx++;\r
- if (rxCurrentIdx >= rxCurrentLen) \r
- DispatchStreamRcvSignal();\r
- }\r
- else if (gbRcvByteEvtEnabled) {\r
- signal UartStream.receivedByte(ucByte);\r
- }\r
- }\r
- break;\r
- case 3: // ERROR\r
- error = call UART.getLSR();\r
- break;\r
- default:\r
- break;\r
- }\r
- return;\r
- }\r
-\r
- default async event void UartStream.sendDone( uint8_t* buf, uint16_t len, error_t error ) {\r
- return; \r
- }\r
-\r
- default async event void UartStream.receivedByte(uint8_t data) {\r
- return;\r
- }\r
-\r
- default async event void UartStream.receiveDone( uint8_t* buf, uint16_t len, error_t error ) {\r
- return;\r
- }\r
-\r
- default async event uint8_t* HalPXA27xSerialPacket.sendDone(uint8_t *buf, \r
- uint16_t len, \r
- uart_status_t status) {\r
- return NULL;\r
- }\r
-\r
- default async event uint8_t* HalPXA27xSerialPacket.receiveDone(uint8_t *buf, \r
- uint16_t len, \r
- uart_status_t status) {\r
- return NULL;\r
- }\r
-\r
-\r
-}\r
+/* $Id$ */
+/*
+ * Copyright (c) 2005 Arched Rock Corporation
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of the Arched Rock Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARCHED
+ * ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+/*
+ * Intel Open Source License
+ *
+ * Copyright (c) 2002 Intel Corporation
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+/**
+ * Implements the UartByte, UartStream and HalPXA27xSerialPacket interface
+ * for a PXA27x UART.
+ *
+ *
+ * @param defaultRate Default baud rate for the serial port.
+ *
+ *
+ * @author Phil Buonadonna
+ */
+
+#include "pxa27x_serial.h"
+
+generic module HalPXA27xSerialP(uint32_t defaultRate)
+{
+ provides {
+ interface Init;
+ interface StdControl;
+ interface UartByte;
+ interface UartStream;
+ interface HalPXA27xSerialPacket;
+ interface HalPXA27xSerialCntl;
+ }
+ uses {
+ interface Init as UARTInit;
+ interface HplPXA27xUART as UART;
+ interface HplPXA27xDMAChnl as RxDMA;
+ interface HplPXA27xDMAChnl as TxDMA;
+ interface HplPXA27xDMAInfo as UARTRxDMAInfo;
+ interface HplPXA27xDMAInfo as UARTTxDMAInfo;
+ }
+}
+
+implementation
+{
+
+ uint8_t *txCurrentBuf, *rxCurrentBuf;
+ uint32_t txCurrentLen, rxCurrentLen, rxCurrentIdx;
+ uint32_t gulFCRShadow;
+ bool gbUsingUartStreamSendIF = FALSE;
+ bool gbUsingUartStreamRcvIF = FALSE;
+ bool gbRcvByteEvtEnabled = TRUE;
+
+ command error_t Init.init() {
+ error_t error = SUCCESS;
+
+ atomic {
+ call UARTInit.init();
+ txCurrentBuf = rxCurrentBuf = NULL;
+ gbUsingUartStreamSendIF = FALSE;
+ gbUsingUartStreamRcvIF = FALSE;
+ gbRcvByteEvtEnabled = TRUE;
+ gulFCRShadow = (FCR_TRFIFOE | FCR_ITL(0)); // FIFO Mode, 1 byte Rx threshold
+ }
+ call TxDMA.setMap(call UARTTxDMAInfo.getMapIndex());
+ call RxDMA.setMap(call UARTRxDMAInfo.getMapIndex());
+ call TxDMA.setDALGNbit(TRUE);
+ call RxDMA.setDALGNbit(TRUE);
+
+ error = call HalPXA27xSerialCntl.configPort(defaultRate,8,NONE,1,FALSE);
+
+ atomic {call UART.setFCR(gulFCRShadow);}
+ return error;
+ }
+
+ command error_t StdControl.start() {
+ atomic {
+ call UART.setIER(IER_UUE | IER_RAVIE);
+ }
+ return SUCCESS;
+ }
+
+ command error_t StdControl.stop() {
+ atomic {
+ call UART.setIER(0);
+ }
+ return SUCCESS;
+ }
+
+ async command error_t UartByte.send(uint8_t data) {
+ atomic call UART.setTHR(data);
+ while ((call UART.getLSR() & LSR_TEMT) == 0);
+ return SUCCESS;
+ }
+
+ async command error_t UartByte.receive( uint8_t *data, uint8_t timeout) {
+ error_t error = FAIL;
+ uint8_t t;
+ for (t = 0; t < timeout; t++) {
+ if (call UART.getLSR() & LSR_DR) {
+ *data = call UART.getRBR();
+ error = SUCCESS;
+ break;
+ }
+ }
+ return error;
+ }
+
+ async command error_t UartStream.send( uint8_t* buf, uint16_t len ) {
+ error_t error;
+ atomic gbUsingUartStreamSendIF = TRUE;
+ error = call HalPXA27xSerialPacket.send(buf,len);
+ if (error) {
+ atomic gbUsingUartStreamSendIF = FALSE;
+ }
+ return error;
+ }
+
+
+ async command error_t UartStream.enableReceiveInterrupt() {
+ error_t error = SUCCESS;
+ atomic {
+ if (rxCurrentBuf == NULL) {
+ call UART.setIER(call UART.getIER() | IER_RAVIE);
+ }
+ gbRcvByteEvtEnabled = TRUE;
+ }
+ return SUCCESS;
+ }
+
+ async command error_t UartStream.disableReceiveInterrupt() {
+ atomic {
+ // Check to make sure a short stream/packet call isn't in progress
+ if ((rxCurrentBuf == NULL) || (rxCurrentLen >= 8)) {
+ call UART.setIER(call UART.getIER() & ~IER_RAVIE);
+ }
+ gbRcvByteEvtEnabled = FALSE;
+ }
+ return SUCCESS;
+ }
+
+ async command error_t UartStream.receive( uint8_t* buf, uint16_t len ) {
+ error_t error;
+ atomic gbUsingUartStreamRcvIF = TRUE;
+ error = call HalPXA27xSerialPacket.receive(buf,len,0);
+ if (error) {
+ atomic gbUsingUartStreamRcvIF = FALSE;
+ }
+ return error;
+ }
+
+ async command error_t HalPXA27xSerialPacket.send(uint8_t *buf, uint16_t len) {
+ uint32_t txAddr;
+ uint32_t DMAFlags;
+ error_t error = SUCCESS;
+
+ atomic {
+ if (txCurrentBuf == NULL) {
+ txCurrentBuf = buf;
+ txCurrentLen = len;
+ }
+ else {
+ error = FAIL;
+ }
+ }
+
+ if (error)
+ return error;
+
+ if (len < 8) {
+ uint16_t i;
+ // Use PIO. Invariant: FIFO is empty
+ atomic {
+ gulFCRShadow |= FCR_TIL;
+ call UART.setFCR(gulFCRShadow);
+ }
+ for (i = 0;i < len;i++) {
+ call UART.setTHR(buf[i]);
+ }
+ atomic call UART.setIER(call UART.getIER() | IER_TIE);
+ }
+ else {
+ // Use DMA
+ DMAFlags = (DCMD_FLOWTRG | DCMD_BURST8 | DCMD_WIDTH1 | DCMD_ENDIRQEN
+ | DCMD_LEN(len) );
+
+ txAddr = (uint32_t) buf;
+ DMAFlags |= DCMD_INCSRCADDR;
+
+ call TxDMA.setDCSR(DCSR_NODESCFETCH);
+ call TxDMA.setDSADR(txAddr);
+ call TxDMA.setDTADR(call UARTTxDMAInfo.getAddr());
+ call TxDMA.setDCMD(DMAFlags);
+
+ atomic {
+ call UART.setIER(call UART.getIER() | IER_DMAE);
+ }
+
+ call TxDMA.setDCSR(DCSR_RUN | DCSR_NODESCFETCH);
+ }
+ return error;
+ }
+
+
+ async command error_t HalPXA27xSerialPacket.receive(uint8_t *buf, uint16_t len,
+ uint16_t timeout) {
+ uint32_t rxAddr;
+ uint32_t DMAFlags;
+ error_t error = SUCCESS;
+
+ atomic {
+ if (rxCurrentBuf == NULL) {
+ rxCurrentBuf = buf;
+ rxCurrentLen = len;
+ rxCurrentIdx = 0;
+ }
+ else {
+ error = FAIL;
+ }
+ }
+
+ if (error)
+ return error;
+
+ if (len < 8) {
+ // Use PIO. Invariant: FIFO is empty
+ atomic {
+ gulFCRShadow = ((gulFCRShadow & ~(FCR_ITL(3))) | FCR_ITL(0));
+ call UART.setFCR(gulFCRShadow);
+ call UART.setIER(call UART.getIER() | IER_RAVIE);
+ }
+ }
+ else {
+ // Use DMA
+ DMAFlags = (DCMD_FLOWSRC | DCMD_BURST8 | DCMD_WIDTH1 | DCMD_ENDIRQEN
+ | DCMD_LEN(len) );
+
+ rxAddr = (uint32_t) buf;
+ DMAFlags |= DCMD_INCTRGADDR;
+
+ call RxDMA.setDCSR(DCSR_NODESCFETCH);
+ call RxDMA.setDTADR(rxAddr);
+ call RxDMA.setDSADR(call UARTRxDMAInfo.getAddr());
+ call RxDMA.setDCMD(DMAFlags);
+
+ atomic {
+ gulFCRShadow = ((gulFCRShadow & ~(FCR_ITL(3))) | FCR_ITL(1));
+ call UART.setFCR(gulFCRShadow);
+ call UART.setIER((call UART.getIER() & ~IER_RAVIE) | IER_DMAE);
+ }
+
+ call RxDMA.setDCSR(DCSR_RUN | DCSR_NODESCFETCH);
+ }
+ return error;
+ }
+
+ void DispatchStreamRcvSignal() {
+ uint8_t *pBuf = rxCurrentBuf;
+ uint16_t len = rxCurrentLen;
+ rxCurrentBuf = NULL;
+ if (gbUsingUartStreamRcvIF) {
+ gbUsingUartStreamRcvIF = FALSE;
+ signal UartStream.receiveDone(pBuf, len, SUCCESS);
+ }
+ else {
+ pBuf = signal HalPXA27xSerialPacket.receiveDone(pBuf, len, SUCCESS);
+ if (pBuf) {
+ call HalPXA27xSerialPacket.receive(pBuf,len,0);
+ }
+ }
+ return;
+ }
+
+ void DispatchStreamSendSignal() {
+ uint8_t *pBuf = txCurrentBuf;
+ uint16_t len = txCurrentLen;
+ txCurrentBuf = NULL;
+ if (gbUsingUartStreamSendIF) {
+ gbUsingUartStreamSendIF = FALSE;
+ signal UartStream.sendDone(pBuf, len, SUCCESS);
+ }
+ else {
+ pBuf = signal HalPXA27xSerialPacket.sendDone(pBuf, len, SUCCESS);
+ if (pBuf) {
+ call HalPXA27xSerialPacket.send(pBuf,len);
+ }
+ }
+ return;
+ }
+
+ async event void RxDMA.interruptDMA() {
+ call RxDMA.setDCMD(0);
+ call RxDMA.setDCSR(DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR);
+ DispatchStreamRcvSignal();
+ if (gbRcvByteEvtEnabled)
+ call UART.setIER(call UART.getIER() | IER_RAVIE);
+ return;
+ }
+
+ async event void TxDMA.interruptDMA() {
+ call TxDMA.setDCMD(0);
+ call TxDMA.setDCSR(DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR);
+ DispatchStreamSendSignal();
+ return;
+ }
+
+
+ async command error_t HalPXA27xSerialCntl.configPort(uint32_t baudrate,
+ uint8_t databits,
+ uart_parity_t parity,
+ uint8_t stopbits,
+ bool flow_cntl) {
+ uint32_t uiDivisor;
+ uint32_t valLCR = 0;
+ uint32_t valMCR = MCR_OUT2;
+
+ uiDivisor = 921600/baudrate;
+ // Check for invalid baud rate divisor value.
+ // XXX - Eventually could use '0' to imply auto rate detection
+ if ((uiDivisor & 0xFFFF0000) || (uiDivisor == 0)) {
+ return EINVAL;
+ }
+
+ if ((databits > 8 || databits < 5)) {
+ return EINVAL;
+ }
+ valLCR |= LCR_WLS((databits-5));
+
+ switch (parity) {
+ case EVEN:
+ valLCR |= LCR_EPS;
+ // Fall through to enable
+ case ODD:
+ valLCR |= LCR_PEN;
+ break;
+ case NONE:
+ break;
+ default:
+ return EINVAL;
+ break;
+ }
+
+ if ((stopbits > 2) || (stopbits < 1)) {
+ return EINVAL;
+ }
+ else if (stopbits == 2) {
+ valLCR |= LCR_STB;
+ }
+
+ if (flow_cntl) {
+ valMCR |= MCR_AFE;
+ }
+
+ atomic {
+ call UART.setDLL((uiDivisor & 0xFF));
+ call UART.setDLH(((uiDivisor >> 8) & 0xFF));
+ call UART.setLCR(valLCR);
+ call UART.setMCR(valMCR);
+ }
+
+ return SUCCESS;
+ }
+
+ async command error_t HalPXA27xSerialCntl.flushPort() {
+
+ atomic {
+ call UART.setFCR(gulFCRShadow | FCR_RESETTF | FCR_RESETRF);
+ }
+
+ return SUCCESS;
+ }
+
+ async event void UART.interruptUART() {
+ uint8_t error, intSource;
+ uint8_t ucByte;
+
+ intSource = call UART.getIIR();
+ intSource &= IIR_IID_MASK;
+ intSource = intSource >> 1;
+
+ switch (intSource) {
+ case 0: // MODEM STATUS
+ break;
+ case 1: // TRANSMIT FIFO
+ call UART.setIER(call UART.getIER() & ~IER_TIE);
+ DispatchStreamSendSignal();
+ break;
+ case 2: // RECEIVE FIFO data available
+ while (call UART.getLSR() & LSR_DR) {
+ ucByte = call UART.getRBR();
+
+ if (rxCurrentBuf != NULL) {
+ rxCurrentBuf[rxCurrentIdx] = ucByte;
+ rxCurrentIdx++;
+ if (rxCurrentIdx >= rxCurrentLen)
+ DispatchStreamRcvSignal();
+ }
+ else if (gbRcvByteEvtEnabled) {
+ signal UartStream.receivedByte(ucByte);
+ }
+ }
+ break;
+ case 3: // ERROR
+ error = call UART.getLSR();
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+
+ default async event void UartStream.sendDone( uint8_t* buf, uint16_t len, error_t error ) {
+ return;
+ }
+
+ default async event void UartStream.receivedByte(uint8_t data) {
+ return;
+ }
+
+ default async event void UartStream.receiveDone( uint8_t* buf, uint16_t len, error_t error ) {
+ return;
+ }
+
+ default async event uint8_t* HalPXA27xSerialPacket.sendDone(uint8_t *buf,
+ uint16_t len,
+ uart_status_t status) {
+ return NULL;
+ }
+
+ default async event uint8_t* HalPXA27xSerialPacket.receiveDone(uint8_t *buf,
+ uint16_t len,
+ uart_status_t status) {
+ return NULL;
+ }
+
+
+}