Bool sbc_read_capacity (void)
{
    U32 mem_size_nb_sector;

    switch (mem_read_capacity (usb_LUN, &mem_size_nb_sector))
    {
    case CTRL_GOOD:
        Usb_reset_endpoint_fifo_access (g_scsi_ep_ms_in);

        // Return nb block.
        Usb_write_endpoint_data (g_scsi_ep_ms_in, 32, sbc_format_mcu_to_scsi_data (32, mem_size_nb_sector));

        // Return block size (= 512 bytes).
        Usb_write_endpoint_data (g_scsi_ep_ms_in, 32, Sbc_format_mcu_to_scsi_data (32, 512));

        Sbc_valid_write_usb (SBC_READ_CAPACITY_LENGTH);
        sbc_lun_status_is_good ();
        return TRUE;

    case CTRL_NO_PRESENT:
        sbc_lun_status_is_not_present ();
        break;

    case CTRL_BUSY:
        sbc_lun_status_is_busy_or_change ();
        break;

    case CTRL_FAIL:
    default:
        sbc_lun_status_is_fail ();
        break;
    }
    return FALSE;
}
Ejemplo n.º 2
0
Archivo: diskio.c Proyecto: gstroe/Arm
DRESULT disk_write(BYTE drv, BYTE const *buff, DWORD sector, UINT count)
{
#if ACCESS_MEM_TO_RAM
	uint8_t uc_sector_size = mem_sector_size(drv);
	uint32_t i;
	uint32_t ul_last_sector_num;

	if (uc_sector_size == 0) {
		return RES_ERROR;
	}

	/* Check valid address */
	mem_read_capacity(drv, &ul_last_sector_num);
	if ((sector + count * uc_sector_size) >
			(ul_last_sector_num + 1) * uc_sector_size) {
		return RES_PARERR;
	}

	/* Write the data */
	for (i = 0; i < count; i++) {
		if (ram_2_memory(drv, sector + uc_sector_size * i,
				buff + uc_sector_size * SECTOR_SIZE_DEFAULT * i) !=
				CTRL_GOOD) {
			return RES_ERROR;
		}
	}

	return RES_OK;

#else
	return RES_ERROR;
#endif
}
Ejemplo n.º 3
0
Archivo: diskio.c Proyecto: gstroe/Arm
/**
 * \brief  Miscellaneous functions, which support the following commands:
 *
 * CTRL_SYNC    Make sure that the disk drive has finished pending write
 * process. When the disk I/O module has a write back cache, flush the
 * dirty sector immediately.
 * In read-only configuration, this command is not needed.
 *
 * GET_SECTOR_COUNT    Return total sectors on the drive into the DWORD variable
 * pointed by buffer.
 * This command is used only in f_mkfs function.
 *
 * GET_BLOCK_SIZE    Return erase block size of the memory array in unit
 * of sector into the DWORD variable pointed by Buffer.
 * When the erase block size is unknown or magnetic disk device, return 1.
 * This command is used only in f_mkfs function.
 *
 * GET_SECTOR_SIZE    Return sector size of the memory array.
 *
 * \param drv Physical drive number (0..).
 * \param ctrl Control code.
 * \param buff Buffer to send/receive control data.
 *
 * \return RES_OK for success, otherwise DRESULT error code.
 */
DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff)
{
	DRESULT res = RES_PARERR;

	switch (ctrl) {
	case GET_BLOCK_SIZE:
		*(DWORD *)buff = 1;
		res = RES_OK;
		break;

	/* Get the number of sectors on the disk (DWORD) */
	case GET_SECTOR_COUNT:
	{
		uint32_t ul_last_sector_num;

		/* Check valid address */
		mem_read_capacity(drv, &ul_last_sector_num);

		*(DWORD *)buff = ul_last_sector_num + 1;

		res = RES_OK;
	}
	break;

	/* Get sectors on the disk (WORD) */
	case GET_SECTOR_SIZE:
	{
		uint8_t uc_sector_size = mem_sector_size(drv);

		if ((uc_sector_size != SECTOR_SIZE_512) &&
				(uc_sector_size != SECTOR_SIZE_1024) &&
				(uc_sector_size != SECTOR_SIZE_2048) &&
				(uc_sector_size != SECTOR_SIZE_4096)) {
			/* The sector size is not supported by the FatFS */
			return RES_ERROR;
		}

		*(uint8_t *)buff = uc_sector_size * SECTOR_SIZE_DEFAULT;

		res = RES_OK;
	}
	break;

	/* Make sure that data has been written */
	case CTRL_SYNC:
		if (mem_test_unit_ready(drv) == CTRL_GOOD) {
			res = RES_OK;
		} else {
			res = RES_NOTRDY;
		}
		break;

	default:
		res = RES_PARERR;
	}

	return res;
}
Ejemplo n.º 4
0
DRESULT disk_write(BYTE drv, BYTE const *buff, DWORD sector, BYTE count)
{
	if (reprap.Debug(moduleStorage))
	{
		debugPrintf("Write %u %u %lu\n", drv, count, sector);
	}

#if ACCESS_MEM_TO_RAM
	MutexLocker lock((drv >= SD_MMC_HSMCI_MEM_CNT) ? Tasks::GetSpiMutex() : nullptr);

	const uint8_t uc_sector_size = mem_sector_size(drv);

	if (uc_sector_size == 0)
	{
		return RES_ERROR;
	}

	/* Check valid address */
	uint32_t ul_last_sector_num;
	mem_read_capacity(drv, &ul_last_sector_num);
	if ((sector + count * uc_sector_size) > (ul_last_sector_num + 1) * uc_sector_size)
	{
		return RES_PARERR;
	}

	/* Write the data */
	unsigned int retryNumber = 0;
	while (ram_2_memory(drv, sector, buff, count) != CTRL_GOOD)
	{
		++retryNumber;
		if (retryNumber == MaxSdCardTries)
		{
			return RES_ERROR;
		}
		delay(SdCardRetryDelay);
	}

	if (retryNumber > highestSdRetriesDone)
	{
		highestSdRetriesDone = retryNumber;
	}

	return RES_OK;

#else
	return RES_ERROR;
#endif
}
Ejemplo n.º 5
0
/*! \brief Sets up USART for shell.
 *
 * \param pba_hz The current module frequency.
 */
static void init_shl_rs232(long pba_hz)
{
  // GPIO map for USART.
  static const gpio_map_t SHL_USART_GPIO_MAP =
  {
    {SHL_USART_RX_PIN, SHL_USART_RX_FUNCTION},
    {SHL_USART_TX_PIN, SHL_USART_TX_FUNCTION}
  };

  // Options for USART.
  static const usart_options_t SHL_USART_OPTIONS =
  {
    .baudrate = SHL_USART_BAUDRATE,
    .charlength = 8,
    .paritytype = USART_NO_PARITY,
    .stopbits = USART_1_STOPBIT,
    .channelmode = USART_NORMAL_CHMODE
  };

  // Set up GPIO for SHL_USART, size of the GPIO map is 2 here.
  gpio_enable_module(SHL_USART_GPIO_MAP,
                     sizeof(SHL_USART_GPIO_MAP) / sizeof(SHL_USART_GPIO_MAP[0]));

  // Initialize it in RS232 mode.
  usart_init_rs232(SHL_USART, &SHL_USART_OPTIONS, pba_hz);
}


/*! \brief Initializes the dataflash memory AT45DBX resources: GPIO, SPI and AT45DBX.
 */
static void at45dbx_resources_init(void)
{
  // GPIO map for SPI.
  static const gpio_map_t AT45DBX_SPI_GPIO_MAP =
  {
    {AT45DBX_SPI_SCK_PIN,          AT45DBX_SPI_SCK_FUNCTION         },  // SPI Clock.
    {AT45DBX_SPI_MISO_PIN,         AT45DBX_SPI_MISO_FUNCTION        },  // MISO.
    {AT45DBX_SPI_MOSI_PIN,         AT45DBX_SPI_MOSI_FUNCTION        },  // MOSI.
#define AT45DBX_ENABLE_NPCS_PIN(NPCS, unused) \
    {AT45DBX_SPI_NPCS##NPCS##_PIN, AT45DBX_SPI_NPCS##NPCS##_FUNCTION},  // Chip Select NPCS.
    MREPEAT(AT45DBX_MEM_CNT, AT45DBX_ENABLE_NPCS_PIN, ~)
#undef AT45DBX_ENABLE_NPCS_PIN
  };

  // Options for SPI.
  spi_options_t spiOptions =
  {
    .reg          = AT45DBX_SPI_FIRST_NPCS,   // Defined in conf_at45dbx.h.
    .baudrate     = AT45DBX_SPI_MASTER_SPEED, // Defined in conf_at45dbx.h.
    .bits         = AT45DBX_SPI_BITS,         // Defined in conf_at45dbx.h.
    .spck_delay   = 0,
    .trans_delay  = 0,
    .stay_act     = 1,
    .spi_mode     = 0,
    .modfdis      = 1
  };

  // Assign I/Os to SPI.
  gpio_enable_module(AT45DBX_SPI_GPIO_MAP,
                     sizeof(AT45DBX_SPI_GPIO_MAP) / sizeof(AT45DBX_SPI_GPIO_MAP[0]));

  // Initialize as master.
  spi_initMaster(AT45DBX_SPI, &spiOptions);

  // Set selection mode: variable_ps, pcs_decode, delay.
  spi_selectionMode(AT45DBX_SPI, 0, 0, 0);

  // Enable SPI.
  spi_enable(AT45DBX_SPI);

  // Initialize data flash with SPI clock Osc0.
  at45dbx_init(spiOptions, FOSC0);
}


/*! \brief Main function. Execution starts here.
 */
int main(void)
{
  U8 i, j;
  U16 file_size;
  Fs_index sav_index;
  static Fs_index mark_index;
  const char *part_type;
  U32 VarTemp;

  // Switch to external oscillator 0.
  pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);

  // Initialize RS232 shell text output.
  init_shl_rs232(FOSC0);

  // Initialize AT45DBX resources: GPIO, SPI and AT45DBX.
  at45dbx_resources_init();

  // Display memory status
  print(SHL_USART, MSG_WELCOME "\nMemory ");

  // Test if the memory is ready - using the control access memory abstraction layer (/SERVICES/MEMORY/CTRL_ACCESS/)
  if (mem_test_unit_ready(LUN_ID_AT45DBX_MEM) == CTRL_GOOD)
  {
    // Get and display the capacity
    mem_read_capacity(LUN_ID_AT45DBX_MEM, &VarTemp);
    print(SHL_USART, "OK:\t");
    print_ulong(SHL_USART, (VarTemp + 1) >> (20 - FS_SHIFT_B_TO_SECTOR));
    print(SHL_USART, " MB\n");
  }