hi all, :wave: i will like to know how to continuous write data to a sd with incrementing address. i'm using msp430f149 microcontroller. thank you very much.
Printable View
hi all, :wave: i will like to know how to continuous write data to a sd with incrementing address. i'm using msp430f149 microcontroller. thank you very much.
Depends on how you have the card interfaced, what language you're using, etc.
i can use both c language as well as assembly language...i'm using SPI interface...i noe how to initialise...but i donno how to transmit data to the sd card with incrementing address in the sd card...pls help...
int main( void )
{
WDTCTL = WDTPW + WDTHOLD;
CCTL1 = CCIE; // CCR1 interrupt enabled
CCR1 = 50000;
TACTL = TASSEL_2 + MC_2; // SMCLK, Contmode
//Initialisation of the MMC/SD-card
while (status != 0) // if return in not NULL an error did occur and the
// MMC/SD-card will be initialized again
{
status = initMMC();
timeout++;
if (timeout == 50) // Try 50 times till error
{
printf ("Waiting for SD card to be inserted...\n");
break;
}
}
while ((mmc_ping() != MMC_SUCCESS)); // Wait till card is inserted
// Read the Card Size from the CSD Register
cardSize = MMC_ReadCardSize();
No sample code with the interface?
#ifndef _MMCLIB_CQuote:
Originally Posted by Al42
#define _MMCLIB_C
//
//---------------------------------------------------------------
#include "mmc.h"
#include "msp430x44x.h"
#include <stdio.h>
//#define withDMA
// Function Prototypes
char mmcGetResponse(void);
char mmcGetXXResponse(const char resp);
char mmcCheckBusy(void);
void initSPI (void);
unsigned char spiSendByte(const unsigned char data);
char mmc_GoIdle();
// Varialbes
char mmc_buffer[512] = { 0 }; // Buffer for mmc i/o for data and registers
//---------------------------------------------------------------------
// setup usart1 in spi mode
void initSPI (void)
{
UCTL1 = SWRST; // 8-bit SPI Master **SWRST**
UTCTL1 = CKPH | SSEL1 | SSEL0 | STC; // SMCLK, 3-pin mode, clock idle low, data valid on rising edge, UCLK delayed
UBR01 = 0x02; // 0x02: UCLK/2 (4 MHz), works also with 3 and 4
UBR11 = 0x00; // -"-
UMCTL1 = 0x00; // no modulation
UCTL1 = CHAR | SYNC | MM | SWRST; // 8-bit SPI Master **SWRST**
UCTL1 &= ~SWRST; // clear SWRST
ME2 |= USPIE1; // Enable USART1 SPI mode
while (!(IFG2 & UTXIFG1)); // USART1 TX buffer ready (empty)?
}
// Initialize MMC card
char initMMC (void)
{
//raise SS and MOSI for 80 clock cycles
//SendByte(0xff) 10 times with SS high
//RAISE SS
int i;
// Port 5 Function Dir On/Off
// 5.0-mmcCD Out 0 - card inserted
// 5.1-Dout Out 0 - off 1 - On -> init in SPI_Init
// 5.2-Din Inp 0 - off 1 - On -> init in SPI_Init
// 5.3-Clk Out - -> init in SPI_Init
// 5.4-mmcCS Out 0 - Active 1 - none Active
P5SEL |= 0x0E;
P5SEL &= ~0x11;
P5OUT |= 0x10;
P5DIR |= 0x1A;
initSPI();
//initialization sequence on PowerUp
CS_HIGH();
for(i=0;i<=9;i++)
spiSendByte(0xff);
return (mmc_GoIdle());
}
char mmc_GoIdle()
{
char response=0x01;
CS_LOW();
//Send Command 0 to put MMC in SPI mode
mmcSendCmd(MMC_GO_IDLE_STATE,0,0x95);
//Now wait for READY RESPONSE
if(mmcGetResponse()!=0x01)
return MMC_INIT_ERROR;
while(response==0x01)
{
CS_HIGH();
spiSendByte(0xff);
CS_LOW();
mmcSendCmd(MMC_SEND_OP_COND,0x00,0xff);
response=mmcGetResponse();
}
CS_HIGH();
spiSendByte(0xff);
return (MMC_SUCCESS);
}
// mmc Get Responce
char mmcGetResponse(void)
{
//Response comes 1-8bytes after command
//the first bit will be a 0
//followed by an error code
//data will be 0xff until response
int i=0;
char response;
while(i<=64)
{
response=spiSendByte(0xff);
if(response==0x00)break;
if(response==0x01)break;
i++;
}
return response;
}
char mmcGetXXResponse(const char resp)
{
//Response comes 1-8bytes after command
//the first bit will be a 0
//followed by an error code
//data will be 0xff until response
int i=0;
char response;
while(i<=1000)
{
response=spiSendByte(0xff);
if(response==resp)break;
i++;
}
return response;
}
char mmcCheckBusy(void)
{
//Response comes 1-8bytes after command
//the first bit will be a 0
//followed by an error code
//data will be 0xff until response
int i=0;
char response;
char rvalue;
while(i<=64)
{
response=spiSendByte(0xff);
response &= 0x1f;
switch(response)
{
case 0x05: rvalue=MMC_SUCCESS;break;
case 0x0b: return(MMC_CRC_ERROR);
case 0x0d: return(MMC_WRITE_ERROR);
default:
rvalue = MMC_OTHER_ERROR;
break;
}
if(rvalue==MMC_SUCCESS)break;
i++;
}
i=0;
do
{
response=spiSendByte(0xff);
i++;
}while(response==0);
return response;
}
// The card will respond with a standard response token followed by a data
// block suffixed with a 16 bit CRC.
char mmcReadBlock(const unsigned long address, const unsigned long count, unsigned char *pBuffer)
{
unsigned long i = 0;
char rvalue = MMC_RESPONSE_ERROR;
// Set the block length to read
if (mmcSetBlockLength (count) == MMC_SUCCESS) // block length could be set
{
// SS = LOW (on)
CS_LOW ();
// send read command MMC_READ_SINGLE_BLOCK=CMD17
mmcSendCmd (MMC_READ_SINGLE_BLOCK,address, 0xFF);
// Send 8 Clock pulses of delay, check if the MMC acknowledged the read block command
// it will do this by sending an affirmative response
// in the R1 format (0x00 is no errors)
if (mmcGetResponse() == 0x00)
{
// now look for the data token to signify the start of
// the data
if (mmcGetXXResponse(MMC_START_DATA_BLOCK_TOKEN) == MMC_START_DATA_BLOCK_TOKEN)
{
#ifndef withDMA
// clock the actual data transfer and receive the bytes; spi_read automatically finds the Data Block
for (i = 0; i < count; i++)
pBuffer[i] = spiSendByte(0xff); // is executed with card inserted
#else
U1IFG &= ~(URXIFG1 + URXIFG1); /* clear flags */
/* Get the block */
/* DMA trigger is UART1 receive for both DMA0 and DMA1 */
DMACTL0 &= ~(DMA0TSEL_15 | DMA1TSEL_15);
DMACTL0 |= (DMA0TSEL_9 | DMA1TSEL_9);
/* Source DMA address: receive register. */
DMA0SA = U1RXBUF_;
/* Destination DMA address: the user data buffer. */
DMA0DA = (unsigned short)pBuffer;
/* The size of the block to be transferred */
DMA0SZ = count;
/* Configure the DMA transfer*/
DMA0CTL =
DMAIE | /* Enable interrupt */
DMADT_0 | /* Single transfer mode */
DMASBDB | /* Byte mode */
DMAEN | /* Enable DMA */
DMADSTINCR1 | DMADSTINCR0; /* Increment the destination address */
/* We depend on the DMA priorities here. Both triggers occur at
the same time, since the source is identical. DMA0 is handled
first, and retrieves the byte. DMA1 is triggered next, and
sends the next byte. */
/* Source DMA address: constant 0xFF (don't increment)*/
DMA1SA = U1TXBUF_;
/* Destination DMA address: the transmit buffer. */
DMA1DA = U1TXBUF_;
/* Increment the destination address */
/* The size of the block to be transferred */
DMA1SZ = count-1;
/* Configure the DMA transfer*/
DMA1CTL =
DMADT_0 | /* Single transfer mode */
DMASBDB | /* Byte mode */
DMAEN; /* Enable DMA */
/* Kick off the transfer by sending the first byte */
U1TXBUF = 0xFF;
// while (DMA0CTL & DMAEN) _NOP(); //LPM0; // wait till done
// while (DMA0CTL & DMAEN) _EINT(); LPM0; // wait till done
_EINT(); LPM0; // wait till done
#endif
// get CRC bytes (not really needed by us, but required by MMC)
spiSendByte(0xff);
spiSendByte(0xff);
rvalue = MMC_SUCCESS;
}
else
{
// the data token was never received
rvalue = MMC_DATA_TOKEN_ERROR; // 3
}
}
else
{
// the MMC never acknowledge the read command
rvalue = MMC_RESPONSE_ERROR; // 2
}
}
else
{
rvalue = MMC_BLOCK_SET_ERROR; // 1
}
CS_HIGH ();
spiSendByte(0xff);
return rvalue;
}// mmc_read_block
I merely use the power supply to provide enough current for the write process to work. Thanks all for your advice.