static BYTE send_cmd ( BYTE cmd, /* Command byte */ DWORD arg /* Argument */ ) { BYTE n, res; if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */ cmd &= 0x7F; res = send_cmd(CMD55, 0); if (res > 1) return res; } #if AXI_SPI XStatus Status = XSpi_SetSlaveSelect(&Spi, 0); if(Status != XST_SUCCESS) { xil_printf("Failure Slave Select 0\r\n"); xil_printf("Status = %d\r\n", Status); } rcvr_mmc(); Status = XSpi_SetSlaveSelect(&Spi, 1); if(Status != XST_SUCCESS) { xil_printf("Failure Slave Select 1\r\n"); } rcvr_mmc(); #else /* Select the card */ CS_H(); rcvr_mmc(); CS_L(); rcvr_mmc(); #endif /* Send a command packet */ xmit_mmc(cmd); /* Start + Command index */ xmit_mmc((BYTE)(arg >> 24)); /* Argument[31..24] */ xmit_mmc((BYTE)(arg >> 16)); /* Argument[23..16] */ xmit_mmc((BYTE)(arg >> 8)); /* Argument[15..8] */ xmit_mmc((BYTE)arg); /* Argument[7..0] */ n = 0x01; /* Dummy CRC + Stop */ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ xmit_mmc(n); /* Receive a command response */ n = 10; /* Wait for a valid response in timeout of 10 attempts */ do { res = rcvr_mmc(); } while ((res & 0x80) && --n); return res; /* Return with the response value */ }
void LD_reset(void) //芯片复位 { RST_H(); delay_ms(2); RST_L(); delay_ms(2); RST_H(); delay_ms(2); CS_L(); delay_ms(2); CS_H(); delay_ms(2); }
static void release_spi (void) { #if AXI_SPI XStatus Status = XSpi_SetSlaveSelect(&Spi, 1); if(Status != XST_SUCCESS) { xil_printf("Failure Slave Select release_spi\r\n"); } //DLY_US(1); #else CS_H(); rcvr_mmc(); #endif }
void ld3320_write_reg(uint8 data1,uint8 data2) { CS_L(); SPIS_L(); spi_send_byte(0x04); spi_send_byte(data1); spi_send_byte(data2); CS_H(); }
uint8 ld3320_read_reg(uint8 reg_add) { uint8 i; CS_L(); SPIS_L(); spi_send_byte(0x05); spi_send_byte(reg_add); i=spi_send_byte(0); CS_H(); return(i); }
DSTATUS disk_initialize (void) { BYTE n, cmd, ty, buf[4]; UINT tmr; INIT_PORT(); CS_H(); skip_mmc(10); /* Dummy clocks */ ty = 0; if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc(); /* Get trailing return value of R7 resp */ if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */ if (send_cmd(ACMD41, 1UL << 30) == 0) break; DLY_US(1000); } if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc(); ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */ } } } else { /* SDv1 or MMCv3 */ if (send_cmd(ACMD41, 0) <= 1) { ty = CT_SD1; cmd = ACMD41; /* SDv1 */ } else { ty = CT_MMC; cmd = CMD1; /* MMCv3 */ } for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */ if (send_cmd(cmd, 0) == 0) break; DLY_US(1000); } if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ ty = 0; } } CardType = ty; release_spi(); return ty ? 0 : STA_NOINIT; }
static BYTE send_cmd ( BYTE cmd, /* Command byte */ DWORD arg /* Argument */ ) { BYTE n, res; if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */ cmd &= 0x7F; res = send_cmd(CMD55, 0); if (res > 1) return res; } /* Select the card */ CS_H(); rcvr_mmc(); CS_L(); rcvr_mmc(); /* Send a command packet */ XMIT_MMC(cmd); /* Start + Command index */ XMIT_MMC((BYTE)(arg >> 24)); /* Argument[31..24] */ XMIT_MMC((BYTE)(arg >> 16)); /* Argument[23..16] */ XMIT_MMC((BYTE)(arg >> 8)); /* Argument[15..8] */ XMIT_MMC((BYTE)arg); /* Argument[7..0] */ n = 0x01; /* Dummy CRC + Stop */ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ XMIT_MMC(n); /* Receive a command response */ n = 10; /* Wait for a valid response in timeout of 10 attempts */ do { res = rcvr_mmc(); } while ((res & 0x80) && --n); return res; /* Return with the response value */ }
void ld3320_spi_init(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; //spi端口配置 RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3 | RCC_APB2Periph_GPIOB,ENABLE); //使能SPI3外设时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //P0/P1/P2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB,&GPIO_InitStructure); //spis 片选 WR GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); CS_H(); //spi功能配置 SPI_Cmd(SPI3, DISABLE); /* SPI3 配置 */ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //时钟极性 空闲状态时,SCK保持低电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //时钟相位 数据采样从第一个时钟边沿开始 SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; //软件产生NSS SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //波特率控制 SYSCLK/128 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据高位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC多项式寄存器初始值为7 SPI_Init(SPI3, &SPI_InitStructure); /* 使能SPI3 */ SPI_Cmd(SPI3, ENABLE); }
static void release_spi (void) { CS_H(); rcvr_mmc(); }
DSTATUS disk_initialize (void) { BYTE n, cmd, ty, buf[4]; UINT tmr; #if AXI_SPI /* * Initialize the SPI driver so that it's ready to use, * specify the device ID that is generated in xparameters.h. */ XStatus Status = XSpi_Initialize(&Spi, XPAR_SDCARD_SPI_DEVICE_ID); if(Status != XST_SUCCESS) {\ xil_printf("Failure INIT\r\n"); return XST_FAILURE; } /* * Set the SPI device as a master and in manual slave select mode such * that the slave select signal does not toggle for every byte of a * transfer, this must be done before the slave select is set. */ Status = XSpi_SetOptions(&Spi, XSP_MASTER_OPTION | XSP_MANUAL_SSELECT_OPTION); if(Status != XST_SUCCESS) { xil_printf("Failure Options\r\n"); return XST_FAILURE; } Status = XSpi_SetSlaveSelect(&Spi, 1); if(Status != XST_SUCCESS) { xil_printf("Failure Slave Select\r\n"); return XST_FAILURE; } XSpi_Start(&Spi); XSpi_IntrGlobalDisable(&Spi); DLY_US(1); #else INIT_PORT(); CS_H(); #endif skip_mmc(10); /* Dummy clocks */ ty = 0; if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc(); /* Get trailing return value of R7 resp */ if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */ if (send_cmd(ACMD41, 1UL << 30) == 0) break; DLY_US(1000); } if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc(); ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */ } } } else { /* SDv1 or MMCv3 */ if (send_cmd(ACMD41, 0) <= 1) { ty = CT_SD1; cmd = ACMD41; /* SDv1 */ } else { ty = CT_MMC; cmd = CMD1; /* MMCv3 */ } for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */ if (send_cmd(cmd, 0) == 0) break; DLY_US(1000); } if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ ty = 0; } } CardType = ty; release_spi(); return ty ? 0 : STA_NOINIT; }