Example #1
0
void test_serial() {
	print("Initialising serial port at 0x3f8 to 9600\n");
	init_serial(0x3f8, 9600);
	print("Writing to UART ... :");
	send_serial(0x3f8, ':');
	print("-");
	send_serial(0x3f8, '-');
	print(")");
	send_serial(0x3f8, ')');
	print("\n");
}
Example #2
0
/*
 * Wait for LC3 to be ready
 */
int wait_lc3_ready(HANDLE hCom) {
	DWORD bytesRead;
	int ready;
	const int nbuff_words = 1024;
	unsigned char buff[nbuff_words*2];
	int respSize = strlen(LC3_READY_RESPONSE);

	do {
		local_message("Quering device...");
		PurgeComm(hCom, PURGE_RXCLEAR);
		if (send_serial(hCom, LC3_CMD_QUERY, 2) < 2) {
			return -1;
		}
		// Wait some time to allow device to respond
		Sleep(100);
		ready = ReadFile(hCom, buff, respSize, &bytesRead, NULL) &&
			      bytesRead==respSize &&
           	   strncmp(buff, LC3_READY_RESPONSE, respSize)==0;
		//		local_message("debug: need:%d[%s], got: %d[%s]\n", respSize, LC3_READY_RESPONSE, bytesRead, buff);
		if (!ready) {
			local_message(" Device not ready.\n"
				"Press PROGRAM push-button (LEFT on the FPGA main board)!\n");
			Sleep(4000);
		}
	} while (!ready);

	return 0;
}
Example #3
0
int serial_string(char * str){  
	
	int i;
	for(i=0;i<strlen(str);i++){
		send_serial(str[i]);
	}
return 0;
}  
Example #4
0
int main(int argc, char *argv[])
{
    int  rv, len, nblocks, done = 0;
    char * data = NULL;

    if ( (rv = get_opts(&gopts, argc, argv)) != 0 )
        return rv;

    /* register interrupt trap */
    signal(SIGTERM, cleanup);  /* so need global variables */
    signal(SIGINT, cleanup);

    /* open or set input file */
    if( gopts.in_fname )
    {
        gcontr.infd = open(gopts.in_fname, O_RDONLY);
        if( gcontr.infd < 0 )
        {
            fprintf(stderr,"** failed to open infile '%s'\n",gopts.in_fname);
            return 1;
        }
    }
    else
        gcontr.infd = 0;  /* stdin */

    /* allocate data block */
    data = (char *)malloc(gopts.block_len * sizeof(char));
    if( !data )
    {
        fprintf(stderr,"** failed to alloc %d bytes for block\n",
                gopts.block_len);
        return 1;
    }

    if( gopts.swap == 2 ) swap_2(data, gopts.block_len/2);
    else if( gopts.swap == 4 ) swap_4(data, gopts.block_len/4);
    
    if( (rv = open_serial(&gopts, &gcontr)) != 0 )
        return rv;

    nblocks = 0;
    while(! done && (gopts.nblocks <= 0 || nblocks < gopts.nblocks) ) 
    {
        len = set_data(&gopts, &gcontr, data);
        if( len > 0 ) done = send_serial(&gopts, &gcontr, data, len);
        else          done = 1;
        nblocks++;
	if( gopts.ms_sleep ) ms_sleep(gopts.ms_sleep);
    } 

    free(data);
    close_ports();

    if(gopts.debug) fprintf(stderr,"-d wrote %d blocks of data\n",nblocks);

    return 0;
}
Example #5
0
/*
 * Upload part of the file
 */
int send_file_chunk(HANDLE hCom, HANDLE hProg, int file_offset, int lc3_offset, int chunk_size, int progress_done, int progress_whole) {
	const int nbuff_words = 1024;
	unsigned char buff[nbuff_words*2];
	DWORD bytesRead, bytesWritten;
	DWORD remain;	// how many bytes of this chunk remaining to send
	DWORD part;	// how many bytes to send in one go (limited by buffer size and remaining data)

	//// Send Upload command:
	// Header:
	buff[0] = LC3_CMD_UPLOAD[0];
	buff[1] = LC3_CMD_UPLOAD[1];
	// Transmission size: Network order (big-endian) in LC3 words
	buff[2] = (char)(chunk_size/2 / 256);
	buff[3] = (char)(chunk_size/2 % 256);
	// Offset: Network order (big-endian) in LC3 words
	buff[4] = (char)(lc3_offset/2 / 256);
	buff[5] = (char)(lc3_offset/2 % 256);
	if (send_serial(hCom, buff, 6) < 6) {
		return -1;
	}

	SetFilePointer(hProg, file_offset, NULL, FILE_BEGIN);
	SetLastError(ERROR_SUCCESS);
	remain = chunk_size;
	part = min(nbuff_words*2, remain);
	while (remain &&
			ReadFile(hProg, buff, part, &bytesRead, NULL)
			&& bytesRead!=0) {
		if (bytesRead < part) {
			local_message("Warning: ReadFile() returned only some of requested data\n");
		}
		if ((bytesWritten=send_serial(hCom, buff, bytesRead)) < bytesRead) {
			// send_serial should have send all requested data
			return -1;
		} else {
			remain -= bytesWritten;
			local_message("\r%3d%% complete     --  %5lu of %5lu bytes send              ",
				       (int)((progress_done+chunk_size-remain)*100/progress_whole), (progress_done+chunk_size-remain), progress_whole);
		}
		part = min(nbuff_words*2, remain);
	}

	return (remain) ? -1 : 0;
}
Example #6
0
int main( int argc, char **argv )
{
    if ( use_gui )
    {
        printf("init_sdl()\n");
        if ( init_sdl() ) return 1;

        printf("init_gl()\n");
        init_gl();
    }

    printf("init_fft()\n");
    if ( init_fft() ) return 1;

    if ( use_serial )
    {
        printf("init_serial()\n");
        if ( init_serial() ) use_serial = FALSE;
    }

    init_lights();
    init_table();

    while ( !done )
    {
        get_samples_do_fft();

        detect_beats();

        assign_lights();

        assign_cells();

        if ( use_gui )
        {
            if (handle_sdl_events()) return 1;
            draw_all();
        }

        if ( use_serial ) send_serial();

        usleep(5000);
    }

    return 0;
}
Example #7
0
int main(int argc, char *argv[])
{
    optiondata  opt;
    motparm     mp;  
    port_list * plist = &g_ports;
    int         rv;

    if ( (rv = get_options(&opt, &mp, plist, argc, argv)) != 0 )
        return rv;
    
    /* register interrupt trap */
    signal( SIGHUP,  clean_n_exit );
    signal( SIGINT,  clean_n_exit );
    signal( SIGQUIT, clean_n_exit );
    signal( SIGKILL, clean_n_exit );
    signal( SIGTERM, clean_n_exit );
    
    if ( (rv = open_incoming_socket(&opt, plist)) < 0 )
        return rv;

    while (1)           /* run until interrupt or error (consider restart?) */
    {
        mp.nread = 0;           /* reset our counter */

        /* wait for AFNI to talk to us */
        if ( (rv = wait_for_socket(&opt, plist, &mp)) < 0 ) {
            clean_n_exit(0);
            return rv;
        }

        if ( ! opt.no_serial )
            if ( (rv = open_serial(&opt, plist)) != 0 )
                return rv;

        /* read data while it is there */
        while ( (rv = read_socket(&opt, plist, &mp)) == 0)
            if ( ! opt.no_serial )
                send_serial(&opt, plist, &mp);

        close_data_ports(plist);
    } 

    return 0;   /* should not be reached, of course */
}
/*
void interrupt isr(void) {
    if (TMR1IF) {
        TMR1IF = 0;
    }
}
*/
int main(void) {
    OSCCON = 0x70; //intosc 8MHz
    TRISA = 0x00; //0011,1111
    TRISB = 0x00; //x001,0010
    ANSELA = 0x00; //Use AN0,1,2
    ANSELB = 0x00; //all digital
    WPUA = 0xFF; // RB1/4は内部プルアップ抵抗を指定する
    OPTION_REGbits.nWPUEN = 0;
    //timer1_init(0);
    //INTCONbits.PEIE = 1;
    //INTCONbits.GIE = 1;
    //LATB = 0xFF;
    uint8_t i;
    while (1) {
        for (i = 0; i < 5; i++) {
            LATB = LATB & 0b00000011;
            send_serial(i);
            LATB = (LATB & 0b00000011) + (1 << (i + 2));
            __delay_ms(1);
        }
    }
    return 0;
}
Example #9
0
static void shortcut_callback(gpointer *number)
{
	gchar *string;
	gchar *str;
	gint i, length;
	guchar a;
	guint val_read;

	string = macros[(long)number].action;
	length = strlen(string);

	for(i = 0; i < length; i++)
	{
		if(string[i] == '\\')
		{
			if(g_unichar_isdigit((gunichar)string[i + 1]))
			{
				if((string[i + 1] == '0') && (string[i + 2] != 0))
				{
					if(g_unichar_isxdigit((gunichar)string[i + 3]))
					{
						str = &string[i + 2];
						i += 3;
					}
					else
					{
						str = &string[i + 1];
						if(g_unichar_isxdigit((gunichar)string[i + 2]))
							i += 2;
						else
							i++;
					}
				}
				else
				{
					str = &string[i + 1];
					if(g_unichar_isxdigit((gunichar)string[i + 2]))
						i += 2;
					else
						i++;
				}
				if(sscanf(str, "%02X", &val_read) == 1)
					a = (guchar)val_read;
				else
					a = '\\';
			}
			else
			{
				switch(string[i + 1])
				{
				case 'a':
					a = '\a';
					break;
				case 'b':
					a = '\b';
					break;
				case 't':
					a = '\t';
					break;
				case 'n':
					a = '\n';
					break;
				case 'v':
					a = '\v';
					break;
				case 'f':
					a = '\f';
					break;
				case 'r':
					a = '\r';
					break;
				case '\\':
					a = '\\';
					break;
				default:
					a = '\\';
					i--;
					break;
				}
				i++;
			}
			send_serial((gchar*)&a, 1);
		}
		else
		{
			send_serial(&string[i], 1);
		}
	}

	str = g_strdup_printf(_("Macro \"%s\" sent !"), macros[(long)number].shortcut);
	Put_temp_message(str, 800);
	g_free(str);
}
Example #10
0
void silence(int fd) {
	send_serial(fd, 0, &stop);
	send_serial(fd, 1, &stop);
	send_serial(fd, 2, &stop);
	send_serial(fd, 3, &stop);
}
Example #11
0
static int send_serial_printf(char c,FILE *stream){
if(c=='\n') send_serial('\r');
send_serial(c);
return 0;
}
Example #12
0
void ecriture(gpointer data, gint source, GdkInputCondition condition)
{
    static gchar buffer[BUFFER_EMISSION];
    static gchar *current_buffer;
    static gint bytes_to_write;
    gint bytes_written;
    gchar *car;

    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ProgressBar), (gfloat)car_written/(gfloat)nb_car );

    if(car_written < nb_car)
    {
	/* Read the file only if buffer totally sent or if buffer empty */
	if(current_buffer_position == bytes_read)
	{
	    bytes_read = read(Fichier, buffer, BUFFER_EMISSION);

	    current_buffer_position = 0;
	    current_buffer = buffer;
	    bytes_to_write = bytes_read;
	}

	car = current_buffer;

	if(config.delai != 0 || config.car != -1)
	{
	    /* search for next LF */
	    bytes_to_write = current_buffer_position;
	    while(*car != LINE_FEED && bytes_to_write < bytes_read)
	    {
		car++;
		bytes_to_write++;
	    }
	    if(*car == LINE_FEED)
		bytes_to_write++;
	}

	/* write to serial port */
	bytes_written = send_serial(current_buffer, bytes_to_write - current_buffer_position);

	if(bytes_written == -1)
	{
	    /* Problem while writing, stop file transfer */
	    g_free(str);
	    str = g_strdup_printf(_("Cannot write file %s\n"), strerror(errno));
	    show_message(str, MSG_ERR);
	    close_all();
	    return;
	}

	car_written += bytes_written;
	current_buffer_position += bytes_written;
	current_buffer += bytes_written;

	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ProgressBar), (gfloat)car_written/(gfloat)nb_car );

	if(config.delai != 0 && *car == LINE_FEED)
	{
	    remove_input();
	    g_timeout_add(config.delai, (GSourceFunc)timer, NULL);
	    waiting_for_timer = TRUE;
	}
	else if(config.car != -1 && *car == LINE_FEED)
	{
	    remove_input();
	    waiting_for_char = TRUE;
	}
    }
    else
    {
	close_all();
	return;
    }
    return;
}
Example #13
0
/* Receive a command from the client and execute it. */
static void handle_command (const int client_id)
{
	int cmd;
	int err = 0;
	struct client *cli = &clients[client_id];

	if (!get_int(cli->socket, &cmd)) {
		logit ("Failed to get command from the client");
		close (cli->socket);
		del_client (cli);
		return;
	}

	switch (cmd) {
		case CMD_QUIT:
			logit ("Exit request from the client");
			close (cli->socket);
			del_client (cli);
			server_quit = 1;
			break;
		case CMD_LIST_CLEAR:
			logit ("Clearing the list");
			audio_plist_clear ();
			break;
		case CMD_LIST_ADD:
			if (!req_list_add(cli))
				err = 1;
			break;
		case CMD_PLAY:
			if (!req_play(cli))
				err = 1;
			break;
		case CMD_DISCONNECT:
			logit ("Client disconnected");
			close (cli->socket);
			del_client (cli);
			break;
		case CMD_PAUSE:
			audio_pause ();
			break;
		case CMD_UNPAUSE:
			audio_unpause ();
			break;
		case CMD_STOP:
			audio_stop ();
			break;
		case CMD_GET_CTIME:
			if (!send_data_int(cli, MAX(0, audio_get_time())))
				err = 1;
			break;
		case CMD_SEEK:
			if (!req_seek(cli))
				err = 1;
			break;
		case CMD_JUMP_TO:
			if (!req_jump_to(cli))
				err = 1;
			break;
		case CMD_GET_SNAME:
			if (!send_sname(cli))
				err = 1;
			break;
		case CMD_GET_STATE:
			if (!send_data_int(cli, audio_get_state()))
				err = 1;
			break;
		case CMD_GET_BITRATE:
			if (!send_data_int(cli, sound_info.bitrate))
				err = 1;
			break;
		case CMD_GET_AVG_BITRATE:
			if (!send_data_int(cli, sound_info.avg_bitrate))
				err = 1;
			break;
		case CMD_GET_RATE:
			if (!send_data_int(cli, sound_info.rate))
				err = 1;
			break;
		case CMD_GET_CHANNELS:
			if (!send_data_int(cli, sound_info.channels))
				err = 1;
			break;
		case CMD_NEXT:
			audio_next ();
			break;
		case CMD_PREV:
			audio_prev ();
			break;
		case CMD_PING:
			if (!send_int(cli->socket, EV_PONG))
				err = 1;
			break;
		case CMD_GET_OPTION:
			if (!send_option(cli))
				err = 1;
			break;
		case CMD_SET_OPTION:
			if (!get_set_option(cli))
				err = 1;
			break;
		case CMD_GET_MIXER:
			if (!send_data_int(cli, audio_get_mixer()))
				err = 1;
			break;
		case CMD_SET_MIXER:
			if (!set_mixer(cli))
				err = 1;
			break;
		case CMD_DELETE:
			if (!delete_item(cli))
				err = 1;
			break;
		case CMD_SEND_PLIST_EVENTS:
			cli->wants_plist_events = 1;
			logit ("Request for events");
			break;
		case CMD_GET_PLIST:
			if (!get_client_plist(cli))
				err = 1;
			break;
		case CMD_SEND_PLIST:
			if (!req_send_plist(cli))
				err = 1;
			break;
		case CMD_CAN_SEND_PLIST:
			cli->can_send_plist = 1;
			break;
		case CMD_CLI_PLIST_ADD:
		case CMD_CLI_PLIST_DEL:
		case CMD_CLI_PLIST_CLEAR:
		case CMD_CLI_PLIST_MOVE:
			if (!plist_sync_cmd(cli, cmd))
				err = 1;
			break;
		case CMD_LOCK:
			if (!client_lock(cli))
				err = 1;
			break;
		case CMD_UNLOCK:
			if (!client_unlock(cli))
				err = 1;
			break;
		case CMD_GET_SERIAL:
			if (!send_serial(cli))
				err = 1;
			break;
		case CMD_PLIST_GET_SERIAL:
			if (!req_plist_get_serial(cli))
				err = 1;
			break;
		case CMD_PLIST_SET_SERIAL:
			if (!req_plist_set_serial(cli))
				err = 1;
			break;
		case CMD_GET_TAGS:
			if (!req_get_tags(cli))
				err = 1;
			break;
		case CMD_TOGGLE_MIXER_CHANNEL:
			req_toggle_mixer_channel ();
			break;
		case CMD_TOGGLE_SOFTMIXER:
			req_toggle_softmixer ();
			break;
		case CMD_GET_MIXER_CHANNEL_NAME:
			if (!req_get_mixer_channel_name(cli))
				err = 1;
			break;
		case CMD_GET_FILE_TAGS:
			if (!get_file_tags(client_id))
				err = 1;
			break;
		case CMD_ABORT_TAGS_REQUESTS:
			if (!abort_tags_requests(client_id))
				err = 1;
			break;
		case CMD_LIST_MOVE:
			if (!req_list_move(cli))
				err = 1;
			break;
		case CMD_TOGGLE_EQUALIZER:
			req_toggle_equalizer();
			break;
		case CMD_EQUALIZER_REFRESH:
			req_equalizer_refresh();
			break;
		case CMD_EQUALIZER_PREV:
			req_equalizer_prev();
			break;
		case CMD_EQUALIZER_NEXT:
			req_equalizer_next();
			break;
		case CMD_TOGGLE_MAKE_MONO:
			req_toggle_make_mono();
			break;
		case CMD_QUEUE_ADD:
			if (!req_queue_add(cli))
				err = 1;
			break;
		case CMD_QUEUE_DEL:
			if (!req_queue_del(cli))
				err = 1;
			break;
		case CMD_QUEUE_CLEAR:
			logit ("Clearing the queue");
			audio_queue_clear ();
			add_event_all (EV_QUEUE_CLEAR, NULL);
			break;
		case CMD_QUEUE_MOVE:
			if (!req_queue_move(cli))
				err = 1;
			break;
		case CMD_GET_QUEUE:
			if (!req_send_queue(cli))
				err = 1;
			break;
		default:
			logit ("Bad command (0x%x) from the client", cmd);
			err = 1;
	}

	if (err) {
		logit ("Closing client connection due to error");
		close (cli->socket);
		del_client (cli);
	}
}
Example #14
0
void cpu_exception_abort(int exception, int *esp)
{
	int i;
	char s[32];

//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 0, 0xFFFFFF, (const uchar *)cpu_exceptions[exception]);
//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 16, 0xFFFFFF, "***registers info***");

	sprintf(s, "%s\n\r", (uchar *)cpu_exceptions[exception]);
	send_serial(s);

//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 32, 0xFFFFFF, "#PUSHAD by _asm_inthandler");

	send_serial("#PUSHAD by _asm_inthandler\n\r");

	for(i = 0; i <= 7; i++){
//		sprintf(s, "%s:0x%08X", cpu_exception_infos[i], esp[i]);
//		putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 16 * (i + 3), 0xFFFFFF, s);

		sprintf(s, "%s:0x%08X\n\r", cpu_exception_infos[i], esp[i]);
		send_serial(s);
	}

//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 176, 0xFFFFFF, "#PUSH by _asm_inthandler");
	send_serial("#PUSH by _asm_inthandler\n\r");

	for(i = 8; i <= 9; i++){
//		sprintf(s, "%s:0x%08X", cpu_exception_infos[i], esp[i]);
//		putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 16 * (i + 4), 0xFFFFFF, s);

		sprintf(s, "%s:0x%08X\n\r", cpu_exception_infos[i], esp[i]);
		send_serial(s);
	}

//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 224, 0xFFFFFF, "#PUSH by CPU");

	send_serial("#PUSH by CPU\n\r");
	for(i = 10; i <= 15; i++){
//		sprintf(s, "%s:0x%08X", cpu_exception_infos[i], esp[i]);
//		putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 16 * (i + 5), 0xFFFFFF, s);

		sprintf(s, "%s:0x%08X\n\r", cpu_exception_infos[i], esp[i]);
		send_serial(s);
	}

	send_serial("#Control Registers\n\r");
	sprintf(s, "CR0 = 0x%08X\n\r", load_cr0());
	send_serial(s);
	sprintf(s, "CR2 = 0x%08X\n\r", load_cr2());
	send_serial(s);
	sprintf(s, "CR3 = 0x%08X\n\r", load_cr3());
	send_serial(s);

	for(;;){
		io_hlt();
	}
}
Example #15
0
/*
 * Check for transmission errors
 */
int check_file_chunk(HANDLE hCom, HANDLE hProg, int file_offset, int lc3_offset, int chunk_size, int *pErr_cnt, int progress_done, int progress_whole) {
	const int nbuff_words = 1024;
	unsigned char buff[nbuff_words*2];
	DWORD bytesRead;
	DWORD remain;	// how many bytes of this chunk remaining to send
	DWORD part;	// how many bytes to send in one go (limited by buffer size and remaining data)

	// Wait some time to allow device to respond
	Sleep(200);
	PurgeComm(hCom, PURGE_RXCLEAR);

	//// Send Memory Download command:
	// Header:
	buff[0] = LC3_CMD_GET_MEM[0];
	buff[1] = LC3_CMD_GET_MEM[1];
	// Transmission size: Network order (big-endian) in LC3 words
	buff[2] = (char)(chunk_size/2 / 256);
	buff[3] = (char)(chunk_size/2 % 256);
	// Offset: Network order (big-endian) in LC3 words
	buff[4] = (char)(lc3_offset/2 / 256);
	buff[5] = (char)(lc3_offset/2 % 256);
	if (send_serial(hCom, buff, 6) < 6) {
		return -1;
	}

	*pErr_cnt = 0;
	{
		unsigned char lc3_buff[nbuff_words*2];
		DWORD lc3_bytesRead;
		int i;

		// Wait some time to allow device to respond
		SetFilePointer(hProg, file_offset, NULL, FILE_BEGIN); // Set file pointer at the start of the program (omit offset)
		SetLastError(ERROR_SUCCESS);
		remain = chunk_size;
		part = min(nbuff_words*2, remain);
		while (remain &&
				ReadFile(hProg, buff, part, &bytesRead, NULL)
				&& bytesRead!=0) {
			if (bytesRead < part) {
				local_message("Warning: ReadFile() returned only some of requested data\n");
			}
			if (!ReadFile(hCom, lc3_buff, bytesRead, &lc3_bytesRead, NULL)
					|| lc3_bytesRead < bytesRead){
				local_message("Read from serial failed (received %lu of %d, error: %lu)\n",
						lc3_bytesRead, bytesRead, GetLastError());
				return -1;
			}
			for (i=0; i < bytesRead; i++) {
				if (buff[i] != lc3_buff[i]) {
					(*pErr_cnt)++;
					if (*pErr_cnt < NUMBER_OF_CHUNK_ERRORS_TO_SHOW) {
						local_message("\r Error at byte %d (send:0x%02x, received:0x%02x)                 \n",
								file_offset+(chunk_size-remain)+i, buff[i], lc3_buff[i]);
					} else if (*pErr_cnt == NUMBER_OF_CHUNK_ERRORS_TO_SHOW) {
						local_message("\r Error at byte %d (send:0x%02x, received:0x%02x) (next errors will not be reported)\n",
								file_offset+(chunk_size-remain)+i, buff[i], lc3_buff[i]);
					}

				}
			}

			remain -= bytesRead;
			local_message("\r%3d%% complete     --  %5lu of %5lu bytes verified      ",
				       (int)((progress_done+chunk_size-remain)*100/progress_whole), (progress_done+chunk_size-remain), progress_whole);
			part = min(nbuff_words*2, remain);
		}
	}

	return 0;
}