-/* $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
- * Implements the TOS 2.0 SpiByte and SpiPacket interfaces for the PXA27x.\r
- * It assumes the Motorola Serial Peripheral Interface format.\r
- * Uses DMA for the packet based transfers.\r
- * \r
- * @param valSCR The value for the SCR field in the SSCR0 register of the \r
- * associated SSP peripheral.\r
- *\r
- * @param valDSS The value for the DSS field in the SSCR0 register of the\r
- * associated SSP peripheral.\r
- * \r
- * @author Phil Buonadonna\r
- */\r
-\r
-generic module HalPXA27xSpiDMAM(uint8_t valFRF, uint8_t valSCR, uint8_t valDSS, bool enableRWOT) \r
-{\r
- provides {\r
- interface Init;\r
- interface SpiByte;\r
- interface SpiPacket[uint8_t instance];\r
- }\r
- uses {\r
- interface HplPXA27xSSP as SSP;\r
- interface HplPXA27xDMAChnl as RxDMA;\r
- interface HplPXA27xDMAChnl as TxDMA;\r
- interface HplPXA27xDMAInfo as SSPRxDMAInfo;\r
- interface HplPXA27xDMAInfo as SSPTxDMAInfo;\r
- }\r
-}\r
-\r
-implementation\r
-{\r
- // The BitBuckets need to be 8 bytes. \r
- norace unsigned long long txBitBucket, rxBitBucket;\r
- //norace uint8_t ucBitBucket[0x10000];\r
- //norace uint32_t txBitBucket, rxBitBucket;\r
- uint8_t *txCurrentBuf, *rxCurrentBuf;\r
- uint8_t instanceCurrent;\r
- uint32_t lenCurrent;\r
-\r
- command error_t Init.init() {\r
-\r
- //txBitBucket = (uint32_t)((uint32_t)&ullBitBucket[1] * ~0x7);\r
- //rxBitBucket = txBitBucket + 8;\r
- //rxBitBucket = txBitBucket = (uint32_t)&ucBitBucket[0];\r
- txCurrentBuf = rxCurrentBuf = NULL;\r
- lenCurrent = 0 ;\r
- instanceCurrent = 0;\r
-\r
- call SSP.setSSCR1((SSCR1_TRAIL | SSCR1_RFT(8) | SSCR1_TFT(8)));\r
- call SSP.setSSTO(3500);\r
- call SSP.setSSCR0(SSCR0_SCR(valSCR) | SSCR0_SSE | SSCR0_FRF(valFRF) | SSCR0_DSS(valDSS) );\r
-\r
- call TxDMA.setMap(call SSPTxDMAInfo.getMapIndex());\r
- call RxDMA.setMap(call SSPRxDMAInfo.getMapIndex());\r
- call TxDMA.setDALGNbit(TRUE);\r
- call RxDMA.setDALGNbit(TRUE);\r
-\r
- return SUCCESS;\r
- }\r
-\r
- async command uint8_t SpiByte.write(uint8_t tx) {\r
- volatile uint32_t tmp;\r
- volatile uint8_t val;\r
-#if 1\r
- while ((call SSP.getSSSR()) & SSSR_RNE) {\r
- tmp = call SSP.getSSDR();\r
- } \r
-#endif\r
- call SSP.setSSDR(tx); \r
-\r
- while ((call SSP.getSSSR()) & SSSR_BSY);\r
-\r
- val = call SSP.getSSDR();\r
-\r
- return val;\r
- }\r
-\r
- async command error_t SpiPacket.send[uint8_t instance](uint8_t* txBuf, uint8_t* rxBuf, uint16_t len) {\r
- uint32_t tmp;\r
- uint32_t txAddr,rxAddr;\r
- uint32_t txDMAFlags, rxDMAFlags;\r
- error_t error = FAIL;\r
-\r
-#if 1\r
- while ((call SSP.getSSSR()) & SSSR_RNE) {\r
- tmp = call SSP.getSSDR();\r
- }\r
-#endif \r
-\r
- atomic {\r
- txCurrentBuf = txBuf;\r
- rxCurrentBuf = rxBuf;\r
- lenCurrent = len;\r
- instanceCurrent = instance;\r
- }\r
-\r
- txDMAFlags = (DCMD_FLOWTRG | DCMD_BURST8 | DCMD_WIDTH1 \r
- | DCMD_LEN(len));\r
- rxDMAFlags = (DCMD_FLOWSRC | DCMD_ENDIRQEN | DCMD_BURST8 | DCMD_WIDTH1 \r
- | DCMD_LEN(len));\r
-\r
- if (rxBuf == NULL) { \r
- rxAddr = (uint32_t)&rxBitBucket; \r
- }\r
- else {\r
- rxAddr = (uint32_t)rxBuf; \r
- rxDMAFlags |= DCMD_INCTRGADDR; \r
- }\r
-\r
- if (txBuf == NULL) {\r
- txAddr = (uint32_t)&txBitBucket; \r
- }\r
- else {\r
- txAddr = (uint32_t)txBuf;\r
- txDMAFlags |= DCMD_INCSRCADDR;\r
- }\r
-\r
- call RxDMA.setDCSR(DCSR_NODESCFETCH | DCSR_EORIRQEN | DCSR_EORINT);\r
- call RxDMA.setDSADR(call SSPRxDMAInfo.getAddr());\r
- call RxDMA.setDTADR(rxAddr);\r
- call RxDMA.setDCMD(rxDMAFlags);\r
-\r
- call TxDMA.setDCSR(DCSR_NODESCFETCH);\r
- call TxDMA.setDSADR(txAddr);\r
- call TxDMA.setDTADR(call SSPTxDMAInfo.getAddr());\r
- call TxDMA.setDCMD(txDMAFlags);\r
- \r
- call SSP.setSSSR(SSSR_TINT);\r
- call SSP.setSSCR1((call SSP.getSSCR1()) | SSCR1_RSRE | SSCR1_TSRE);\r
-\r
- call RxDMA.setDCSR(DCSR_RUN | DCSR_NODESCFETCH | DCSR_EORIRQEN);\r
- call TxDMA.setDCSR(DCSR_RUN | DCSR_NODESCFETCH);\r
- \r
- error = SUCCESS;\r
- \r
- return error;\r
- }\r
- \r
- async event void RxDMA.interruptDMA() {\r
- uint8_t *txBuf,*rxBuf;\r
- uint8_t instance;\r
- uint32_t len;\r
- \r
- atomic {\r
- instance = instanceCurrent;\r
- len = lenCurrent;\r
- txBuf = txCurrentBuf;\r
- rxBuf = rxCurrentBuf;\r
- lenCurrent = 0;\r
- }\r
- call RxDMA.setDCMD(0);\r
- call RxDMA.setDCSR(DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR);\r
-\r
- signal SpiPacket.sendDone[instance](txBuf,rxBuf,len,SUCCESS);\r
-\r
- return;\r
- }\r
-\r
- async event void TxDMA.interruptDMA() {\r
- // The transmit side should NOT generate an interrupt. \r
- call TxDMA.setDCMD(0);\r
- call TxDMA.setDCSR(DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR);\r
- return;\r
- }\r
-\r
- async event void SSP.interruptSSP() {\r
- // For this Hal, we should never get here normally\r
- // Perhaps we should signal any weird errors? For now, just clear the interrupts\r
- call SSP.setSSSR(SSSR_BCE | SSSR_TUR | SSSR_EOC | SSSR_TINT | \r
- SSSR_PINT | SSSR_ROR );\r
- return;\r
- }\r
-\r
- default async event void SpiPacket.sendDone[uint8_t instance](uint8_t* txBuf, uint8_t* rxBuf, \r
- uint16_t len, error_t error) {\r
- return;\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.
+ */
+/**
+ * Implements the TOS 2.0 SpiByte and SpiPacket interfaces for the PXA27x.
+ * It assumes the Motorola Serial Peripheral Interface format.
+ * Uses DMA for the packet based transfers.
+ *
+ * @param valSCR The value for the SCR field in the SSCR0 register of the
+ * associated SSP peripheral.
+ *
+ * @param valDSS The value for the DSS field in the SSCR0 register of the
+ * associated SSP peripheral.
+ *
+ * @author Phil Buonadonna
+ */
+
+generic module HalPXA27xSpiDMAM(uint8_t valFRF, uint8_t valSCR, uint8_t valDSS, bool enableRWOT)
+{
+ provides {
+ interface Init;
+ interface SpiByte;
+ interface SpiPacket[uint8_t instance];
+ }
+ uses {
+ interface HplPXA27xSSP as SSP;
+ interface HplPXA27xDMAChnl as RxDMA;
+ interface HplPXA27xDMAChnl as TxDMA;
+ interface HplPXA27xDMAInfo as SSPRxDMAInfo;
+ interface HplPXA27xDMAInfo as SSPTxDMAInfo;
+ }
+}
+
+implementation
+{
+ // The BitBuckets need to be 8 bytes.
+ norace unsigned long long txBitBucket, rxBitBucket;
+ //norace uint8_t ucBitBucket[0x10000];
+ //norace uint32_t txBitBucket, rxBitBucket;
+ uint8_t *txCurrentBuf, *rxCurrentBuf;
+ uint8_t instanceCurrent;
+ uint32_t lenCurrent;
+
+ command error_t Init.init() {
+
+ //txBitBucket = (uint32_t)((uint32_t)&ullBitBucket[1] * ~0x7);
+ //rxBitBucket = txBitBucket + 8;
+ //rxBitBucket = txBitBucket = (uint32_t)&ucBitBucket[0];
+ txCurrentBuf = rxCurrentBuf = NULL;
+ lenCurrent = 0 ;
+ instanceCurrent = 0;
+
+ call SSP.setSSCR1((SSCR1_TRAIL | SSCR1_RFT(8) | SSCR1_TFT(8)));
+ call SSP.setSSTO(3500);
+ call SSP.setSSCR0(SSCR0_SCR(valSCR) | SSCR0_SSE | SSCR0_FRF(valFRF) | SSCR0_DSS(valDSS) );
+
+ call TxDMA.setMap(call SSPTxDMAInfo.getMapIndex());
+ call RxDMA.setMap(call SSPRxDMAInfo.getMapIndex());
+ call TxDMA.setDALGNbit(TRUE);
+ call RxDMA.setDALGNbit(TRUE);
+
+ return SUCCESS;
+ }
+
+ async command uint8_t SpiByte.write(uint8_t tx) {
+ volatile uint32_t tmp;
+ volatile uint8_t val;
+#if 1
+ while ((call SSP.getSSSR()) & SSSR_RNE) {
+ tmp = call SSP.getSSDR();
+ }
+#endif
+ call SSP.setSSDR(tx);
+
+ while ((call SSP.getSSSR()) & SSSR_BSY);
+
+ val = call SSP.getSSDR();
+
+ return val;
+ }
+
+ async command error_t SpiPacket.send[uint8_t instance](uint8_t* txBuf, uint8_t* rxBuf, uint16_t len) {
+ uint32_t tmp;
+ uint32_t txAddr,rxAddr;
+ uint32_t txDMAFlags, rxDMAFlags;
+ error_t error = FAIL;
+
+#if 1
+ while ((call SSP.getSSSR()) & SSSR_RNE) {
+ tmp = call SSP.getSSDR();
+ }
+#endif
+
+ atomic {
+ txCurrentBuf = txBuf;
+ rxCurrentBuf = rxBuf;
+ lenCurrent = len;
+ instanceCurrent = instance;
+ }
+
+ txDMAFlags = (DCMD_FLOWTRG | DCMD_BURST8 | DCMD_WIDTH1
+ | DCMD_LEN(len));
+ rxDMAFlags = (DCMD_FLOWSRC | DCMD_ENDIRQEN | DCMD_BURST8 | DCMD_WIDTH1
+ | DCMD_LEN(len));
+
+ if (rxBuf == NULL) {
+ rxAddr = (uint32_t)&rxBitBucket;
+ }
+ else {
+ rxAddr = (uint32_t)rxBuf;
+ rxDMAFlags |= DCMD_INCTRGADDR;
+ }
+
+ if (txBuf == NULL) {
+ txAddr = (uint32_t)&txBitBucket;
+ }
+ else {
+ txAddr = (uint32_t)txBuf;
+ txDMAFlags |= DCMD_INCSRCADDR;
+ }
+
+ call RxDMA.setDCSR(DCSR_NODESCFETCH | DCSR_EORIRQEN | DCSR_EORINT);
+ call RxDMA.setDSADR(call SSPRxDMAInfo.getAddr());
+ call RxDMA.setDTADR(rxAddr);
+ call RxDMA.setDCMD(rxDMAFlags);
+
+ call TxDMA.setDCSR(DCSR_NODESCFETCH);
+ call TxDMA.setDSADR(txAddr);
+ call TxDMA.setDTADR(call SSPTxDMAInfo.getAddr());
+ call TxDMA.setDCMD(txDMAFlags);
+
+ call SSP.setSSSR(SSSR_TINT);
+ call SSP.setSSCR1((call SSP.getSSCR1()) | SSCR1_RSRE | SSCR1_TSRE);
+
+ call RxDMA.setDCSR(DCSR_RUN | DCSR_NODESCFETCH | DCSR_EORIRQEN);
+ call TxDMA.setDCSR(DCSR_RUN | DCSR_NODESCFETCH);
+
+ error = SUCCESS;
+
+ return error;
+ }
+
+ async event void RxDMA.interruptDMA() {
+ uint8_t *txBuf,*rxBuf;
+ uint8_t instance;
+ uint32_t len;
+
+ atomic {
+ instance = instanceCurrent;
+ len = lenCurrent;
+ txBuf = txCurrentBuf;
+ rxBuf = rxCurrentBuf;
+ lenCurrent = 0;
+ }
+ call RxDMA.setDCMD(0);
+ call RxDMA.setDCSR(DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR);
+
+ signal SpiPacket.sendDone[instance](txBuf,rxBuf,len,SUCCESS);
+
+ return;
+ }
+
+ async event void TxDMA.interruptDMA() {
+ // The transmit side should NOT generate an interrupt.
+ call TxDMA.setDCMD(0);
+ call TxDMA.setDCSR(DCSR_EORINT | DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERRINTR);
+ return;
+ }
+
+ async event void SSP.interruptSSP() {
+ // For this Hal, we should never get here normally
+ // Perhaps we should signal any weird errors? For now, just clear the interrupts
+ call SSP.setSSSR(SSSR_BCE | SSSR_TUR | SSSR_EOC | SSSR_TINT |
+ SSSR_PINT | SSSR_ROR );
+ return;
+ }
+
+ default async event void SpiPacket.sendDone[uint8_t instance](uint8_t* txBuf, uint8_t* rxBuf,
+ uint16_t len, error_t error) {
+ return;
+ }
+
+}