Esempio n. 1
0
// C implemtation for computer
uint16_t compute_crc(char *data, int len){
        uint16_t crc = 0xffff;
        int i;
        for(i=0; i<len; i++){
                crc=crc16_update(crc,data[i]);
        }
        return crc;
}
Esempio n. 2
0
uint16_t crc16_calculate(const uint8_t *buf, size_t len)
{
        uint16_t crc;

        crc16_init(&crc);
        crc16_update(&crc, buf, len);

        return crc;
}
Esempio n. 3
0
//! @brief Calculate crc over framing data packet.
static uint16_t calculate_framing_crc16(framing_data_packet_t * packet, const uint8_t * data)
{
    uint16_t crc16;

    // Initialize the CRC16 information
    crc16_data_t crcInfo;
    crc16_init(&crcInfo);

    // Run CRC on all header bytes besides the CRC field
    crc16_update(&crcInfo, (uint8_t *)&packet->header.startByte, sizeof(framing_data_packet_t) - sizeof(uint16_t));

    // Continue running CRC on any payload bytes
    crc16_update(&crcInfo, data, packet->length);

    // Finalize the CRC calculations
    crc16_finalize(&crcInfo, &crc16);

    return crc16;
}
static int hinge_bl_send_cmd(struct hinge_data *data, uint8_t cmd, uint32_t *args, uint8_t count)
{
	int err;
	struct i2c_client *client;
	struct i2c_msg msg[1];
	uint8_t buf[10 + sizeof(uint32_t) * count];
	uint16_t packet_len;

	/* validate args */
	if (!data || (!args && count > 0) || count > 7) {
		dev_err(data->dev, "%s: invalid args: data=%p cmd=%02x args=%p count=%u\n",
				__func__, data, cmd, args, count);
		return -EINVAL;
	}

	client = to_i2c_client(data->dev);

	/* packet length is size of payload after framing header */
	packet_len = 4 + sizeof(uint32_t) * count;

	/* setup framing packet */
	buf[0] = MCU_PACKET_START_BYTE;
	buf[1] = MCU_PACKET_TYPE_COMMAND;
	buf[2] = packet_len; /* packet len low */
	buf[3] = packet_len >> 8; /* packet len high */
	buf[4] = 0x00; /* crc16 low (updated later) */
	buf[5] = 0x00; /* crc16 high (updated later) */

	/* setup command packet */
	buf[6] = cmd; /* command */
	buf[7] = 0x00; /* flags */
	buf[8] = 0x00; /* reserved */
	buf[9] = count; /* param count */

	/* copy the args into the packet */
	if (args)
		memcpy(&buf[10], args, sizeof(uint32_t) * count);

	crc16_update(buf, sizeof(buf));

	msg[0].addr = HINGE_BL_SLAVE_ADDRESS;
	msg[0].flags = 0;
	msg[0].len = sizeof(buf);
	msg[0].buf = (void *) buf;

	err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
	CHECK_ERROR(err < 0, error, "Failed to send command packet: %d\n", err);

	err = hinge_bl_read_ack(data);

error:
	return err;
}
Esempio n. 5
0
uint16_t SPIreaddata(int len)
{
    int result;
    int tries = 1000;
    do {
        result = SPIxfer(0xff);
        if (tries-- <= 0) return -1;
    } while (result != 0xfe);

    uint16_t crc = 0;
    for (int i = 0; i < len; i++) {
        uint8_t dat = sdbuf[i] = SPIxfer(0xff);
        crc16_update(crc, dat);
    }

    uint16_t recv_crc = SPIread16();

    printf("Calculated CRC %04x, received CRC %04x\n", crc, recv_crc);
    return crc != recv_crc;
}
Esempio n. 6
0
uint8_t reprog_restart(void)
{
    uint16_t address, length, crc;

    /* Read code length and crc */
    eeprom_mcu_read((uint8_t*)&length, 3, 4);
    eeprom_mcu_read((uint8_t*)&crc, 5, 6);

    /* Calculate CRC and compare to stored value */
    crc16_init();
    for (uint16_t i = CODE_HEADER_SIZE; i < length + CODE_HEADER_SIZE; i++) {
        eeprom_mcu_read(buffer, address, address);
        crc16_update(buffer[0]);
    }

    /* Only restart if CRC matches */
    if (crc != crc16_read()) {
        return false;
    }

    /* Copy from upper half of memory to lower half */
    for (uint8_t j = 0; j < (MEM_SIZE / BUFFER_SIZE); j++) {
        address = j * BUFFER_SIZE;
        eeprom_mcu_read(buffer, address, address + (BUFFER_SIZE - 1));
        mem_eeprom_CodeSection(true);
        eeprom_mcu_write(buffer, address, address + (BUFFER_SIZE - 1));
        mem_eeprom_CodeSection(false);
    }

    /* Reset address = 0x8000 (bootloader) */
    RSTREAS |= BIT(RFLR1);
    
    /* Start watchdog timer */
    regx_write(WD, 1);
    
    /* Wait for WDT to timeout */
    for(;;) {
        ;
    }
}
static int hinge_bl_send_data(struct hinge_data *data, const void *payload, uint16_t len)
{
	int err;
	struct i2c_client *client;
	struct i2c_msg msg[1];
	uint8_t buf[6 + len];

	/* validate args */
	if (!payload || len > 32)
		return -EINVAL;

	client = to_i2c_client(data->dev);

	buf[0] = MCU_PACKET_START_BYTE; /* start byte */
	buf[1] = MCU_PACKET_TYPE_DATA; /* data packet */
	buf[2] = len; /* length low */
	buf[3] = len >> 8; /* length high */
	buf[4] = 0x00; /* crc low */
	buf[5] = 0x00; /* crc high */

	memcpy(&buf[6], payload, len);

	crc16_update(buf, sizeof(buf));

	msg[0].addr = HINGE_BL_SLAVE_ADDRESS;
	msg[0].flags = 0;
	msg[0].len = sizeof(buf);
	msg[0].buf = (void *) buf;

	err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
	CHECK_ERROR(err < 0, error, "Failed to send data packet: %d\n", err);

	err = hinge_bl_read_ack(data);

error:
	return err;
}
Esempio n. 8
0
u8 XN297_WritePayload(u8* msg, int len)
{
    u8 packet[32];
    u8 res;
    if (is_xn297) {
        res = NRF24L01_WritePayload(msg, len);
    } else {
        int last = 0;
        if (xn297_addr_len < 4) {
            // If address length (which is defined by receive address length)
            // is less than 4 the TX address can't fit the preamble, so the last
            // byte goes here
            packet[last++] = 0x55;
        }
        for (int i = 0; i < xn297_addr_len; ++i) {
            packet[last++] = xn297_tx_addr[xn297_addr_len-i-1] ^ xn297_scramble[i];
        }

        for (int i = 0; i < len; ++i) {
            // bit-reverse bytes in packet
            u8 b_out = bit_reverse(msg[i]);
            packet[last++] = b_out ^ xn297_scramble[xn297_addr_len+i];
        }
        if (xn297_crc) {
            int offset = xn297_addr_len < 4 ? 1 : 0;
            u16 crc = initial;
            for (int i = offset; i < last; ++i) {
                crc = crc16_update(crc, packet[i]);
            }
            crc ^= xn297_crc_xorout[xn297_addr_len - 3 + len];
            packet[last++] = crc >> 8;
            packet[last++] = crc & 0xff;
        }
        res = NRF24L01_WritePayload(packet, last);
    }
    return res;
}
Esempio n. 9
0
uint8_t XN297_WritePayload(uint8_t* msg, int len)
{
    uint8_t buf[32];
    uint8_t res;
    int last = 0;
    if (xn297_addr_len < 4) {
        // If address length (which is defined by receive address length)
        // is less than 4 the TX address can't fit the preamble, so the last
        // byte goes here
        buf[last++] = 0x55;
    }
    int i;
    for (i = 0; i < xn297_addr_len; ++i) {
        buf[last++] = xn297_tx_addr[xn297_addr_len-i-1] ^ xn297_scramble[i];
    }

    for (i = 0; i < len; ++i) {
        // bit-reverse bytes in packet
        uint8_t b_out = bit_reverse(msg[i]);
        buf[last++] = b_out ^ xn297_scramble[xn297_addr_len+i];
    }

    if (xn297_crc) {
        int offset = xn297_addr_len < 4 ? 1 : 0;
        uint16_t crc = initial;
        int i;
        for (i = offset; i < last; ++i) {
            crc = crc16_update(crc, buf[i]);
        }
        crc ^= xn297_crc_xorout[xn297_addr_len - 3 + len];
        buf[last++] = crc >> 8;
        buf[last++] = crc & 0xff;
    }
    res = NRF24L01_WritePayload(buf, last);
    return res;
}
Esempio n. 10
0
int CHashManager::HashFile(char *pszFile)
{
	FILE *fp = NULL;
	unsigned char pBuf[SIZE_HASH_BUFFER];
	unsigned long uRead = 0;
	unsigned char pTemp[256];
	char szTemp[RH_MAX_BUFFER];
	int i = 0;

	printf("File: <");
	printf(pszFile);
	printf(">");
	printf(CPS_NEWLINE);

	fp = fopen(pszFile, "rb");
	if(fp == NULL) return RH_CANNOT_OPEN_FILE;

	if(m_bAlgorithm[HASHID_CRC16]) crc16_init(&m_crc16);
	if(m_bAlgorithm[HASHID_CRC16CCITT]) crc16ccitt_init(&m_crc16ccitt);
	if(m_bAlgorithm[HASHID_CRC32]) crc32Init(&m_crc32);
	if(m_bAlgorithm[HASHID_FCS_16]) fcs16_init(&m_fcs16);
	if(m_bAlgorithm[HASHID_FCS_32]) fcs32_init(&m_fcs32);
	if(m_bAlgorithm[HASHID_GHASH_32_3] || m_bAlgorithm[HASHID_GHASH_32_5]) m_ghash.Init();
	if(m_bAlgorithm[HASHID_GOST]) gosthash_reset(&m_gost);
	if(m_bAlgorithm[HASHID_HAVAL]) haval_start(&m_haval);
	if(m_bAlgorithm[HASHID_MD2]) m_md2.Init();
	if(m_bAlgorithm[HASHID_MD4]) MD4Init(&m_md4);
	if(m_bAlgorithm[HASHID_MD5]) MD5Init(&m_md5, 0);
	if(m_bAlgorithm[HASHID_SHA1]) sha1_begin(&m_sha1);
	if(m_bAlgorithm[HASHID_SHA2_256]) sha256_begin(&m_sha256);
	if(m_bAlgorithm[HASHID_SHA2_384]) sha384_begin(&m_sha384);
	if(m_bAlgorithm[HASHID_SHA2_512]) sha512_begin(&m_sha512);
	if(m_bAlgorithm[HASHID_SIZE_32]) sizehash32_begin(&m_uSizeHash32);
	if(m_bAlgorithm[HASHID_TIGER]) tiger_init(&m_tiger);

	while(1)
	{
		uRead = fread(pBuf, 1, SIZE_HASH_BUFFER, fp);

		if(uRead != 0)
		{
			if(m_bAlgorithm[HASHID_CRC16])
				crc16_update(&m_crc16, pBuf, uRead);

			if(m_bAlgorithm[HASHID_CRC16CCITT])
				crc16ccitt_update(&m_crc16ccitt, pBuf, uRead);

			if(m_bAlgorithm[HASHID_CRC32])
				crc32Update(&m_crc32, pBuf, uRead);

			if(m_bAlgorithm[HASHID_FCS_16])
				fcs16_update(&m_fcs16, pBuf, uRead);

			if(m_bAlgorithm[HASHID_FCS_32])
				fcs32_update(&m_fcs32, pBuf, uRead);

			if(m_bAlgorithm[HASHID_GHASH_32_3] || m_bAlgorithm[HASHID_GHASH_32_5])
				m_ghash.Update(pBuf, uRead);

			if(m_bAlgorithm[HASHID_GOST])
				gosthash_update(&m_gost, pBuf, uRead);

			if(m_bAlgorithm[HASHID_HAVAL])
				haval_hash(&m_haval, pBuf, uRead);

			if(m_bAlgorithm[HASHID_MD2])
				m_md2.Update(pBuf, uRead);

			if(m_bAlgorithm[HASHID_MD4])
				MD4Update(&m_md4, pBuf, uRead);

			if(m_bAlgorithm[HASHID_MD5])
				MD5Update(&m_md5, pBuf, uRead);

			if(m_bAlgorithm[HASHID_SHA1])
				sha1_hash(pBuf, uRead, &m_sha1);

			if(m_bAlgorithm[HASHID_SHA2_256])
				sha256_hash(pBuf, uRead, &m_sha256);

			if(m_bAlgorithm[HASHID_SHA2_384])
				sha384_hash(pBuf, uRead, &m_sha384);

			if(m_bAlgorithm[HASHID_SHA2_512])
				sha512_hash(pBuf, uRead, &m_sha512);

			if(m_bAlgorithm[HASHID_SIZE_32])
				sizehash32_hash(&m_uSizeHash32, uRead);

			if(m_bAlgorithm[HASHID_TIGER])
				tiger_process(&m_tiger, pBuf, uRead);
		}

		if(uRead != SIZE_HASH_BUFFER) break;
	}

	fclose(fp); fp = NULL;

	// SizeHash-32 is the first hash, because it's the simplest one,
	// the fastest, and most widely used one. ;-)
	if(m_bAlgorithm[HASHID_SIZE_32])
	{
		sizehash32_end(&m_uSizeHash32);
		printf(SZ_SIZEHASH_32);
		printf(SZ_HASHPRE);

		printf("%08X", m_uSizeHash32);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_CRC16])
	{
		crc16_final(&m_crc16);
		printf(SZ_CRC16);
		printf(SZ_HASHPRE);

		printf("%04X", m_crc16);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_CRC16CCITT])
	{
		crc16ccitt_final(&m_crc16ccitt);
		printf(SZ_CRC16CCITT);
		printf(SZ_HASHPRE);

		printf("%04X", m_crc16ccitt);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_CRC32])
	{
		crc32Finish(&m_crc32);
		printf(SZ_CRC32);
		printf(SZ_HASHPRE);

		printf("%08X", m_crc32);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_FCS_16])
	{
		fcs16_final(&m_fcs16);
		printf(SZ_FCS_16);
		printf(SZ_HASHPRE);

		printf("%04X", m_fcs16);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_FCS_32])
	{
		fcs32_final(&m_fcs32);
		printf(SZ_FCS_32);
		printf(SZ_HASHPRE);

		printf("%08X", m_fcs32);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_GHASH_32_3])
	{
		m_ghash.FinalToStr(szTemp, 3);
		printf(SZ_GHASH_32_3);
		printf(SZ_HASHPRE);

		printf(szTemp);

		printf(CPS_NEWLINE);
	}
	if(m_bAlgorithm[HASHID_GHASH_32_5])
	{
		m_ghash.FinalToStr(szTemp, 5);
		printf(SZ_GHASH_32_5);
		printf(SZ_HASHPRE);

		printf(szTemp);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_GOST])
	{
		gosthash_final(&m_gost, pTemp);
		printf(SZ_GOST);
		printf(SZ_HASHPRE);

		for(i = 0; i < 32; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_HAVAL])
	{
		haval_end(&m_haval, pTemp);
		printf(SZ_HAVAL);
		printf(SZ_HASHPRE);

		for(i = 0; i < 32; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_MD2])
	{
		m_md2.TruncatedFinal(pTemp, 16);
		printf(SZ_MD2);
		printf(SZ_HASHPRE);

		for(i = 0; i < 16; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_MD4])
	{
		MD4Final(pTemp, &m_md4);
		printf(SZ_MD4);
		printf(SZ_HASHPRE);

		for(i = 0; i < 16; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_MD5])
	{
		MD5Final(&m_md5);
		printf(SZ_MD5);
		printf(SZ_HASHPRE);

		for(i = 0; i < 16; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", m_md5.digest[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_SHA1])
	{
		sha1_end(pTemp, &m_sha1);
		printf(SZ_SHA1);
		printf(SZ_HASHPRE);

		for(i = 0; i < 20; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_SHA2_256])
	{
		sha256_end(pTemp, &m_sha256);
		printf(SZ_SHA2_256);
		printf(SZ_HASHPRE);

		for(i = 0; i < 32; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}
	if(m_bAlgorithm[HASHID_SHA2_384])
	{
		sha384_end(pTemp, &m_sha384);
		printf(SZ_SHA2_384);
		printf(SZ_HASHPRE);

		for(i = 0; i < 48; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}
	if(m_bAlgorithm[HASHID_SHA2_512])
	{
		sha512_end(pTemp, &m_sha512);
		printf(SZ_SHA2_512);
		printf(SZ_HASHPRE);

		for(i = 0; i < 64; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_TIGER])
	{
		tiger_done(&m_tiger, pTemp);
		printf(SZ_TIGER);
		printf(SZ_HASHPRE);

		for(i = 0; i < 8; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[7-i]); }
		for(i = 8; i < 16; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[23-i]); }
		for(i = 16; i < 24; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[39-i]); }

		printf(CPS_NEWLINE);
	}

	return RH_SUCCESS;
}
Esempio n. 11
0
uint16_t scan_dir(char* path, char mkdb, uint32_t this_dir_tgt) {
	DIR dir;
	FILINFO fno;
	FRESULT res;
	uint8_t len;
	unsigned char* fn;
	static unsigned char depth = 0;
	static uint16_t crc;
	static uint32_t db_tgt;
	static uint32_t next_subdir_tgt;
	static uint32_t parent_tgt;
	static uint32_t dir_end = 0;
	static uint8_t was_empty = 0;
	uint32_t dir_tgt;
	uint16_t numentries;
	uint32_t dirsize;
	uint8_t pass = 0;

	dir_tgt = this_dir_tgt;
	if(depth==0) {
		crc = 0;
		db_tgt = SRAM_DB_ADDR+0x10;
		dir_tgt = SRAM_DIR_ADDR;
		next_subdir_tgt = SRAM_DIR_ADDR;
		this_dir_tgt = SRAM_DIR_ADDR;
		parent_tgt = 0;
		dprintf("root dir @%lx\n", dir_tgt);
	}	
	
	fno.lfn = file_lfn;
	numentries=0;
	for(pass = 0; pass < 2; pass++) {
		if(pass) {
			dirsize = 4*(numentries);
//			dir_tgt_next = dir_tgt + dirsize + 4; // number of entries + end marker
			next_subdir_tgt += dirsize + 4;
			if(parent_tgt) next_subdir_tgt += 4;
			if(next_subdir_tgt > dir_end) {
				dir_end = next_subdir_tgt;
			}
			dprintf("path=%s depth=%d ptr=%lx entries=%d parent=%lx next subdir @%lx\n", path, depth, db_tgt, numentries, parent_tgt, next_subdir_tgt /*dir_tgt_next*/);
//			_delay_ms(50);
			if(mkdb) {
				dprintf("d=%d Saving %lX to Address %lX  [end]\n", depth, 0L, next_subdir_tgt - 4);
//				_delay_ms(50);	
				sram_writelong(0L, next_subdir_tgt - 4);
			}
		}
		res = f_opendir(&dir, (unsigned char*)path);
		if (res == FR_OK) {
			if(pass && parent_tgt && mkdb) {
				// write backlink to parent dir
				// switch to next bank if record does not fit in current bank
				if((db_tgt&0xffff) > ((0x10000-(sizeof(next_subdir_tgt)+sizeof(len)+4))&0xffff)) {
					dprintf("switch! old=%lx ", db_tgt);
					db_tgt &= 0xffff0000;
					db_tgt += 0x00010000;
					dprintf("new=%lx\n", db_tgt);
				}
				sram_writelong((parent_tgt-SRAM_MENU_ADDR), db_tgt);
				sram_writebyte(0, db_tgt+sizeof(next_subdir_tgt));
				sram_writeblock("../\0", db_tgt+sizeof(next_subdir_tgt)+sizeof(len), 4);
				sram_writelong((db_tgt-SRAM_MENU_ADDR)|((uint32_t)0x80<<24), dir_tgt);
				db_tgt += sizeof(next_subdir_tgt)+sizeof(len)+4;
				dir_tgt += 4;
			}
			len = strlen((char*)path);
			for (;;) {
				toggle_busy_led();
				res = f_readdir(&dir, &fno);
				if (res != FR_OK || fno.fname[0] == 0) {
					if(pass) {
						if(!numentries) was_empty=1;
					}
					break;
				}
				fn = *fno.lfn ? fno.lfn : fno.fname;
	//			dprintf("%s\n", fn);
	//			_delay_ms(100);
				if (*fn == '.') continue;
				if (fno.fattrib & AM_DIR) {
					numentries++;
					if(pass) {
						path[len]='/';
						strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
						depth++;
						if(mkdb) {
							uint16_t pathlen = strlen(path);
							// write element pointer to current dir structure
							dprintf("d=%d Saving %lX to Address %lX  [dir]\n", depth, db_tgt, dir_tgt);
//							_delay_ms(50);
							sram_writelong((db_tgt-SRAM_MENU_ADDR)|((uint32_t)0x80<<24), dir_tgt);
//							sram_writeblock((uint8_t*)&db_tgt, dir_tgt_save, sizeof(dir_tgt_save));

							// save element:
							//  - path name
							//  - pointer to sub dir structure
							if((db_tgt&0xffff) > ((0x10000-(sizeof(next_subdir_tgt) + sizeof(len) + pathlen + 2))&0xffff)) {
								dprintf("switch! old=%lx ", db_tgt);
								db_tgt &= 0xffff0000;
								db_tgt += 0x00010000;
								dprintf("new=%lx\n", db_tgt);
							}
							dprintf("    Saving dir descriptor to %lX, tgt=%lX, path=%s\n", db_tgt, next_subdir_tgt, path);
//							_delay_ms(100);
							sram_writelong((next_subdir_tgt-SRAM_MENU_ADDR), db_tgt);
							sram_writebyte(len+1, db_tgt+sizeof(next_subdir_tgt));
							sram_writeblock(path, db_tgt+sizeof(next_subdir_tgt)+sizeof(len), pathlen);
							sram_writeblock("/\0", db_tgt + sizeof(next_subdir_tgt) + sizeof(len) + pathlen, 2);
//							sram_writeblock((uint8_t*)&dir_tgt, db_tgt+256, sizeof(dir_tgt));
							db_tgt += sizeof(next_subdir_tgt) + sizeof(len) + pathlen + 2;
						}
						parent_tgt = this_dir_tgt;
						scan_dir(path, mkdb, next_subdir_tgt);
						dir_tgt += 4;
//						if(was_empty)dir_tgt_next += 4;
						was_empty = 0;
						depth--;
						path[len]=0;
					}
				} else {
					SNES_FTYPE type = determine_filetype((char*)fn);
					if(type != TYPE_UNKNOWN) {
						numentries++;
						if(pass) {
							if(mkdb) {
								snes_romprops_t romprops;
								path[len]='/';
								strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
								uint16_t pathlen = strlen(path);
								switch(type) {
									case TYPE_SMC:
// XXX										file_open_by_filinfo(&fno);
// XXX										if(file_res){
// XXX											dprintf("ZOMG NOOOO %d\n", file_res);
// XXX											_delay_ms(30);
// XXX										}
// XXX										smc_id(&romprops);
// XXX										file_close();
		//								_delay_ms(30);
										// write element pointer to current dir structure
//										dprintf("d=%d Saving %lX to Address %lX  [file]\n", depth, db_tgt, dir_tgt);
//										_delay_ms(50);
										if((db_tgt&0xffff) > ((0x10000-(sizeof(romprops) + sizeof(len) + pathlen + 1))&0xffff)) {
											dprintf("switch! old=%lx ", db_tgt);
											db_tgt &= 0xffff0000;
											db_tgt += 0x00010000;
											dprintf("new=%lx\n", db_tgt);
										}
										sram_writelong((db_tgt-SRAM_MENU_ADDR), dir_tgt);
//										sram_writeblock((uint8_t*)&db_tgt, dir_tgt, sizeof(db_tgt));
										dir_tgt += 4;
										// save element:
										//  - SNES header information
										//  - file name
										sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops));
										sram_writebyte(len+1, db_tgt + sizeof(romprops));
										sram_writeblock(path, db_tgt + sizeof(romprops) + sizeof(len), pathlen + 1);
										db_tgt += sizeof(romprops) + sizeof(len) + pathlen + 1;
										break;
									case TYPE_UNKNOWN:
									default:
										break;
								}
								path[len]=0;
		//						dprintf("%s ", path);
		//						_delay_ms(30);
							}
						} else {
							unsigned char* sfn = fno.fname;
							while(*sfn != 0) {
								crc += crc16_update(crc, sfn++, 1);
							}
						}
					}
	//					dprintf("%s/%s\n", path, fn);
	//					_delay_ms(50);
				}
			}
		} else uart_putc(0x30+res);
	}
//	dprintf("%x\n", crc);
//	_delay_ms(50);
	sram_writelong(db_tgt, SRAM_DB_ADDR+4);
	sram_writelong(dir_end, SRAM_DB_ADDR+8);
	return crc;
}