mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-12-22 10:30:13 +00:00
more protection against interrupts that might spoil SPI sequences.
made coding style more like that of contiki.
This commit is contained in:
parent
f39d2bd4c6
commit
e9d279620f
@ -47,9 +47,9 @@ Berlin, 2007
|
||||
* @brief MMC-/SD-Card library
|
||||
*
|
||||
* @author Michael Baar <baar@inf.fu-berlin.de>
|
||||
* @version $Revision: 1.7 $
|
||||
* @version $Revision: 1.8 $
|
||||
*
|
||||
* $Id: sd.c,v 1.7 2009/05/25 13:19:04 nvt-se Exp $
|
||||
* $Id: sd.c,v 1.8 2009/05/26 12:15:46 nvt-se Exp $
|
||||
*
|
||||
* Initialisation and basic functions for read and write access
|
||||
*/
|
||||
@ -231,7 +231,7 @@ sd_set_blocklength(const uint8_t blocklength_bit)
|
||||
// Public functions, Reading
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
uint16_t
|
||||
sd_AlignAddress(uint32_t * pAddress)
|
||||
sd_align_address(uint32_t * pAddress)
|
||||
{
|
||||
uint16_t blMask = sd_state.BlockLen - 1;
|
||||
uint16_t *lw = (uint16_t *)pAddress;
|
||||
@ -246,7 +246,12 @@ sd_AlignAddress(uint32_t * pAddress)
|
||||
uint16_t
|
||||
sd_read_block(void (*const pBuffer), const uint32_t address)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splhigh();
|
||||
|
||||
if(!_sd_read_start(SD_CMD_READ_SINGLE_BLOCK, address)) {
|
||||
splx(s);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -255,6 +260,8 @@ sd_read_block(void (*const pBuffer), const uint32_t address)
|
||||
// receive CRC16 and finish
|
||||
_sd_read_stop(2);
|
||||
|
||||
splx(s);
|
||||
|
||||
return sd_state.BlockLen;
|
||||
}
|
||||
|
||||
@ -269,7 +276,7 @@ sd_read_byte(void *pBuffer, const uint32_t address)
|
||||
uint32_t blAdr = address;
|
||||
uint16_t offset; // bytes from aligned address to start of first byte to keep
|
||||
// align
|
||||
offset = sd_AlignAddress(&blAdr);
|
||||
offset = sd_align_address(&blAdr);
|
||||
|
||||
// start
|
||||
if(!_sd_read_start(SD_CMD_READ_SINGLE_BLOCK, address)) {
|
||||
@ -277,7 +284,7 @@ sd_read_byte(void *pBuffer, const uint32_t address)
|
||||
}
|
||||
|
||||
// read
|
||||
Spi_read(pBuffer, offset + 1, FALSE);
|
||||
sdspi_read(pBuffer, offset + 1, FALSE);
|
||||
|
||||
// done
|
||||
_sd_read_stop(sd_state.BlockLen - offset - 1);
|
||||
@ -302,11 +309,11 @@ sd_read(void *pBuffer, unsigned long address, unsigned int size)
|
||||
// parameter processing
|
||||
//
|
||||
if(size == 0) {
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// align to block
|
||||
offset = sd_AlignAddress(&address);
|
||||
offset = sd_align_address(&address);
|
||||
|
||||
if((offset == 0) && (sd_state.BlockLen == size)) {
|
||||
// best case: perfectly block aligned, no chunking
|
||||
@ -323,10 +330,14 @@ sd_read(void *pBuffer, unsigned long address, unsigned int size)
|
||||
// Data transfer
|
||||
//
|
||||
|
||||
s = splhigh(s);
|
||||
|
||||
// request data transfer
|
||||
ret = _sd_read_start(SD_CMD_READ_SINGLE_BLOCK, address);
|
||||
|
||||
RETF(ret);
|
||||
if(!ret) {
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// run to offset
|
||||
if(offset) {
|
||||
@ -377,7 +388,10 @@ sd_read(void *pBuffer, unsigned long address, unsigned int size)
|
||||
|
||||
sdspi_unselect();
|
||||
ret = _sd_read_start(SD_CMD_READ_SINGLE_BLOCK, address);
|
||||
RETF(ret);
|
||||
if(!ret) {
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// finished
|
||||
_sd_read_stop(0);
|
||||
@ -386,6 +400,8 @@ sd_read(void *pBuffer, unsigned long address, unsigned int size)
|
||||
}
|
||||
} while(1);
|
||||
|
||||
splx(s);
|
||||
|
||||
return num_bytes_read;
|
||||
}
|
||||
|
||||
@ -409,11 +425,11 @@ _sd_write_finish(void)
|
||||
sdspi_dma_lock = FALSE;
|
||||
#endif
|
||||
|
||||
s = splhigh();
|
||||
|
||||
// dummy crc
|
||||
sdspi_idle(2);
|
||||
|
||||
s = splhigh();
|
||||
|
||||
// receive data response (ZZS___ 3 bits crc response)
|
||||
for(i = 0; i < SD_TIMEOUT_NCR; i++) {
|
||||
ret = sdspi_rx();
|
||||
@ -426,10 +442,9 @@ _sd_write_finish(void)
|
||||
}
|
||||
}
|
||||
|
||||
splx(s);
|
||||
|
||||
// wait for data to be written
|
||||
_sd_wait_standby(NULL);
|
||||
splx(s);
|
||||
sdspi_unselect();
|
||||
|
||||
if(ret) {
|
||||
@ -494,21 +509,23 @@ _sd_write_block(const uint32_t * pAddress, const void *pBuffer, int increment)
|
||||
return SD_WRITE_COMMAND_ERR;
|
||||
}
|
||||
// write data
|
||||
sdspi_select();
|
||||
s = splhigh();
|
||||
sdspi_select();
|
||||
sdspi_tx(0xFF);
|
||||
sdspi_tx(SD_TOKEN_WRITE);
|
||||
sdspi_write(pBuffer, sd_state.BlockLen, increment);
|
||||
splx(s);
|
||||
|
||||
SD_LED_WRITE_OFF;
|
||||
|
||||
// finish write
|
||||
#if SPI_DMA_WRITE
|
||||
sdspi_dma_lock = TRUE;
|
||||
splx(s);
|
||||
return SD_WRITE_SUCCESS;
|
||||
#else
|
||||
return _sd_write_finish();
|
||||
ret = _sd_write_finish();
|
||||
splx(s);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,9 @@ Berlin, 2007
|
||||
* @brief MMC-/SD-Card library, Public interface
|
||||
*
|
||||
* @author Michael Baar <baar@inf.fu-berlin.de>
|
||||
* @version $Revision: 1.5 $
|
||||
* @version $Revision: 1.6 $
|
||||
*
|
||||
* $Id: sd.h,v 1.5 2008/11/10 14:32:49 nvt-se Exp $
|
||||
* $Id: sd.h,v 1.6 2009/05/26 12:15:46 nvt-se Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -224,7 +224,7 @@ void sd_close(void);
|
||||
* 2^n value, where n shall be between 0 and 11.
|
||||
* Be aware that a card may or may not support different blocksizes.
|
||||
*
|
||||
* Since all read and write operations have to use blockaligned addresses
|
||||
* Since all read and write operations have to use block-aligned addresses
|
||||
* and need to process complete blocks always try to use the optimal blocksize
|
||||
* and let ::sd_read do the rest. If the blocklength is already set to the new
|
||||
* value nothing is done.
|
||||
@ -251,7 +251,7 @@ void sd_close(void);
|
||||
* @param[in,out] pAddress address to align, will be modified to be block aligned
|
||||
* @return Offset from aligned address to original address
|
||||
*/
|
||||
uint16_t sd_AlignAddress(uint32_t * pAddress);
|
||||
uint16_t sd_align_address(uint32_t * pAddress);
|
||||
|
||||
/**
|
||||
* @brief Read one complete block from a block aligned address into buffer
|
||||
|
@ -47,9 +47,9 @@ Berlin, 2007
|
||||
* @brief MMC-/SD-Card library, cached read and write
|
||||
*
|
||||
* @author Michael Baar <baar@inf.fu-berlin.de>
|
||||
* @version $Revision: 1.4 $
|
||||
* @version $Revision: 1.5 $
|
||||
*
|
||||
* $Id: sd_cache.c,v 1.4 2008/03/31 14:32:00 nvt-se Exp $
|
||||
* $Id: sd_cache.c,v 1.5 2009/05/26 12:15:46 nvt-se Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ _sd_cache_init(void)
|
||||
|
||||
sd_state.Cache->address = 1;
|
||||
sd_state.Cache->state = 0;
|
||||
// pre-read first block
|
||||
/* pre-read first block */
|
||||
sd_cache_read_block(&addr);
|
||||
SD_FREE_LOCK(sd_state.Cache);
|
||||
}
|
||||
@ -111,20 +111,20 @@ sd_cache_read_block(const uint32_t * pblAdr)
|
||||
uint16_t
|
||||
sd_read(void *pBuffer, uint32_t address, uint16_t size)
|
||||
{
|
||||
uint16_t offset; // bytes from aligned address to start of first byte to keep
|
||||
char *p; // pointer to current pos in receive buffer
|
||||
uint16_t bytes_left; // num bytes to read
|
||||
uint16_t read_count; // num bytes to read from current block
|
||||
uint16_t offset; /* bytes from aligned address to start of first byte to keep */
|
||||
char *p; /* pointer to current pos in receive buffer */
|
||||
uint16_t bytes_left; /* num bytes to read */
|
||||
uint16_t read_count; /* num bytes to read from current block */
|
||||
|
||||
// parameter processing
|
||||
/* parameter processing */
|
||||
p = (char *)pBuffer;
|
||||
bytes_left = size;
|
||||
// align to block
|
||||
offset = sd_AlignAddress(&address);
|
||||
/* align to block */
|
||||
offset = sd_align_address(&address);
|
||||
|
||||
// Data transfer
|
||||
/* Data transfer */
|
||||
do {
|
||||
// calculate block
|
||||
/* calculate block */
|
||||
if((offset == 0) && (bytes_left >= sd_state.BlockLen)) {
|
||||
read_count = sd_state.BlockLen;
|
||||
sd_read_block(p, address);
|
||||
@ -150,28 +150,28 @@ sd_read(void *pBuffer, uint32_t address, uint16_t size)
|
||||
address += sd_state.BlockLen;
|
||||
} while(1);
|
||||
}
|
||||
#endif // SD_READ_ANY
|
||||
#endif /* SD_READ_ANY */
|
||||
|
||||
#if SD_WRITE
|
||||
uint16_t
|
||||
sd_write(uint32_t address, void *pBuffer, uint16_t size)
|
||||
{
|
||||
uint16_t offset; // bytes from aligned address to start of first byte to keep
|
||||
char *p; // pointer to current pos in receive buffer
|
||||
uint16_t bytes_left; // num bytes to read
|
||||
uint16_t read_count; // num bytes to read from current block
|
||||
uint16_t offset; /* bytes from aligned address to start of first byte to keep */
|
||||
char *p; /* pointer to current pos in receive buffer */
|
||||
uint16_t bytes_left; /* num bytes to read */
|
||||
uint16_t read_count; /* num bytes to read from current block */
|
||||
|
||||
// parameter processing
|
||||
/* parameter processing */
|
||||
p = (char *)pBuffer;
|
||||
bytes_left = size;
|
||||
// align to block
|
||||
offset = sd_AlignAddress(&address);
|
||||
/* align to block */
|
||||
offset = sd_align_address(&address);
|
||||
|
||||
sd_set_blocklength(SD_WRITE_BLOCKLENGTH_BIT);
|
||||
|
||||
// Data transfer
|
||||
/* Data transfer */
|
||||
do {
|
||||
// calculate block
|
||||
/* calculate block */
|
||||
if((offset == 0) && (bytes_left >= sd_state.BlockLen)) {
|
||||
read_count = sd_state.BlockLen;
|
||||
sd_write_block(address, p);
|
||||
@ -198,7 +198,7 @@ sd_write(uint32_t address, void *pBuffer, uint16_t size)
|
||||
} while(1);
|
||||
}
|
||||
|
||||
#endif // SD_WRITE
|
||||
#endif // SD_CACHE
|
||||
#endif /* SD_WRITE */
|
||||
#endif /* SD_CACHE */
|
||||
|
||||
/** @} */
|
||||
|
@ -47,9 +47,9 @@ Berlin, 2007
|
||||
* @brief MMC-/SD-Card library, Block erase
|
||||
*
|
||||
* @author Michael Baar <baar@inf.fu-berlin.de>
|
||||
* @version $Revision: 1.4 $
|
||||
* @version $Revision: 1.5 $
|
||||
*
|
||||
* $Id: sd_erase.c,v 1.4 2008/05/27 13:01:27 nvt-se Exp $
|
||||
* $Id: sd_erase.c,v 1.5 2009/05/26 12:15:46 nvt-se Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -47,9 +47,9 @@ Berlin, 2007
|
||||
* @brief MMC-/SD-Card library, Additional Information
|
||||
*
|
||||
* @author Michael Baar <baar@inf.fu-berlin.de>
|
||||
* @version $Revision: 1.3 $
|
||||
* @version $Revision: 1.4 $
|
||||
*
|
||||
* $Id: sd_info.c,v 1.3 2008/03/28 23:03:05 nvt-se Exp $
|
||||
* $Id: sd_info.c,v 1.4 2009/05/26 12:15:46 nvt-se Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -47,9 +47,9 @@ Berlin, 2007
|
||||
* @brief Serial Peripheral Interface for SD library
|
||||
*
|
||||
* @author Michael Baar <baar@inf.fu-berlin.de>
|
||||
* @version $Revision: 1.3 $
|
||||
* @version $Revision: 1.4 $
|
||||
*
|
||||
* $Id: sdspi.c,v 1.3 2009/05/25 13:19:04 nvt-se Exp $
|
||||
* $Id: sdspi.c,v 1.4 2009/05/26 12:15:46 nvt-se Exp $
|
||||
*/
|
||||
|
||||
#include <msp430x16x.h>
|
||||
@ -72,7 +72,8 @@ sdspi_init(void)
|
||||
sdspi_dma_lock = FALSE;
|
||||
#endif
|
||||
|
||||
/* The 16-bit value of UxBR0+UxBR1 is the division factor of the USART clock
|
||||
/*
|
||||
* The 16-bit value of UxBR0+UxBR1 is the division factor of the USART clock
|
||||
* source, BRCLK. The maximum baud rate that can be generated in master
|
||||
* mode is BRCLK/2. The maximum baud rate that can be generated in slave
|
||||
* mode is BRCLK. The modulator in the USART baud rate generator is not used
|
||||
@ -102,9 +103,10 @@ sdspi_tx(register const uint8_t c)
|
||||
void
|
||||
sdspi_dma_wait(void)
|
||||
{
|
||||
/* Wait until a previous transfer is complete */
|
||||
while(DMA0CTL & DMAEN) {
|
||||
_NOP();
|
||||
} // Wait until a previous transfer is complete
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -118,29 +120,29 @@ sdspi_read(void *pDestination, const uint16_t size, const bool incDest)
|
||||
#if SPI_DMA_READ
|
||||
sdspi_dma_wait();
|
||||
|
||||
UART_RESET_RXTX(); // clear interrupts
|
||||
UART_RESET_RXTX(); /* clear interrupts */
|
||||
|
||||
// Configure the DMA transfer
|
||||
DMA0SA = (uint16_t) & UART_RX; // source DMA address
|
||||
DMA0DA = (uint16_t) pDestination; // destination DMA address
|
||||
DMA0SZ = size; // number of bytes to be transferred
|
||||
DMA1SA = (uint16_t) & UART_TX; // source DMA address (constant 0xff)
|
||||
DMA1DA = DMA1SA; // destination DMA address
|
||||
DMA1SZ = size - 1; // number of bytes to be transferred
|
||||
DMACTL0 = DMA0TSEL_9 | DMA1TSEL_9; // trigger is UART1 receive for both DMA0 and DMA1
|
||||
DMA0CTL = DMADT_0 | // Single transfer mode
|
||||
DMASBDB | // Byte mode
|
||||
DMADSTINCR0 | DMADSTINCR1 | // Increment destination
|
||||
DMAEN; // Enable DMA
|
||||
/* Configure the DMA transfer */
|
||||
DMA0SA = (uint16_t) & UART_RX; /* source DMA address */
|
||||
DMA0DA = (uint16_t) pDestination; /* destination DMA address */
|
||||
DMA0SZ = size; /* number of bytes to be transferred */
|
||||
DMA1SA = (uint16_t) & UART_TX; /* source DMA address (constant 0xff) */
|
||||
DMA1DA = DMA1SA; /* destination DMA address */
|
||||
DMA1SZ = size - 1; /* number of bytes to be transferred */
|
||||
DMACTL0 = DMA0TSEL_9 | DMA1TSEL_9; /* trigger is UART1 receive for both DMA0 and DMA1 */
|
||||
DMA0CTL = DMADT_0 | /* Single transfer mode */
|
||||
DMASBDB | /* Byte mode */
|
||||
DMADSTINCR0 | DMADSTINCR1 | /* Increment destination */
|
||||
DMAEN; /* Enable DMA */
|
||||
if(!incDest) {
|
||||
DMA0CTL &= ~(DMADSTINCR0 | DMADSTINCR1);
|
||||
}
|
||||
|
||||
DMA1CTL = DMADT_0 | // Single transfer mode
|
||||
DMASBDB | // Byte mode
|
||||
DMAEN; // Enable DMA
|
||||
DMA1CTL = DMADT_0 | /* Single transfer mode */
|
||||
DMASBDB | /* Byte mode */
|
||||
DMAEN; /* Enable DMA */
|
||||
|
||||
UART_TX = SPI_IDLE_SYMBOL; // Initiate transfer by sending the first byte
|
||||
UART_TX = SPI_IDLE_SYMBOL; /* Initiate transfer by sending the first byte */
|
||||
sdspi_dma_wait();
|
||||
|
||||
#else
|
||||
@ -171,17 +173,17 @@ sdspi_write(const void *pSource, const uint16_t size, const int increment)
|
||||
#if SPI_DMA_WRITE
|
||||
sdspi_dma_wait();
|
||||
|
||||
UART_RESET_RXTX(); // clear interrupts
|
||||
UART_RESET_RXTX(); /* clear interrupts */
|
||||
|
||||
// Configure the DMA transfer
|
||||
DMA0SA = ((uint16_t) pSource) + 1; // source DMA address
|
||||
DMA0DA = (uint16_t) & UART_TX; // destination DMA address
|
||||
DMA0SZ = size - 1; // number of bytes to be transferred
|
||||
DMACTL0 = DMA0TSEL_9; // trigger is UART1 receive
|
||||
DMA0CTL = DMADT_0 | // Single transfer mode
|
||||
DMASBDB | // Byte mode
|
||||
DMASRCINCR_3 | // Increment source
|
||||
DMAEN; // Enable DMA
|
||||
/* Configure the DMA transfer */
|
||||
DMA0SA = ((uint16_t) pSource) + 1; /* source DMA address */
|
||||
DMA0DA = (uint16_t) & UART_TX; /* destination DMA address */
|
||||
DMA0SZ = size - 1; /* number of bytes to be transferred */
|
||||
DMACTL0 = DMA0TSEL_9; /* trigger is UART1 receive */
|
||||
DMA0CTL = DMADT_0 | /* Single transfer mode */
|
||||
DMASBDB | /* Byte mode */
|
||||
DMASRCINCR_3 | /* Increment source */
|
||||
DMAEN; /* Enable DMA */
|
||||
if(increment == 0) {
|
||||
DMA0CTL &= ~DMASRCINCR_3;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user