Код: Выделить всё
void SPI_SETUP(uint16_t SPEED)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
GPIO_PinAFConfig(GPIOA,SD_SPI_SCK_SOURCE,GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA,SD_SPI_MISO_SOURCE,GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA,SD_SPI_MOSI_SOURCE,GPIO_AF_SPI1);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SD_SPI_SCK_PIN|SD_SPI_MISO_PIN| SD_SPI_MOSI_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SD_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStructure);
/* SPI_MMC configuration */
SPI_StructInit(&SPI_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPEED; /* 84000kHz /256 = 328 < 400kHz */
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SD_SPI, &SPI_InitStructure);
SPI_Cmd(SD_SPI, ENABLE);
}
//?????????? ? ????????? ????
uint8_t SPI_SEND(uint8_t Data)
{
while(!(SD_SPI->SR & SPI_I2S_FLAG_TXE));
SPI1->DR = Data;
while(!(SD_SPI->SR & SPI_I2S_FLAG_RXNE));
return (SD_SPI->DR);
}
void SPI_CMD2(uint8_t cmd, uint32_t arg, uint8_t crc)
{
SPI_SEND(cmd | 0x40);
SPI_SEND(arg >> 24);
SPI_SEND(arg >> 16);
SPI_SEND(arg >> 8);
SPI_SEND(arg);
SPI_SEND(crc);
}
//?????????? ???????(?????)
uint8_t SPI_CMD(uint8_t cmd, uint32_t arg, uint8_t crc, uint8_t answer)
{
RSD1 = 0;
do
{
RSD2 = 0;
CS();
if (cmd == 41)
SPI_CMD2(55, 0, 0); else SPI_CMD2(cmd, arg, crc);
while((RSD3 = SPI_SEND(0xFF)) == 0xff)
{
_delay(20000);
if(RSD2++ > 0xFE) return 1;
}
if ((cmd == 8)|(cmd == 58))
{
RSD4 = SPI_SEND(0xFF);
SPI_SEND(0xFF);
SPI_SEND(0xFF);
SPI_SEND(0xFF);
}
SPI_SEND(0xFF); //extra 8 CLK
DECS();
if (cmd == 41)
{
RSD2 = 0;
CS();
SPI_CMD2(cmd, arg, crc);
while(SPI_SEND(0xFF) == 0xff)
{
_delay(20000);
if(RSD2++ > 0xFE) return 1;
}
SPI_SEND(0xFF); //extra 8 CLK
DECS();
}
RSD1++;
if(RSD1 > 0xFE) return 1; //time out
}while(RSD3 != answer);
return 0;
}
//????????????? ?????: ????????? = CADR_TYPE
uint8_t SD_INI(void)
{
SPI_SETUP(SPI_BaudRatePrescaler_256);
DECS();
_delay(10000);
for (RSD1 = 0; RSD1<10; RSD1++) SPI_SEND(0xFF);
_delay(10000);
CADR_TYPE = SD_ERROR;
if (SPI_CMD(0, 0, 0x95, 0x01)) return SD_ERROR; //IDLE
if (SPI_CMD(8, 0x01AA, 0x87, 0x01))
{ //VER1.0
if (SPI_CMD(41, 0, 0x95, 0))
{
if (SPI_CMD(1, 0, 0x95, 0x00)) return SD_ERROR;
CADR_TYPE = SD_MMC;
} else
CADR_TYPE = SD_VER1;
}
else
{ //VER2.0
if (SPI_CMD(41, 0x40000000, 0x95, 0)) return SD_ERROR;
if (SPI_CMD(58, 0, 0x95, 0)) return SD_ERROR;
if(RSD4 & 0x40) CADR_TYPE = SD_VER2HC;
else CADR_TYPE = SD_VER2SC;
}
if (CADR_TYPE != SD_VER2HC)
if (SPI_CMD(16, 0x200, 0x95, 0)) return SD_ERROR;
SPI_SETUP(SPI_BaudRatePrescaler_2);
return CADR_TYPE;
}
//?????? ?????? ?????? ? BUFFER: ????????? 1 - ?????? 0 - ??? ??????
uint8_t SD_READ(uint32_t sector)
{
if (CADR_TYPE != SD_VER2HC) sector *= 512;
if (SPI_CMD(17, sector, 0x0, 0x00)) return 1;
CS();
RSD1 = 0;
while(SPI_SEND(0xFF) != 0xFE) //?????? ??????
if(RSD1++ > 0xFFFE)
{
DECS();
return 1;
}
for(RSD2=0; RSD2 < 512; RSD2++)
BUFFER[RSD2] = SPI_SEND(0xFF);
SPI_SEND(0xFF);
SPI_SEND(0xFF);
SPI_SEND(0xFF);
DECS();
return 0;
}
//????? ?????? ?????? ? BUFFER: ????????? 1 - ?????? 0 - ??? ??????
uint8_t SD_WRITE(uint32_t sector)
{
if (CADR_TYPE != SD_VER2HC) sector *= 512;
if (SPI_CMD(24, sector, 0x0, 0x00)) return 1;
CS();
SPI_SEND(0xFE);
for(RSD1=0; RSD1 < 512; RSD1++)
SPI_SEND(BUFFER[RSD1]);
SPI_SEND(0xFF); //CRC
SPI_SEND(0xFF);
RSD2 = SPI_SEND(0xFF);
//????? ?? ????????
if( (RSD2 & 0x1F) != 0x05)
{
DECS();
return RSD2;
}
RSD3 = 0;
while(!SPI_SEND(0xFF))
if(RSD3++ > 0xFFFE)
{
DECS();
return 1;
}
DECS();
SPI_SEND(0xFF);
CS();
RSD3 = 0;
while(!SPI_SEND(0xFF))
if(RSD3++ > 0xFFFE)
{
DECS();
return 1;
}
DECS();
return 0;
}