Exemplo n.º 1
0
static int destroy_ipsec_tunnel(const str remote_addr, ipsec_t* s)
{
    struct mnl_socket* sock = init_mnl_socket();
    if (sock == NULL) {
        return -1;
    }

    LM_DBG("Destroying security associations: Local IP: %.*s client port: %d server port: %d; UE IP: %.*s; client port %d server port %d\n",
            ipsec_listen_addr.len, ipsec_listen_addr.s, ipsec_client_port, ipsec_server_port,
            remote_addr.len, remote_addr.s, s->port_uc, s->port_us);

    // P-CSCF 'client' tunnel to UE 'server'
    remove_sa    (sock, ipsec_listen_addr, remote_addr, ipsec_client_port, s->port_us, s->spi_us);
    remove_policy(sock, ipsec_listen_addr, remote_addr, ipsec_client_port, s->port_us, s->spi_us, IPSEC_POLICY_DIRECTION_OUT);

    // UE 'client' to P-CSCF 'server' tunnel
    remove_sa    (sock, remote_addr, ipsec_listen_addr, s->port_uc, ipsec_server_port, s->spi_ps);
    remove_policy(sock, remote_addr, ipsec_listen_addr, s->port_uc, ipsec_server_port, s->spi_ps, IPSEC_POLICY_DIRECTION_IN);

    // Release SPIs
    release_spi(s->spi_uc);
    release_spi(s->spi_us);


    close_mnl_socket(sock);
    return 0;
}
Exemplo n.º 2
0
int main(void){

	/* Sample data */
	char *data = "REDPITAYA SPI TEST";

	/* Init the spi resources */
	if(init_spi() < 0){
		printf("Initialization of SPI failed. Error: %s\n", strerror(errno));
		return -1;
	}

	/* Write some sample data */
	if(write_spi(data, strlen(data)) < 0){
		printf("Write to SPI failed. Error: %s\n", strerror(errno));
		return -1;
	}

	/* Read flash ID and some sample loopback data */
	if(read_flash_id(spi_fd) < 0){
		printf("Error reading from SPI bus : %s\n", strerror(errno));
		return -1;
	}

	/* Release resources */
	if(release_spi() < 0){
		printf("Relase of SPI resources failed, Error: %s\n", strerror(errno));
		return -1;
	}

	return 0;
}
Exemplo n.º 3
0
DRESULT mmc_readsector_halp(BYTE *buff, DWORD lba, BYTE top)
{
   DRESULT res;
   BYTE rc;
   WORD bc;

   GREENLEDON();

   if (!(CardType & CT_BLOCK)) lba *= 512;      /* Convert to byte address if needed */

   res = RES_ERROR;
   if (send_cmd(CMD17, lba) == 0) {    /* READ_SINGLE_BLOCK */

      bc = 30000;
      do {                    /* Wait for data packet in timeout of 100ms */
         rc = XFER_SPI(0xff);
      } while (rc == 0xFF && --bc);

      if (rc == 0xFE)
      {
         if (top)
         {
            for (bc = 0; bc < 256; ++bc)
            {
               XFER_SPI(0xff);
            }
         }

         /* A data packet arrived */
         for (bc = 0; bc < 256; ++bc)
         {
            buff[bc] = XFER_SPI(0xff);
         }

         if (!top)
         {
            for (bc = 0; bc < 256; ++bc)
            {
               XFER_SPI(0xff);
            }
         }

         /* Skip CRC */
         XFER_SPI(0xff);
         XFER_SPI(0xff);

         res = RES_OK;
      }
   }

   release_spi();

   GREENLEDOFF();

   return res;
}
Exemplo n.º 4
0
static void power_off (void)
{
	SELECT();				/* Wait for card ready */
	wait_ready();
	release_spi();

	SSP2CON1bits.SSPEN = 0;				/* Disable SPI1 */

	return;
}
Exemplo n.º 5
0
DSTATUS disk_initialize (void)
{
	BYTE n, cmd, ty, buf[4];
	UINT tmr;


//	INIT_PORT();
	mmc_spi_InitSocket();

//	CS_H();
	mmc_spi_SetCardDeselect();
	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);
					mmc_spi_SetTimer(1);
					while( mmc_spi_CheckTimer() ) {}
				}
				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(ACMD41, 0) == 0) break;
//				DLY_US(1000);
				mmc_spi_SetTimer(1);
				while( mmc_spi_CheckTimer() ) {}
			}
			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;

	if ( !ty ) return STA_NOINIT;

	mmc_spi_SetTransClock();
	return 0;
}
Exemplo n.º 6
0
DRESULT disk_readp (
	BYTE *buff,		// Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) 
	DWORD lba,		// Sector number (LBA) 
	WORD ofs,		// Byte offset to read from (0..511) 
	WORD cnt		// Number of bytes to read (ofs + cnt mus be <= 512) 
)
{
	DRESULT res;
	BYTE rc;
	WORD bc;

	if ((PINB&_BV(SD_INS))!=0x00) return RES_ERROR;

	if (!(CardType & CT_BLOCK)) lba *= 512;		// Convert to byte address if needed 

	res = RES_ERROR;
	if (send_cmd(CMD17, lba) == 0) {		// READ_SINGLE_BLOCK 

		bc = 30000;
		do {							// Wait for data packet in timeout of 100ms 
			rc = rcv_spi();
		} while (rc == 0xFF && --bc);

		if (rc == 0xFE) {				// A data packet arrived 
			bc = 514 - ofs - cnt;

			// Skip leading bytes 
			if (ofs) {
				do rcv_spi(); while (--ofs);
			}

			// Receive a part of the sector 
			if (buff) {	// Store data to the memory 
				do
					*buff++ = rcv_spi();
				while (--cnt);
			} else {	// Forward data to the outgoing stream (depends on the project) 
				do 
                ;//uart_transmit(rcv_spi());		// (Console output) 
				while (--cnt);
			}

			// Skip trailing bytes and CRC 
			do rcv_spi(); while (--bc);

			res = RES_OK;
		}
	}

	release_spi();

	return res;
}
Exemplo n.º 7
0
DRESULT disk_readp (
	BYTE *buff,		/* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */
	DWORD lba,		/* Sector number (LBA) */
	WORD ofs,		/* Byte offset to read from (0..511) */
	WORD cnt		/* Number of bytes to read (ofs + cnt mus be <= 512) */
)
{
	DRESULT res;
	BYTE d;
	WORD bc, tmr;


	if (!(CardType & CT_BLOCK)) lba *= 512;		/* Convert to byte address if needed */

	res = RES_ERROR;
	if (send_cmd(CMD17, lba) == 0) {		/* READ_SINGLE_BLOCK */

		tmr = 1000;
		do {							/* Wait for data packet in timeout of 100ms */
//			DLY_US(100);
			mmc_spi_Wait100us();
			d = rcvr_mmc();
		} while (d == 0xFF && --tmr);

		if (d == 0xFE) {				/* A data packet arrived */
			bc = 514 - ofs - cnt;

			/* Skip leading bytes */
			if (ofs) skip_mmc(ofs);

			/* Receive a part of the sector */
//			if (buff) {	/* Store data to the memory */
				do
					*buff++ = rcvr_mmc();
				while (--cnt);
//			} else {	/* Forward data to the outgoing stream */
//				do {
//					d = rcvr_mmc();
//					FORWARD(d);
//				} while (--cnt);
//			}

			/* Skip trailing bytes and CRC */
			skip_mmc(bc);

			res = RES_OK;
		}
	}

	release_spi();

	return res;
}
Exemplo n.º 8
0
DRESULT disk_readp (
	u8 *buff,		/* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */
	u32 lba,		/* Sector number (LBA) */
	u16 ofs,		/* Byte offset to read from (0..511) */
	u16 cnt		/* Number of bytes to read (ofs + cnt mus be <= 512) */
)
{
	DRESULT res;
	u8 rc;
	u16 bc;

	if (!(CardType & CT_BLOCK)) lba *= 512;		/* Convert to byte address if needed */

	res = RES_ERROR;
	if (send_cmd(CMD17, lba) == 0) {		/* READ_SINGLE_BLOCK */
		Tim1 = 200;
		do {							/* Wait for data packet in timeout of 200ms */
			rc = rcvr_spi();
			Tim1 = decreasetim(Tim1);
		} while (rc == 0xFF && Tim1);
	}

	if(Tim1) {
		if (rc == 0xFE) {				/* A data packet arrived */
			bc = 514 - ofs - cnt;


			/* Skip leading bytes */
			if (ofs) {
				do rcvr_spi(); while (--ofs);
			}

			/* Receive a part of the sector */
				do
					*buff++ = rcvr_spi();
				while (--cnt);

			/* Skip trailing bytes and CRC */
			do rcvr_spi(); while (--bc);

			res = cnt ? 1 : RES_OK;
		}
	}

	release_spi();

	return res;
}
Exemplo n.º 9
0
DRESULT disk_writep (
	const BYTE *buff,	// Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) 
	DWORD sa			// Number of bytes to send, Sector number (LBA) or zero 
)
{
	DRESULT res;
	WORD bc;
	static WORD wc;

	if ((PINB&_BV(SD_INS))!=0x00) return RES_ERROR;
	if ((PINB&_BV(SD_WP))!=0x00) return RES_ERROR;

	res = RES_ERROR;

	if (buff) {		// Send data bytes 
		bc = (WORD)sa;
		while (bc && wc) {		// Send data bytes to the card 
			xmit_spi(*buff++);
			wc--; bc--;
		}
		res = RES_OK;
	} else {
		if (sa) {	// Initiate sector write process 
			if (!(CardType & CT_BLOCK)) sa *= 512;	// Convert to byte address if needed 
			if (send_cmd(CMD24, sa) == 0) {			// WRITE_SINGLE_BLOCK 
				xmit_spi(0xFF); xmit_spi(0xFE);		// Data block header 
				wc = 512;							// Set byte counter 
				res = RES_OK;
			}
		} else {	// Finalize sector write process 
			bc = wc + 2;
			while (bc--) xmit_spi(0);	// Fill left bytes and CRC with zeros 
			if ((rcv_spi() & 0x1F) == 0x05) {	// Receive data resp and wait for end of write process in timeout of 300ms 
				for (bc = 65000; rcv_spi() != 0xFF && bc; bc--) ;	// Wait ready 
				if (bc) res = RES_OK;
			}
			release_spi();
		}
	}

	return res;
}
Exemplo n.º 10
0
DRESULT disk_writep (
	const BYTE *buff,	/* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */
	DWORD sa			/* Number of bytes to send, Sector number (LBA) or zero */
)
{
	DRESULT res;
	WORD bc, tmr;
	static WORD wc;


	res = RES_ERROR;

	if (buff) {		/* Send data bytes */
		bc = (WORD)sa;
		while (bc && wc) {		/* Send data bytes to the card */
			xmit_mmc(*buff++);
			wc--; bc--;
		}
		res = RES_OK;
	} else {
		if (sa) {	/* Initiate sector write process */
			if (!(CardType & CT_BLOCK)) sa *= 512;	/* Convert to byte address if needed */
			if (send_cmd(CMD24, sa) == 0) {			/* WRITE_SINGLE_BLOCK */
				xmit_mmc(0xFF); xmit_mmc(0xFE);		/* Data block header */
				wc = 512;							/* Set byte counter */
				res = RES_OK;
			}
		} else {	/* Finalize sector write process */
			bc = wc + 2;
			while (bc--) xmit_mmc(0);	/* Fill left bytes and CRC with zeros */
			if ((rcvr_mmc() & 0x1F) == 0x05) {	/* Receive data resp and wait for end of write process in timeout of 300ms */
				for (tmr = 10000; rcvr_mmc() != 0xFF && tmr; tmr--)	/* Wait for ready (max 1000ms) */
//					DLY_US(100);
					mmc_spi_Wait100us();
				if (tmr) res = RES_OK;
			}
			release_spi();
		}
	}

	return res;
}
Exemplo n.º 11
0
//--------------------------------------------------------------------------
// Initialize Disk Drive                                                 
//--------------------------------------------------------------------------
DSTATUS disk_initialize (void)
{
	BYTE n, cmd, ty, ocr[4];
	WORD tmr;


	INIT_SPI();

	if ((PINB&_BV(SD_INS))!=0x00) return STA_NOINIT;

#if _WRITE_FUNC
	if (MMC_SEL) disk_writep(0, 0);		// Finalize write process if it is in progress 
#endif
	for (n = 100; n; n--) rcv_spi();	// 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++) ocr[n] = rcv_spi();		// Get trailing return value of R7 resp 
			if (ocr[2] == 0x01 && ocr[3] == 0xAA) {				// The card can work at vdd range of 2.7-3.6V 
				for (tmr = 12000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) ;	// Wait for leaving idle state (ACMD41 with HCS bit) 
				if (tmr && send_cmd(CMD58, 0) == 0) {		// Check CCS bit in the OCR 
					for (n = 0; n < 4; n++) ocr[n] = rcv_spi();
					ty = (ocr[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 = 25000; tmr && send_cmd(cmd, 0); tmr--) ;	// Wait for leaving idle state 
			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;
}
Exemplo n.º 12
0
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();
	release_spi();
//	CS_L(); rcvr_mmc();
	mmc_spi_SetCardSelect();

	/* 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 */
}
Exemplo n.º 13
0
DRESULT disk_writep (
	const u8 *buff,	/* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */
	u32 sa			/* Number of bytes to send, Sector number (LBA) or zero */
)
{
	DRESULT res;
	u16 bc;
	static u16 wc;


	res = RES_ERROR;

	if (buff) {		/* Send data bytes */
		bc = (u16)sa;
		while (bc && wc) {		/* Send data bytes to the card */
			xmit_spi(*buff++);
			wc--; bc--;
		}
		res = RES_OK;
	} else {
		if (sa) {	/* Initiate sector write process */
			if (!(CardType & CT_BLOCK)) sa *= 512;	/* Convert to byte address if needed */
			if (send_cmd(CMD24, sa) == 0) {			/* WRITE_SINGLE_BLOCK */
				xmit_spi(0xFF); xmit_spi(0xFE);		/* Data block header */
				wc = 512;							/* Set byte counter */
				res = RES_OK;
			}
		} else {	/* Finalize sector write process */
			bc = wc + 2;
			while (bc--) xmit_spi(0);	/* Fill left bytes and CRC with zeros */
			if ((rcvr_spi() & 0x1F) == 0x05) {	/* Receive data resp and wait for end of write process in timeout of 300ms */
				for (bc = 65000; rcvr_spi() != 0xFF && bc; bc--) ;	/* Wait ready */
				if (bc) res = RES_OK;
			}
			release_spi();
		}
	}

	return res;
}
Exemplo n.º 14
0
DRESULT mmc_writesector(BYTE *buff, DWORD sa)
{
   DRESULT res;
   WORD bc;

   GREENLEDON();

   res = RES_ERROR;

   if (!(CardType & CT_BLOCK)) sa *= 512; /* Convert to byte address if needed */

   if (send_cmd(CMD24, sa) == 0)
   {
      XFER_SPI(0xFF);
      XFER_SPI(0xFE);

      for (bc = 0; bc < 512; ++bc)
      {
         XFER_SPI(buff[bc]);
      }

      XFER_SPI(0);
      XFER_SPI(0);

      if ((XFER_SPI(0xff) & 0x1F) == 0x05)
      {
         /* Receive data resp and wait for end of write process in timeout of 300ms */
         for (bc = 65000; XFER_SPI(0xff) != 0xFF && bc; bc--) ;   /* Wait ready */
         if (bc) res = RES_OK;

         release_spi();
      }
   }

   GREENLEDOFF();

   return res;
}
Exemplo n.º 15
0
DRESULT disk_readp (
	BYTE *buff,		/* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */
	DWORD sector,	/* Sector number (LBA) */
	UINT offset,	/* Byte offset to read from (0..511) */
	UINT count		/* Number of bytes to read (ofs + cnt mus be <= 512) */
)
{
        BYTE *buff_sec = buffer;
	DRESULT res;
	BYTE d;
	UINT bc, tmr;

	if (!(CardType & CT_BLOCK)) sector *= 512;	/* Convert to byte address if needed */

	// check if sector is already in sector buffer
	if(buffer_sector == sector) {
	  buff_sec += offset;  // skip to requested bytes
	  while(count--)
	    *buff++ = *buff_sec++;

	  return RES_OK;
	}

	res = RES_ERROR;
	if (send_cmd(CMD17, sector) == 0) {		/* READ_SINGLE_BLOCK */

		tmr = 1000;
		do {							/* Wait for data packet in timeout of 100ms */
			DLY_US(100);
			d = rcvr_mmc();
		} while (d == 0xFF && --tmr);

		if (d == 0xFE) {				/* A data packet arrived */
			bc = 512 - offset - count;

			/* Skip leading bytes (store in buffer only) */
			while(offset--)
			  *buff_sec++ = rcvr_mmc();

			/* Receive a part of the sector */
			if (buff) {	/* Store data to the memory */
			    do
			        *buff_sec++ = *buff++ = rcvr_mmc();
			    while (--count);
			} else {	/* Forward data to the outgoing stream */
				do {
					*buff_sec++ = d = rcvr_mmc();
					FORWARD(d);
				} while (--count);
			}

			/* Skip trailing bytes (store in buffer only) */
			while(bc--)
			  *buff_sec++ = rcvr_mmc();
			
			/* and skip crc */
			skip_mmc(2);

			buffer_sector = sector;
			res = RES_OK;
		}
	}

	release_spi();

	return res;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
DSTATUS disk_initialize(void)
{
	u8 n, cmd, ty, ocr[4], rep, timeout;
	u16 tmr;

	power_on();							/* Force socket power on */

	for (n = 10; n; n--) xmit_spi(0xFF);	/* Dummy clocks */

	ty = 0;
	timeout=100;

    // Trying to enter Idle state
	do {
		DESELECT();
		xmit_spi(0xFF);
		SELECT();
		rep = send_cmd(CMD0,0);
	} while ((rep != 1) && (--timeout));

    if(timeout == 0)
    {
		DESELECT();
		xmit_spi(0xFF);
		SELECT();
		rep = send_cmd(CMD12,0);
		rep = send_cmd(CMD0,0);
		if (rep != 1)
        {
            return STA_NOINIT;
        }
	}

	rep = send_cmd(CMD8, 0x1AA);

    // SDHC
	if ( rep == 1)
    {
		for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();		/* Get trailing return value of R7 resp */

		if (ocr[2] == 0x01 && ocr[3] == 0xAA) {				/* The card can work at vdd range of 2.7-3.6V */
			for (tmr = 25000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) ;	/* Wait for leaving idle state (ACMD41 with HCS bit) */

			if (tmr && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */
				for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
				ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* SDv2 */
			}
		}

	}

    // SDSC or MMC
    else
    {
		if (send_cmd(ACMD41, 0) <= 1) 	{
			ty = CT_SD1; cmd = ACMD41;	/* SDv1 */
		} else {
			ty = CT_MMC; cmd = CMD1;	/* MMCv3 */
		}

		for (tmr = 25000; tmr && send_cmd(cmd, 0); tmr--) ;	/* Wait for leaving idle state */

		if (!tmr || send_cmd(CMD16, 512) != 0)			/* Set R/W block length to 512 */
			ty = 0;

	}

	CardType = ty;
	release_spi();

    // Initialization succeded
	if (ty)
    {
		FCLK_FAST();
		return RES_OK;
	}

    // Initialization failed
    else
    {
		power_off();
		return STA_NOINIT;
	}
}
Exemplo n.º 18
0
DRESULT disk_readp (
	BYTE *buff,		/* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */
	DWORD lba,		/* Sector number (LBA) */
	WORD ofs,		/* Byte offset to read from (0..511) */
	WORD cnt		/* Number of bytes to read (ofs + cnt mus be <= 512) */
)
{

#if 0
	xil_printf("\n\n");
	xil_printf("lba = %d\n", lba);
	xil_printf("ofs = %d\n", ofs);
	xil_printf("cnt = %d\n", cnt);
#endif


	typedef struct LRUEntry {
		bool valid;
		DWORD lba_key;
		BYTE buffer[512];
		struct LRUEntry* more_recently_used;
		struct LRUEntry* less_recently_used;
	} LRUEntry;

#define NUM_LRU_ENTRIES 2 // At least 2
	static LRUEntry* least_recently_used_entry = 0;
	static LRUEntry* most_recently_used_entry = 0;
	static LRUEntry read_buff_lru[NUM_LRU_ENTRIES];

	static BYTE write_buff[512];
	// Init once.
	if(!write_buff[0]){
		memset(write_buff, 0xff, 512);

		// 0 is most recent and NUM_LRU_ENTRIES-1 is least recent.
		read_buff_lru[0].valid = false;
		read_buff_lru[0].more_recently_used = NULL;
		read_buff_lru[0].less_recently_used = &read_buff_lru[1];
		most_recently_used_entry = &read_buff_lru[0];
		for(int i = 1; i < NUM_LRU_ENTRIES-1; i++){
			read_buff_lru[i].valid = false;
			read_buff_lru[i].more_recently_used = &read_buff_lru[i-1];
			read_buff_lru[i].less_recently_used = &read_buff_lru[i+1];
		}
		read_buff_lru[NUM_LRU_ENTRIES-1].valid = false;
		read_buff_lru[NUM_LRU_ENTRIES-1].more_recently_used = &read_buff_lru[NUM_LRU_ENTRIES-2];
		read_buff_lru[NUM_LRU_ENTRIES-1].less_recently_used = NULL;
		least_recently_used_entry = &read_buff_lru[NUM_LRU_ENTRIES-1];
	}

	// Search for entry...
	for(int i = 0; i < NUM_LRU_ENTRIES; i++){
		if(read_buff_lru[i].valid && read_buff_lru[i].lba_key == lba){
		 	if(buff){
		 		memcpy(buff, read_buff_lru[i].buffer + ofs, cnt);
		 	}
		 	LRUEntry* curr_entry = &read_buff_lru[i];

		 	// Update LRU list.
		 	if(curr_entry != most_recently_used_entry){
				if(curr_entry == least_recently_used_entry){
					least_recently_used_entry = curr_entry->more_recently_used;
					least_recently_used_entry->less_recently_used = NULL;
				}
				most_recently_used_entry->more_recently_used = curr_entry;
				curr_entry->less_recently_used = most_recently_used_entry;
				curr_entry->more_recently_used = NULL;
				most_recently_used_entry = curr_entry;
		 	}
		 	return RES_OK;
		}
	}

	// Took least recently used entry to read to it.
	// Update LRU list.
	LRUEntry* curr_entry = least_recently_used_entry;
	// Setting new least recently used.
	least_recently_used_entry = curr_entry->more_recently_used;
	least_recently_used_entry->less_recently_used = NULL;
	// Prepending new most recently used.
	most_recently_used_entry->more_recently_used = curr_entry;
	curr_entry->less_recently_used = most_recently_used_entry;
	curr_entry->more_recently_used = NULL;
	most_recently_used_entry = curr_entry;

	curr_entry->valid = true;
	curr_entry->lba_key = lba;
	BYTE* read_buff = curr_entry->buffer;


	if (!(CardType & CT_BLOCK)) lba *= 512;		/* Convert to byte address if needed */

	DRESULT res = RES_ERROR;
	if (send_cmd(CMD17, lba) == 0) {		/* READ_SINGLE_BLOCK */
		BYTE d;

		int tmr = 100000;
		do {							/* Wait for data packet in timeout of 100ms */
			DLY_US(1);
			d = rcvr_mmc();
		} while (d == 0xFF && --tmr);

		if (d == 0xFE) {				/* A data packet arrived */
			XStatus Status = XSpi_Transfer(&Spi, write_buff, read_buff, 512);
		 	if(Status != XST_SUCCESS) {
				xil_printf("Error in read transfer\r\n");
				return res;
			}
		 	if(buff){
		 		memcpy(buff, read_buff + ofs, cnt);
		 	}

			res = RES_OK;
		}
	}

	release_spi();

	return res;
}
Exemplo n.º 19
0
DSTATUS mmc_initialize (void)
{
   BYTE n, cmd, ty, ocr[4];
   WORD tmr;

   GREENLEDON();

   INIT_SPI();

#if _WRITE_FUNC
   if (MMC_SEL) disk_writep(0, 0);     /* Finalize write process if it is in progress */
#endif
   for (n = 11; n; --n) XFER_SPI(0xff);   /* 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++)
         {
            ocr[n] = XFER_SPI(0xff);      /* Get trailing return value of R7 resp */
         }
         if (ocr[2] == 0x01 && ocr[3] == 0xAA)
         {
            /* The card can work at vdd range of 2.7-3.6V */
            for (tmr = 12000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) ; /* Wait for leaving idle state (ACMD41 with HCS bit) */

            if (tmr && send_cmd(CMD58, 0) == 0)
            {
               /* Check CCS bit in the OCR */
               for (n = 0; n < 4; n++) ocr[n] = XFER_SPI(0xff);
               ty = (ocr[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 = 25000; tmr && send_cmd(cmd, 0); tmr--) ;   /* Wait for leaving idle state */

         if (!tmr || send_cmd(CMD16, 512) != 0)       /* Set R/W block length to 512 */
         {
            ty = 0;
         }
      }
   }
   CardType = ty;
   release_spi();

   GREENLEDOFF();

   return ty ? 0 : STA_NOINIT;
}