halpxa27xspidmam.nc
来自「tinyos-2.0源代码!转载而已!要的尽管拿!」· NC 代码 · 共 207 行
NC
207 行
/* $Id: HalPXA27xSpiDMAM.nc,v 1.1.2.5 2006/02/16 19:03:16 idgay 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.
*/
/**
* 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;
uint8_t *txCurrentBuf, *rxCurrentBuf;
uint8_t instanceCurrent;
uint32_t lenCurrent;
command error_t Init.init() {
txBitBucket = 0, rxBitBucket = 0;
txCurrentBuf = rxCurrentBuf = NULL;
lenCurrent = 0 ;
instanceCurrent = 0;
call SSP.setSSCR1((SSCR1_TRAIL | SSCR1_RFT(8) | SSCR1_TFT(8)));
call SSP.setSSTO(96*8);
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 void SpiByte.write(uint8_t tx, uint8_t* rx) {
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();
if (rx != NULL) *rx = 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);
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);
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;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?