⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 halpxa27xserialp.nc

📁 tinyos2.0版本驱动
💻 NC
字号:
/* $Id: HalPXA27xSerialP.nc,v 1.5 2008/06/11 00:42:13 razvanm Exp $ *//* * 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;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -