-/* $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
- * Provides master mode communication for a variety of frame formats, speeds\r
- * and data sizes.\r
- * \r
- * @param valFRF The frame format to use. \r
- * \r
- * @param valSCR The value for the SSP clock rate.\r
- *\r
- * @param valDSS The value for the DSS field in the SSCR0 register of the\r
- * associated SSP peripheral.\r
- * \r
- * @param enableRWOT Enables Receive without transmit mode. Used only for \r
- * the SpiPacket interface. If the txBuf parameter of SpiPacket.send is null\r
- * the implementation will continuously clock in data without regard to the \r
- * contents of the TX FIFO. This is different from the spec for the interface\r
- * which requires that the transmitter send zeros (0) for this case.\r
- * \r
- * @author Phil Buonadonna\r
- */\r
-\r
-generic module HalPXA27xSpiPioM(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
- }\r
-}\r
-\r
-implementation\r
-{\r
- // The BitBuckets need to be 8 bytes. \r
- norace unsigned long long txBitBucket, rxBitBucket;\r
- uint8_t *txCurrentBuf, *rxCurrentBuf, *txPtr, *rxPtr;\r
- uint8_t instanceCurrent;\r
- uint32_t lenCurrent, lenRemain, txInc, rxInc;\r
- norace uint32_t flagsSSCR0, flagsSSCR1;\r
-\r
- task void SpiPacketDone() {\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
- signal SpiPacket.sendDone[instance](txBuf,rxBuf,len,SUCCESS);\r
- }\r
- \r
- return;\r
- }\r
-\r
- command error_t Init.init() {\r
-\r
- txBitBucket = 0, rxBitBucket = 0;\r
- txCurrentBuf = rxCurrentBuf = NULL;\r
- lenCurrent = 0 ;\r
- instanceCurrent = 0;\r
- lenRemain = 0;\r
-\r
- flagsSSCR1 = 0;\r
- flagsSSCR0 = (SSCR0_SCR(valSCR) | SSCR0_FRF(/*0*/valFRF) | SSCR0_DSS(valDSS) );\r
-\r
- call SSP.setSSCR1(flagsSSCR1);\r
- call SSP.setSSTO(3500 /*96*8*/);\r
- call SSP.setSSCR0(flagsSSCR0);\r
- call SSP.setSSCR0(flagsSSCR0 | SSCR0_SSE);\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,i;\r
- //uint8_t *txPtr,*rxPtr;\r
- //uint32_t txInc = 1,rxInc = 1;\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 = lenRemain = len;\r
- instanceCurrent = instance;\r
- \r
- if (rxBuf == NULL) { \r
- rxPtr = (uint8_t *)&rxBitBucket; \r
- rxInc = 0;\r
- }\r
- else {\r
- rxPtr = rxBuf; \r
- rxInc = 1;\r
- }\r
- \r
- if (txBuf == NULL) {\r
- txPtr = (uint8_t *)&txBitBucket; \r
- txInc = 0;\r
- }\r
- else {\r
- txPtr = txBuf;\r
- txInc = 1;\r
- }\r
- }\r
-\r
- atomic {\r
- if ((txBuf == NULL) && (enableRWOT == TRUE)) {\r
- \r
- call SSP.setSSCR0(flagsSSCR0);\r
- call SSP.setSSCR1(flagsSSCR1 | SSCR1_RWOT);\r
- call SSP.setSSCR0(flagsSSCR0 | SSCR0_SSE);\r
- while (len > 0) {\r
- while (!(call SSP.getSSSR() & SSSR_RNE));\r
- *rxPtr = call SSP.getSSDR();\r
- rxPtr += rxInc;\r
- len--;\r
- }\r
- call SSP.setSSCR0(flagsSSCR0);\r
- call SSP.setSSCR1(flagsSSCR1);\r
- call SSP.setSSCR0(flagsSSCR0 | SSCR0_SSE);\r
- }\r
- else {\r
- uint8_t burst = (len < 16) ? len : 16;\r
- for (i = 0;i < burst; i++) {\r
- call SSP.setSSDR(*txPtr);\r
- txPtr += txInc;\r
- }\r
- call SSP.setSSCR1(flagsSSCR1 | SSCR1_TINTE | SSCR1_RIE);\r
- /*\r
- while (len > 16) {\r
- for (i = 0;i < 16; i++) {\r
- call SSP.setSSDR(*txPtr);\r
- txPtr += txInc;\r
- }\r
- while (call SSP.getSSSR() & SSSR_BSY);\r
- for (i = 0;i < 16;i++) {\r
- *rxPtr = call SSP.getSSDR();\r
- rxPtr += rxInc;\r
- }\r
- len -= 16;\r
- }\r
- for (i = 0;i < len; i++) {\r
- call SSP.setSSDR(*txPtr);\r
- txPtr += txInc;\r
- }\r
- while (call SSP.getSSSR() & SSSR_BSY);\r
- for (i = 0;i < len;i++) {\r
- *rxPtr = call SSP.getSSDR();\r
- rxPtr += rxInc;\r
- }\r
- */\r
- }\r
- }\r
- //post SpiPacketDone();\r
- \r
- error = SUCCESS;\r
- \r
- return error;\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
- uint32_t i, uiStatus, uiFifoLevel;\r
- uint32_t burst;\r
-\r
- uiStatus = call SSP.getSSSR();\r
- call SSP.setSSSR(SSSR_TINT);\r
-\r
- uiFifoLevel = ((uiStatus & SSSR_RFL) >> 12) | 0xFUL;\r
-\r
- if ((uiFifoLevel < 0xF) || (uiStatus & SSSR_RNE)) {\r
- //uiFifoLevel = (uiFifoLevel == 0) ? 16 : uiFifoLevel;\r
- uiFifoLevel = (uiFifoLevel > lenRemain) ? lenRemain : uiFifoLevel;\r
- for (i = 0;i < uiFifoLevel;i++) {\r
- *rxPtr = call SSP.getSSDR();\r
- rxPtr += rxInc;\r
- }\r
- lenRemain -= uiFifoLevel;\r
- }\r
- if (lenRemain > 0) {\r
- burst = (lenRemain < uiFifoLevel) ? lenRemain : uiFifoLevel;\r
- for (i = 0;i < burst;i++) {\r
- call SSP.setSSDR(*txPtr);\r
- txPtr += txInc;\r
- }\r
- }\r
- else {\r
- uint32_t len = lenCurrent;\r
- call SSP.setSSCR1(flagsSSCR1);\r
- lenCurrent = 0;\r
- signal SpiPacket.sendDone[instanceCurrent](txCurrentBuf, rxCurrentBuf,len,SUCCESS);\r
- }\r
-\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.
+ * Provides master mode communication for a variety of frame formats, speeds
+ * and data sizes.
+ *
+ * @param valFRF The frame format to use.
+ *
+ * @param valSCR The value for the SSP clock rate.
+ *
+ * @param valDSS The value for the DSS field in the SSCR0 register of the
+ * associated SSP peripheral.
+ *
+ * @param enableRWOT Enables Receive without transmit mode. Used only for
+ * the SpiPacket interface. If the txBuf parameter of SpiPacket.send is null
+ * the implementation will continuously clock in data without regard to the
+ * contents of the TX FIFO. This is different from the spec for the interface
+ * which requires that the transmitter send zeros (0) for this case.
+ *
+ * @author Phil Buonadonna
+ * @author Miklos Maroti, Brano Kusy
+ */
+
+generic module HalPXA27xSpiPioM(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;
+ }
+}
+
+implementation
+{
+ enum{
+ FLAGS_SSCR0 = SSCR0_SCR(valSCR) | SSCR0_FRF(/*0*/valFRF) | SSCR0_DSS(valDSS),
+ FLAGS_SSCR1 = 0
+ };
+
+ // The BitBuckets need to be 8 bytes.
+ norace unsigned long long txBitBucket, rxBitBucket;
+ norace uint8_t *txCurrentBuf, *rxCurrentBuf, *txPtr, *rxPtr;
+ norace uint8_t txInc, rxInc;
+ norace uint8_t instanceCurrent;
+ uint32_t lenCurrent, lenRemain;
+
+ command error_t Init.init() {
+
+ txBitBucket = 0, rxBitBucket = 0;
+ txCurrentBuf = rxCurrentBuf = NULL;
+ lenCurrent = 0 ;
+ instanceCurrent = 0;
+ atomic lenRemain = 0;
+
+ call SSP.setSSCR1(FLAGS_SSCR1);
+ call SSP.setSSTO(3500 /*96*8*/);
+ call SSP.setSSCR0(FLAGS_SSCR0);
+ call SSP.setSSCR0(FLAGS_SSCR0 | SSCR0_SSE);
+
+ return SUCCESS;
+ }
+
+ async command uint8_t SpiByte.write(uint8_t tx) {
+ volatile uint8_t val;
+#if 1
+ while ((call SSP.getSSSR()) & SSSR_RNE) {
+ 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 i;
+
+#if 1
+ while ((call SSP.getSSSR()) & SSSR_RNE) {
+ call SSP.getSSDR();
+ }
+#endif
+
+ txCurrentBuf = txBuf;
+ rxCurrentBuf = rxBuf;
+ atomic lenCurrent = lenRemain = len;
+ instanceCurrent = instance;
+
+ if (rxBuf == NULL) {
+ rxPtr = (uint8_t *)&rxBitBucket;
+ rxInc = 0;
+ }
+ else {
+ rxPtr = rxBuf;
+ rxInc = 1;
+ }
+
+ if (txBuf == NULL) {
+ txPtr = (uint8_t *)&txBitBucket;
+ txInc = 0;
+ }
+ else {
+ txPtr = txBuf;
+ txInc = 1;
+ }
+
+ if ((txBuf == NULL) && (enableRWOT == TRUE)) {
+ call SSP.setSSCR0(FLAGS_SSCR0);
+ call SSP.setSSCR1(FLAGS_SSCR1 | SSCR1_RWOT);
+ call SSP.setSSCR0(FLAGS_SSCR0 | SSCR0_SSE);
+ while (len > 0) {
+ while (!(call SSP.getSSSR() & SSSR_RNE));
+ *rxPtr = call SSP.getSSDR();
+ rxPtr += rxInc;
+ len--;
+ }
+ call SSP.setSSCR0(FLAGS_SSCR0);
+ call SSP.setSSCR1(FLAGS_SSCR1);
+ call SSP.setSSCR0(FLAGS_SSCR0 | SSCR0_SSE);
+ }
+ else {
+ uint8_t burst = (len < 16) ? len : 16;
+ for (i = 0;i < burst; i++) {
+ call SSP.setSSDR(*txPtr);
+ txPtr += txInc;
+ }
+ call SSP.setSSCR1(FLAGS_SSCR1 | SSCR1_TINTE | SSCR1_RIE);
+ }
+
+ return SUCCESS;
+ }
+
+ async event void SSP.interruptSSP() {
+ uint32_t i, uiStatus, uiFifoLevel;
+ uint32_t burst;
+
+ uiStatus = call SSP.getSSSR();
+ call SSP.setSSSR(SSSR_TINT);
+
+ uiFifoLevel = (((uiStatus & SSSR_RFL) >> 12) | 0xF) + 1;
+ uiFifoLevel = (uiFifoLevel > lenRemain) ? lenRemain : uiFifoLevel;
+
+ if( !(uiStatus & SSSR_RNE))
+ return;
+
+ for (i = 0; i < uiFifoLevel; i++) {
+ *rxPtr = call SSP.getSSDR();
+ rxPtr += rxInc;
+ }
+
+ atomic {
+ lenRemain -= uiFifoLevel;
+ burst = (lenRemain < 16) ? lenRemain : 16;
+ }
+
+ if (burst > 0) {
+ for (i = 0;i < burst;i++) {
+ call SSP.setSSDR(*txPtr);
+ txPtr += txInc;
+ }
+ }
+ else {
+ uint32_t len = lenCurrent;
+ call SSP.setSSCR1(FLAGS_SSCR1);
+ lenCurrent = 0;
+ signal SpiPacket.sendDone[instanceCurrent](txCurrentBuf, rxCurrentBuf,len,SUCCESS);
+ }
+
+ return;
+ }
+
+ default async event void SpiPacket.sendDone[uint8_t instance](uint8_t* txBuf, uint8_t* rxBuf,
+ uint16_t len, error_t error) {
+ return;
+ }
+
+}