Esempio n. 1
0
static int nor_write(mtd_t *_dev, void *_src, uint32_t _off, int _amt)
{
	nor_device_t *dev = nor_device_get(_dev);
	int startSector = _off / NOR_BLOCK_SIZE;
	int endSector = (_off + _amt) / NOR_BLOCK_SIZE;

	int numSectors = endSector - startSector + 1;
	uint8_t* sectorsToChange = (uint8_t*) malloc(NOR_BLOCK_SIZE * numSectors);
	nor_read(_dev, sectorsToChange, startSector * NOR_BLOCK_SIZE, NOR_BLOCK_SIZE * numSectors);

	int offsetFromStart = _off - (startSector * NOR_BLOCK_SIZE);

	memcpy(sectorsToChange + offsetFromStart, _src, _amt);

	int i;
	for(i = 0; i < numSectors; i++) {
		if(nor_erase_sector(dev, (i + startSector) * NOR_BLOCK_SIZE) != 0)
			return -1;

		int j;
		uint16_t* curSector = (uint16_t*)(sectorsToChange + (i * NOR_BLOCK_SIZE));
		for(j = 0; j < NOR_BLOCK_SIZE; j += 2)
		{
			if(nor_write_short(dev, ((i + startSector) * NOR_BLOCK_SIZE) + j, curSector[j/2]) != 0)
				return -1;
		}
	}

	free(sectorsToChange);

	return 0;
}
Esempio n. 2
0
void images_erase(Image* image) {
	if(image == NULL)
		return;

	nor_erase_sector(image->offset);

	images_release();
	images_setup();
}
Esempio n. 3
0
void cmd_nor_erase(int argc, char** argv) {
	if(argc < 3) {
		bufferPrintf("Usage: %s <address> <address again for confirmation>\r\n", argv[0]);
		return;
	}
	
	uint32_t addr1 = parseNumber(argv[1]);
	uint32_t addr2 = parseNumber(argv[2]);

	if(addr1 != addr2) {
		bufferPrintf("0x%x does not match 0x%x\r\n", addr1, addr2);
		return;
	}

	bufferPrintf("Erasing 0x%x - 0x%x...\r\n", addr1, addr1 + getNORSectorSize());
	nor_erase_sector(addr1);
	bufferPrintf("Done.\r\n");
}
Esempio n. 4
0
int main(void)
{
	SetupHardware();
	sei();

	// Initialize the USB, and then wait for the host to set configuration.
	// If the Teensy is powered without a PC connected to the USB port,
	// this will wait forever.
	while (USB_DeviceState != DEVICE_STATE_Configured)  /* wait */
		USB_USBTask();

	//configure all i/o lines (and set tristate=low)
	//nor_initports();
	nand_initports();

	// Wait an extra second for the PC's operating system to load drivers
	// and do whatever it does to actually be ready for input
	_delay_ms(1000);

	usbio_initbuffers();

	int16_t command = -1;
	uint8_t nand_id = 0;
	uint16_t nand_block = 0;

	while (1) {
		USB_USBTask();
		while (USB_DeviceState == DEVICE_STATE_Configured) { // is user still connected?
			command = usbio_get_byte();
			if (command == -1) continue;

			switch (command) {
			case CMD_GETVERSION:
				usbio_set_byte(NANDORWAY_MAJOR_VERSION, 0);
				usbio_set_byte(NANDORWAY_MINOR_VERSION, 0);
				usbio_set_byte(NANDORWAY_BUILD_VERSION, 1);
				break;
			case CMD_PING:
				usbio_set_byte(0x42, 0);
				usbio_set_byte(0xbd, 1);
				break;
			case CMD_BOOTLOADER:
				bootloader();
				break;
			case CMD_SPEEDTEST_READ:
				speedtest_send();
				break;
			case CMD_SPEEDTEST_WRITE:
				speedtest_receive();
				break;
			case CMD_IO_LOCK:
				nor_initports();
				break;
			case CMD_IO_RELEASE:
				nor_releaseports();
				break;
			case CMD_NOR_ID:
				nor_id();
				break;
			case CMD_NOR_RESET:
				nor_reset();
				break;
			case CMD_NOR_ERASE_SECTOR:
				nor_erase_sector();
				break;
			case CMD_NOR_ERASE_CHIP:
				nor_erase_chip();
				break;
			case CMD_NOR_ADDRESS_SET:
				nor_address_set(usbio_get_byte(), usbio_get_byte(), usbio_get_byte());
				break;
			case CMD_NOR_ADDRESS_INCREMENT:
				nor_address_increment(1);
				break;
			case CMD_NOR_ADDRESS_INCREMENT_ENABLE:
				nor_address_increment_set(1);
				break;
			case CMD_NOR_ADDRESS_INCREMENT_DISABLE:
				nor_address_increment_set(0);
				break;
			case CMD_NOR_2ND_DIE_ENABLE:
				nor_2nd_die_offset(0x40); //A22=HIGH for Samsung K8Q2815
				break;
			case CMD_NOR_2ND_DIE_DISABLE:
				nor_2nd_die_offset(0x00); //A22=LOW for Samsung K8Q2815
				break;
			case CMD_NOR_READ_WORD:
				nor_read(NOR_BSS_WORD, 1);
				break;
			case CMD_NOR_READ_BLOCK_4KB:
				nor_read(NOR_BSS_4, 1);
				break;
			case CMD_NOR_READ_BLOCK_8KB:
				nor_read(NOR_BSS_8, 1);
				break;
			case CMD_NOR_READ_BLOCK_64KB:
				nor_read(NOR_BSS_64, 1);
				break;
			case CMD_NOR_READ_BLOCK_128KB:
				nor_read(NOR_BSS_128, 1);
				break;
			case CMD_NOR_WRITE_WORD:
				nor_write_word();
				break;
			case CMD_NOR_WRITE_BLOCK_WORD:
				nor_write_block(NOR_PRG_MODE_WORD);
				break;
			case CMD_NOR_WRITE_BLOCK_UBM:
				nor_write_block(NOR_PRG_MODE_UBM);
				break;
			case CMD_NOR_WRITE_BLOCK_WBP:
				nor_write_block(NOR_PRG_MODE_WBP);
				break;
			case CMD_NAND_ID:
				switch (nand_id) {
				case 0:
					if (init_nand(&nand0) == 1) {
						//24 bytes
						usbio_set_byte(nand0.info.maker_code, 0);
						usbio_set_byte(nand0.info.device_code, 0);
						usbio_set_byte((nand0.info.page_size >> 24) & 0xFF, 0);
						usbio_set_byte((nand0.info.page_size >> 16) & 0xFF, 0);
						usbio_set_byte((nand0.info.page_size >> 8) & 0xFF, 0);
						usbio_set_byte(nand0.info.page_size & 0xFF, 0);
						usbio_set_byte(nand0.info.oob->size, 0);
						usbio_set_byte((nand0.info.block_size >> 24) & 0xFF, 0);
						usbio_set_byte((nand0.info.block_size >> 16) & 0xFF, 0);
						usbio_set_byte((nand0.info.block_size >> 8) & 0xFF, 0);
						usbio_set_byte(nand0.info.block_size & 0xFF, 0);
						usbio_set_byte((nand0.info.num_blocks >> 24) & 0xFF, 0);
						usbio_set_byte((nand0.info.num_blocks >> 16) & 0xFF, 0);
						usbio_set_byte((nand0.info.num_blocks >> 8) & 0xFF, 0);
						usbio_set_byte(nand0.info.num_blocks & 0xFF, 0);
						usbio_set_byte(nand0.info.num_planes, 0);
						usbio_set_byte((nand0.info.plane_size >> 56) & 0xFF, 0);
						usbio_set_byte((nand0.info.plane_size >> 48) & 0xFF, 0);
						usbio_set_byte((nand0.info.plane_size >> 40) & 0xFF, 0);
						usbio_set_byte((nand0.info.plane_size >> 32) & 0xFF, 0);
						usbio_set_byte((nand0.info.plane_size >> 24) & 0xFF, 0);
						usbio_set_byte((nand0.info.plane_size >> 16) & 0xFF, 0);
						usbio_set_byte((nand0.info.plane_size >> 8) & 0xFF, 0);
						usbio_set_byte(nand0.info.plane_size & 0xFF, 1);
					}
					else {
						for (uint8_t i = 0; i < 23; ++i)
							usbio_set_byte(0xFF, 0);
						usbio_set_byte(0xFF, 1);
					}
					break;
				case 1:
					if (init_nand(&nand1) == 1) {
						//24 bytes
						usbio_set_byte(nand1.info.maker_code, 0);
						usbio_set_byte(nand1.info.device_code, 0);
						usbio_set_byte((nand1.info.page_size >> 24) & 0xFF, 0);
						usbio_set_byte((nand1.info.page_size >> 16) & 0xFF, 0);
						usbio_set_byte((nand1.info.page_size >> 8) & 0xFF, 0);
						usbio_set_byte(nand1.info.page_size & 0xFF, 0);
						usbio_set_byte(nand1.info.oob->size, 0);
						usbio_set_byte((nand1.info.block_size >> 24) & 0xFF, 0);
						usbio_set_byte((nand1.info.block_size >> 16) & 0xFF, 0);
						usbio_set_byte((nand1.info.block_size >> 8) & 0xFF, 0);
						usbio_set_byte(nand1.info.block_size & 0xFF, 0);
						usbio_set_byte((nand1.info.num_blocks >> 24) & 0xFF, 0);
						usbio_set_byte((nand1.info.num_blocks >> 16) & 0xFF, 0);
						usbio_set_byte((nand1.info.num_blocks >> 8) & 0xFF, 0);
						usbio_set_byte(nand1.info.num_blocks & 0xFF, 0);
						usbio_set_byte(nand1.info.num_planes, 0);
						usbio_set_byte((nand1.info.plane_size >> 56) & 0xFF, 0);
						usbio_set_byte((nand1.info.plane_size >> 48) & 0xFF, 0);
						usbio_set_byte((nand1.info.plane_size >> 40) & 0xFF, 0);
						usbio_set_byte((nand1.info.plane_size >> 32) & 0xFF, 0);
						usbio_set_byte((nand1.info.plane_size >> 24) & 0xFF, 0);
						usbio_set_byte((nand1.info.plane_size >> 16) & 0xFF, 0);
						usbio_set_byte((nand1.info.plane_size >> 8) & 0xFF, 0);
						usbio_set_byte(nand1.info.plane_size & 0xFF, 1);
					}
					else {
						for (uint8_t i = 0; i < 23; ++i)
							usbio_set_byte(0xFF, 0);
						usbio_set_byte(0xFF, 1);
					}
					break;
				default:
					break;
				}