Пример #1
0
// Work around TI's OS behaviour: extra bulk write of 0 size required after the last raw packet in a transfer,
// when some conditions are met.
static void workaround_send(CalcHandle *h, DUSBRawPacket *raw, DUSBVirtualPacket *vtl)
{
	uint8_t buf[64];

	ticalcs_info("workaround_send: vtl->size=%d\traw->size=%d", vtl->size, raw->size);

	if (h->model == CALC_TI89T_USB)
	{
		// A 1076-byte (string) variable doesn't require this workaround, but bigger (string) variables do.
		if (vtl->size > 1076 && ((raw->size + 5) % 64) == 0)
		{
			ticalcs_info("XXX triggering an extra bulk write\n\tvtl->size=%d\traw->size=%d", vtl->size, raw->size);
			ticables_cable_send(h->cable, buf, 0);
		}
	}
	else // if (h->model == CALC_TI84P_USB)
	{
		// A 244-byte (program) variable doesn't require this workaround, but bigger (program) variables do.
		if (raw->type == DUSB_RPKT_VIRT_DATA_LAST && vtl->size > 244 && (vtl->size % 250) == 244)
		{
			ticalcs_info("XXX triggering an extra bulk write\n\tvtl->size=%d\traw->size=%d", vtl->size, raw->size);
			ticables_cable_send(h->cable, buf, 0);
		}
	}
}
Пример #2
0
static int send_pkt(CalcHandle* handle, uint16_t cmd, uint16_t len, uint8_t* data)
{
	uint16_t sum;

	// command
	buf[0] = LSB(cmd);
	buf[1] = MSB(cmd);

	// length
	buf[2] = LSB(len);
	buf[3] = MSB(len);

	// data
	if(data)
		memcpy(buf+4, data, len);

	// checksum
	sum = tifiles_checksum(buf, 4 + len);
	buf[len+4+0] = LSB(sum);
	buf[len+4+1] = MSB(sum);

	TRYF(ticables_cable_send(handle->cable, buf, len+6));

	return 0;
}
Пример #3
0
TIEXPORT3 int TICALL ti68k_send_KEY(CalcHandle* handle, uint16_t scancode, uint8_t target)
{
	uint8_t buf[4] = { target, DBUS_CMD_KEY, LSB(scancode), MSB(scancode) };

	VALIDATE_HANDLE(handle);

	ticalcs_info(" PC->TI: KEY");
	return ticables_cable_send(handle->cable, buf, 4);
}
Пример #4
0
TIEXPORT3 int TICALL ti73_send_KEY(CalcHandle* handle, uint16_t scancode)
{
	uint8_t buf[5];
  
	buf[0] = PC_TI7383;
	buf[1] = CMD_KEY;
	buf[2] = LSB(scancode);
	buf[3] = MSB(scancode);

	ticalcs_info(" PC->TI: KEY");
	return ticables_cable_send(handle->cable, buf, 4);
}
Пример #5
0
int ti83_send_KEY_h(CalcHandle* handle, uint16_t scancode)
{
	uint8_t buf[5];
  
	buf[0] = PC_TI83;
	buf[1] = CMD_KEY;
	buf[2] = LSB(scancode);
	buf[3] = MSB(scancode);

	ticalcs_info(" PC->TI: KEY");
	TRYF(ticables_cable_send(handle->cable, buf, 4));

	return 0;
}
Пример #6
0
TIEXPORT3 int TICALL dusb_send(CalcHandle* handle, DUSBRawPacket* pkt)
{
	uint8_t buf[sizeof(pkt->data) + 5];
	uint32_t size;
	int ret;

	VALIDATE_HANDLE(handle);
	VALIDATE_NONNULL(pkt);

	memset(buf, 0, sizeof(buf));
	size = pkt->size;

	if (size > sizeof(pkt->data))
	{
		size = sizeof(pkt->data);
	}

	buf[0] = MSB(MSW(size));
	buf[1] = LSB(MSW(size));
	buf[2] = MSB(LSW(size));
	buf[3] = LSB(LSW(size));
	buf[4] = pkt->type;
	memcpy(buf + 5, pkt->data, size);

	//printf("dusb_send: pkt->size=%d\n", pkt->size);
	ticables_progress_reset(handle->cable);
	ret = ticables_cable_send(handle->cable, buf, size + 5);
	if (!ret)
	{
		if (size >= 128)
		{
			ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);
		}

		if (handle->updat->cancel)
		{
			ret = ERR_ABORT;
		}
	}

	return ret;
}
Пример #7
0
int dusb_send(CalcHandle* handle, RawPacket* pkt)
{
	uint8_t buf[1023 + 5]= { 0 };
	uint32_t size = pkt->size + 5;

	buf[0] = MSB(MSW(pkt->size));
	buf[1] = LSB(MSW(pkt->size));
	buf[2] = MSB(LSW(pkt->size));
	buf[3] = LSB(LSW(pkt->size));
	buf[4] = pkt->type;
	memcpy(buf+5, pkt->data, pkt->size);

	//printf("dusb_send: pkt->size=%d\n", pkt->size);
	ticables_progress_reset(handle->cable);
	TRYF(ticables_cable_send(handle->cable, buf, size));
	if(size >= 128)
		ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);

	if (handle->updat->cancel)
		return ERR_ABORT;

	return 0;
}
Пример #8
0
TIEXPORT3 int TICALL dusb_send(CalcHandle* handle, DUSBRawPacket* pkt)
{
	uint8_t buf[1023 + 5]= { 0 };
	uint32_t size;

	if (handle == NULL)
	{
		ticalcs_critical("%s: handle is NULL", __FUNCTION__);
		return ERR_INVALID_HANDLE;
	}
	if (pkt == NULL)
	{
		ticalcs_critical("%s: pkt is NULL", __FUNCTION__);
		return ERR_INVALID_PACKET;
	}

	size = pkt->size + 5;

	buf[0] = MSB(MSW(pkt->size));
	buf[1] = LSB(MSW(pkt->size));
	buf[2] = MSB(LSW(pkt->size));
	buf[3] = LSB(LSW(pkt->size));
	buf[4] = pkt->type;
	memcpy(buf+5, pkt->data, pkt->size);

	//printf("dusb_send: pkt->size=%d\n", pkt->size);
	ticables_progress_reset(handle->cable);
	TRYF(ticables_cable_send(handle->cable, buf, size));
	if(size >= 128)
		ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);

	if (handle->updat->cancel)
		return ERR_ABORT;

	return 0;
}
Пример #9
0
int main(int argc, char **argv)
{
	CableHandle *handle;
	int err;
	//	int i, j;
	//	uint8_t buf[65536], data;
	//	int status, result;
	//	uint8_t scr[3840 + 6];
	//	int **probing = NULL;

 #if 0
	tiTIME ref, end;
	unsigned long k;

	to_START(ref);
	for(k = 0; k < 1000000; k++) printf(" ");
	to_START(end);
	printf("%lu %lu\n", ref, end);
	printf("%lu\n", to_CURRENT(ref));
	printf("%i\n", to_ELAPSED(ref, 60));

	return 0;
#endif

	printf("USB support: %i\n", ticables_is_usb_enabled());

	// init lib
	ticables_library_init();


print_lc_error(1);

#if 0
	ticables_probing_do(&probing, 5, PROBE_ALL);
	for(i = 1; i <= 7; i++) 
		printf("%i: %i %i %i %i\n", i, probing[i][1], probing[i][2], probing[i][3], probing[i][4]);
	ticables_probing_finish(&probing);
#endif

#if 0
	{
		int *list = NULL;
		int i, n;
		int *p;

		ticables_get_usb_devices(&list, &n);
		printf("List of devices:\n");
		for(i = 0; i < n; i++)
		    printf("%i: %04x\n", i, list[i]);
	}
#endif

	// set cable
	handle = ticables_handle_new(CABLE_PAR, PORT_1);
	if(handle == NULL)
	    return -1;

	ticables_options_set_timeout(handle, 15);
	ticables_options_set_delay(handle, 10);
	ticables_handle_show(handle);

	// open cable
	err = ticables_cable_open(handle);
	if(err) print_lc_error(err);
	if(err) return -1;
#if 0
	// simple test with DirectLink hand-helds (buf size req/neg)
	buf[0]=0x00; buf[1]=0x00; buf[2]=0x00; buf[3]=0x04;
	buf[4]=0x01;
	buf[5]=0x00; buf[6]=0x00; buf[7]=0x04; buf[8]=0x00;
	err = ticables_cable_send(handle, buf, 9);
        if(err) print_lc_error(err);

	// display answer
	memset(buf, 0, sizeof(buf));
	err = ticables_cable_recv(handle, buf, 9);
	if(err) print_lc_error(err);

	for(i = 0; i < 9; i++)
	    printf("%02x ", buf[i]);
	printf("\n");
#endif

#if 0
	// mode set
	i = 0;
	buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x10;
	buf[i++]=0x04;
	buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x0a;
	buf[i++]=0x00; buf[i++]=0x01;
	buf[i++]=0x00; buf[i++]=0x03; 
	buf[i++]=0x00; buf[i++]=0x01;
	buf[i++]=0x00; buf[i++]=0x00; 
	buf[i++]=0x00; buf[i++]=0x00; 
	buf[i++]=0x07; buf[i++]=0xd0;

	err = ticables_cable_send(handle, buf, i);
	if(err) print_lc_error(err);

	err = ticables_cable_recv(handle, buf, 7);
	if(err) print_lc_error(err);
	for(i = 0; i < 7; i++)
	    printf("%02x ", buf[i]);
	printf("\n");

	// mode ack
	err = ticables_cable_recv(handle, buf, 15);
	if(err) print_lc_error(err);
	for(i = 0; i < 15; i++)
		printf("%02x ", buf[i]);
	printf("\n");

	i = 0;
	buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x02;
	buf[i++]=0x05;
	buf[i++]=0xe0; buf[i++]=0x00;

	err = ticables_cable_send(handle, buf, i);
	if(err) print_lc_error(err);
	PAUSE(500);
#endif

#if 0
	// param req (TI84+ only)
	i = 0;
	buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0xa;
	buf[i++]=0x04;
	buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x04;
	buf[i++]=0x00; buf[i++]=0x07;
	buf[i++]=0x00; buf[i++]=0x01; 
	buf[i++]=0x00; buf[i++]=0x22;

	err = ticables_cable_send(handle, buf, i);
	if(err) print_lc_error(err);

	err = ticables_cable_recv(handle, buf, 7);
	if(err) print_lc_error(err);
	for(i = 0; i < 7; i++)
		printf("%02x ", buf[i]);
	printf("\n");

	// delay ack
	err = ticables_cable_recv(handle, buf, 15);
	if(err) print_lc_error(err);
	for(i = 0; i < 15; i++)
	    printf("%02x ", buf[i]);
	printf("\n");

	i = 0;
	buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x02;
	buf[i++]=0x05;
	buf[i++]=0xe0; buf[i++]=0x00;

	err = ticables_cable_send(handle, buf, i);
	if(err) print_lc_error(err);

	// param data
	for(j = 0; j < 3; j++)
	{
		err = ticables_cable_recv(handle, buf, 255);
		if(err) print_lc_error(err);
		for(i = 0; i < 16; i++)
			printf("%02x ", buf[i]);
		printf("\n");

		i = 0;
		buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x02;
		buf[i++]=0x05;
		buf[i++]=0xe0; buf[i++]=0x00;

		err = ticables_cable_send(handle, buf, i);
		if(err) print_lc_error(err);
	}
	{
		err = ticables_cable_recv(handle, buf, 36);
		if(err) print_lc_error(err);
		for(i = 0; i < 16; i++)
			printf("%02x ", buf[i]);
		printf("\n");

		i = 0;
		buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x00; buf[i++]=0x02;
		buf[i++]=0x05;
		buf[i++]=0xe0; buf[i++]=0x00;

		err = ticables_cable_send(handle, buf, i);
		if(err) print_lc_error(err);
	}
	PAUSE(500);
#endif

#if 0
	// do a simple test with a TI89/92+ calculator
	buf[0] = 0x08; buf[1] = 0x68; buf[2] = 0x00; buf[3] = 0x00;	// RDY
	err = ticables_cable_send(handle, buf, 4);
	if(err) print_lc_error(err);
	 
	// display answer
	memset(buf, 0xff, 4);
	err = ticables_cable_recv(handle, buf, 4);
	if(err) print_lc_error(err);

	for(i = 0; i < 4; i++)
		printf("%02x ", buf[i]);
	printf("\n");
#endif

#if 0
	// do a screendump
	buf[0] = 0x08;  buf[1] = 0x6D; buf[2] = 0x00; buf[3] = 0x00;	// SCR
	err = ticables_cable_send(handle, buf, 4);
	if(err) print_lc_error(err);
	
	memset(buf, 0xff, 4);
	err = ticables_cable_recv(handle, buf, 4);	// ACK
	if(err) print_lc_error(err);

	err = ticables_cable_recv(handle, scr, 0x0f00 + 6);	// XDP
	if(err) print_lc_error(err);
	printf("%02x %02x\n", scr[2], scr[3]);

	buf[0] = 0x08;  buf[1] = 0x56; buf[2] = 0x00; buf[3] = 0x00;	// ACK
	err = ticables_cable_send(handle, buf, 4);
	if(err) print_lc_error(err);
#endif

#if 0
	// simple test for data arrival detection
	buf[0] = 0x08;  buf[1] = 0x87; buf[2] = 'A'; buf[3] = 0x00;		// KEY
	err = ticables_cable_send(handle, buf, 4);
	if(err) print_lc_error(err);

	for(status = 0; !status;)
	{
		err = ticables_cable_check(handle, &status);
		if(err) print_lc_error(err);
	}

	// display answer
	memset(buf, 0xff, 4);
	err = ticables_cable_recv(handle, buf, 4);
	if(err) print_lc_error(err);

	for(i = 0; i < 4; i++)
		printf("%02x ", buf[i]);
	printf("\n");
#endif

#if 0
	for(status = 0; !status;)
	{
	    //fprintf(stdout, "$\n");
	    //fflush(stdout);
		err = ticables_cable_check(handle, &status);
		if(err) print_lc_error(err);
	}

	// display answer
	memset(buf, 0xff, 4);
	err = ticables_cable_recv(handle, buf, 4);
	if(err) print_lc_error(err);

	for(i = 0; i < 4; i++)
		printf("%02x ", buf[i]);
	printf("\n");
#endif

	// close cable
	ticables_cable_close(handle);
	// release handle
	ticables_handle_del(handle);
	
	// exit lib
	ticables_library_exit();
#ifdef __WIN32__
	while(!kbhit());
#endif
	return 0;
}
Пример #10
0
/*
    Send a packet from PC (host) to TI (target):
    - target [in] : a machine ID uint8_t
    - cmd [in]    : a command ID uint8_t
    - length [in] : length of buffer
    - data [in]   : data to send (or 0x00 if NULL)
    - int [out]   : an error code
*/
TIEXPORT3 int TICALL dbus_send(CalcHandle* handle, uint8_t target, uint8_t cmd, uint16_t len, uint8_t* data)
{
	int i;
	uint16_t sum;
	uint32_t length = (len == 0x0000) ? 65536 : len;   // wrap around
	uint8_t *buf;
	int r, q;
	static int ref = 0;

	if (handle == NULL)
	{
		ticalcs_critical("%s: handle is NULL", __FUNCTION__);
		return ERR_INVALID_HANDLE;
	}
	buf = (uint8_t *)handle->priv2;                    //[65536+6];
	if (buf == NULL)
	{
		ticalcs_critical("%s: handle->priv2 is NULL", __FUNCTION__);
		return ERR_INVALID_HANDLE;
	}

	ticables_progress_reset(handle->cable);

	if(data == NULL)
	{
		// short packet (no data)
		buf[0] = target;
		buf[1] = cmd;
		buf[2] = 0x00;
		buf[3] = 0x00;

		// TI80 does not use length
		if(target == PC_TI80)
		{
			TRYF(ticables_cable_send(handle->cable, buf, 2));
		}
		else
		{
			TRYF(ticables_cable_send(handle->cable, buf, 4));
		}
	}
	else 
	{
		// std packet (data + checksum)
		buf[0] = target;
		buf[1] = cmd;
		buf[2] = LSB(length);
		buf[3] = MSB(length);

		// copy data
		memcpy(buf+4, data, length);

		// add checksum of packet
		sum = tifiles_checksum(data, length);
		buf[length+4+0] = LSB(sum);
		buf[length+4+1] = MSB(sum);

		// compute chunks
		MIN_SIZE = (handle->cable->model == CABLE_GRY) ? 512 : 2048;
		BLK_SIZE = (length + 6) / 20;		// 5%
		if(BLK_SIZE == 0) BLK_SIZE = length + 6;
		if(BLK_SIZE < 32) BLK_SIZE = 128;	// SilverLink doesn't like small block (< 32)

		q = (length + 6) / BLK_SIZE;
		r = (length + 6) % BLK_SIZE;

		handle->updat->max1 = length + 6;
		handle->updat->cnt1 = 0;

		// send full chunks
		for(i = 0; i < q; i++)
		{
			TRYF(ticables_cable_send(handle->cable, &buf[i*BLK_SIZE], BLK_SIZE));
			ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);

			handle->updat->cnt1 += BLK_SIZE;
			if(length > MIN_SIZE)
				handle->updat->pbar();

			if (handle->updat->cancel)
				return ERR_ABORT;
		}

		// send last chunk
		{
			TRYF(ticables_cable_send(handle->cable, &buf[i*BLK_SIZE], (uint16_t)r));
			ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);

			handle->updat->cnt1 += 1;
			if(length > MIN_SIZE)
				handle->updat->pbar();

			if (handle->updat->cancel)
				return ERR_ABORT;
		}
	}

	// force periodic refresh
	if(!(ref++ % 4))
		handle->updat->refresh();

	return 0;
}
Пример #11
0
/*
    Send a packet from PC (host) to TI (target):
    - target [in] : a machine ID uint8_t
    - cmd [in]    : a command ID uint8_t
    - length [in] : length of buffer
    - data [in]   : data to send (or 0x00 if NULL)
    - int [out]   : an error code
*/
TIEXPORT3 int TICALL dbus_send(CalcHandle* handle, uint8_t target, uint8_t cmd, uint16_t len, const uint8_t* data)
{
	int i;
	uint16_t sum;
	uint32_t length = (len == 0x0000) ? 65536 : len;   // wrap around
	uint8_t *buf;
	int r, q;
	static int ref = 0;
	int ret;

	VALIDATE_HANDLE(handle);

	buf = (uint8_t *)handle->buffer;                    //[65536+6];
	if (buf == NULL)
	{
		ticalcs_critical("%s: handle->buffer is NULL", __FUNCTION__);
		return ERR_INVALID_HANDLE;
	}

	ticables_progress_reset(handle->cable);

	if (data == NULL)
	{
		// short packet (no data)
		buf[0] = target;
		buf[1] = cmd;
		buf[2] = 0x00;
		buf[3] = 0x00;

		// The TI-80 does not use length
		ret = ticables_cable_send(handle->cable, buf, (target == DBUS_MID_PC_TI80) ? 2 : 4);
	}
	else 
	{
		// std packet (data + checksum)
		buf[0] = target;
		buf[1] = cmd;
		buf[2] = LSB(length);
		buf[3] = MSB(length);

		// copy data
		memcpy(buf+4, data, length);

		// add checksum of packet
		sum = tifiles_checksum(data, length);
		buf[length+4+0] = LSB(sum);
		buf[length+4+1] = MSB(sum);

		// compute chunks
		handle->priv.progress_min_size = (handle->cable->model == CABLE_GRY) ? 512 : 2048;
		handle->priv.progress_blk_size = (length + 6) / 20;		// 5%
		if (handle->priv.progress_blk_size == 0)
		{
			handle->priv.progress_blk_size = length + 6;
		}
		if (handle->priv.progress_blk_size < 32)
		{
			handle->priv.progress_blk_size = 128;	// SilverLink doesn't like small block (< 32)
		}

		q = (length + 6) / handle->priv.progress_blk_size;
		r = (length + 6) % handle->priv.progress_blk_size;

		handle->updat->max1 = length + 6;
		handle->updat->cnt1 = 0;

		ret = 0;

		// send full chunks
		for (i = 0; i < q; i++)
		{
			ret = ticables_cable_send(handle->cable, &buf[i*handle->priv.progress_blk_size], handle->priv.progress_blk_size);
			if (ret)
			{
				break;
			}
			ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);

			handle->updat->cnt1 += handle->priv.progress_blk_size;
			if (length > handle->priv.progress_min_size)
			{
				handle->updat->pbar();
			}

			if (handle->updat->cancel)
			{
				ret = ERR_ABORT;
				break;
			}
		}

		// send last chunk
		if (!ret)
		{
			ret = ticables_cable_send(handle->cable, &buf[i*handle->priv.progress_blk_size], (uint16_t)r);
			if (!ret)
			{
				ticables_progress_get(handle->cable, NULL, NULL, &handle->updat->rate);

				handle->updat->cnt1 += 1;
				if (length > handle->priv.progress_min_size)
				{
					handle->updat->pbar();
				}

				if (handle->updat->cancel)
				{
					ret = ERR_ABORT;
				}
			}
		}
	}

	// force periodic refresh
	if (!ret && !(ref++ % 4))
	{
		handle->updat->refresh();
	}

	return ret;
}