[tuxdroid-svn] r1214 - firmware/tuxup/trunk
Status: Beta
Brought to you by:
ks156
From: Paul_R <c2m...@c2...> - 2008-06-04 09:50:47
|
Author: Paul_R Date: 2008-06-04 11:37:42 +0200 (Wed, 04 Jun 2008) New Revision: 1214 Added: firmware/tuxup/trunk/tux_hid_win32.c firmware/tuxup/trunk/tux_hid_win32.h Modified: firmware/tuxup/trunk/Makefile firmware/tuxup/trunk/bootloader.c firmware/tuxup/trunk/bootloader.h firmware/tuxup/trunk/main.c Log: * Added the compatibility with windows. With Windows, only the HID version is considered. The code is a bit messy for now. I have to clean it up when I will have the time. To compile tuxup for Windows, you have to install MinGWStudio. All the binaries must be in the path. You need also the win api package, downloadable here : ftp://gd.tuwien.ac.at/gnu/mingw/ (w32api), and modify the makefile to specify the path of the w32api files. Modified: firmware/tuxup/trunk/Makefile =================================================================== --- firmware/tuxup/trunk/Makefile 2008-06-04 09:10:38 UTC (rev 1213) +++ firmware/tuxup/trunk/Makefile 2008-06-04 09:37:42 UTC (rev 1214) @@ -3,23 +3,74 @@ ##################################################### ## General Flags -CC = gcc +ifdef windir + CC = "gcc.exe" + DEFS = -DWIN32 + C_INCLUDE_DIRS = -I"C:\bin\MinGWStudio\MinGW\include\ddk" + CFLAGS = -pipe -Wall -funsigned-char -g2 -O0 + LIBS = -lwinmm -lhid -lsetupapi -lhidparse +else + CC = gcc + DEFS = + CFLAGS = -g -Wall $(DEFS) + LIBS = -lusb +endif TARGET = tuxup -CFLAGS = -g -Wall ## Libraries -LIB = -lusb ## Objects that must be built in order to link -FILES = main.c usb-connection.c bootloader.c tux_hid_unix.c tux_misc.c +FILES = main.c usb-connection.c bootloader.c tux_hid_win32.c tux_misc.c -## Build +## Compile and link +ifdef windir + SRC_OBJS = main.o bootloader.o tux_hid_win32.o tux_misc.o + +define build_target +@echo Linking... +@$(CC) -o "$(TARGET)" $(SRC_OBJS) $(LIB_DIRS) $(LIBS) $(LDFLAGS) +endef + +define compile_source +@echo Compiling $< +@$(CC) $(CFLAGS) $(C_PREPROC) $(C_INCLUDE_DIRS) -c "$<" -o "$@" +endef + +.PHONY: print_header +$(TARGET): print_header $(SRC_OBJS) + $(build_target) + +print_header: + @echo Start compiling + +main.o: main.c \ +tux-api.h \ +bootloader.h \ +version.h \ +tux_misc.h \ +tux_hid_win32.h + $(compile_source) + +bootloader.o: bootloader.c \ +tux_misc.h \ +tux_hid_win32.h \ +tux-api.h + $(compile_source) + +tux_hid_win32.o: tux_hid_win32.c \ +tux_hid_win32.h \ +tux_misc.h + $(compile_source) + +tux_misc.o: tux_misc.c \ +tux_misc.h + $(compile_source) + +else all: $(TARGET) - -## Compile and link tuxup: main.c bootloader.c bootloader.h usb-connection.c usb-connection.h tux_hid_unix.c tux_hid_unix.h tux_misc.c tux_misc.h tux-api.h version.h common/commands.h - ${CC} ${LIB} ${CFLAGS} -o tuxup main.c bootloader.c usb-connection.c \ - tux_hid_unix.c tux_misc.c - + ${CC} ${LIBS} ${CFLAGS} ${C_INCLUDE_DIRS} ${DEFS} -o tuxup \ + main.c bootloader.c usb-connection.c tux_hid_unix.c tux_misc.c +endif clean : -rm -f $(TARGET) *.o Modified: firmware/tuxup/trunk/bootloader.c =================================================================== --- firmware/tuxup/trunk/bootloader.c 2008-06-04 09:10:38 UTC (rev 1213) +++ firmware/tuxup/trunk/bootloader.c 2008-06-04 09:37:42 UTC (rev 1214) @@ -32,8 +32,14 @@ #include <stdlib.h> #include <time.h> #include <string.h> -#include "usb-connection.h" -#include "tux_hid_unix.h" +#ifdef WIN32 +# include "tux_misc.h" +# include "tux_hid_win32.h" +# include <windows.h> +#else +# include "usb-connection.h" +# include "tux_hid_unix.h" +#endif #include "tux-api.h" /* Whether to display verbose messages. */ @@ -62,7 +68,9 @@ #define BOOT_FILLPAGE 2 #define BOOT_EXIT 3 -static bool wait_status(uint8_t value, int timeout); +#ifndef WIN32 +static bool wait_status(char value, int timeout); +#endif static void compute_progress_bar(float line_nb); typedef uint32_t FILE_Addr_t; @@ -94,7 +102,9 @@ FILE_Addr_t currAddr; /* Current address in memory being processed */ uint8_t *segmentData; /* Complete segment data */ int segmentDataIdx; /* Index used for filling in the segment data */ +#ifndef WIN32 usb_dev_handle *dev_handle; /* USB device handle for sending parsed data */ +#endif } Parser_t; /** @@ -261,7 +271,7 @@ /** * Put one byte of data in the segmentData */ -static int fillSegment(Parser_t * parser, uint8_t data) +static int fillSegment(Parser_t * parser, unsigned char data) { parser->segmentData[parser->segmentDataIdx++] = data; parser->currAddr++; @@ -276,7 +286,7 @@ int finishSegment(Parser_t * parser) { int i, idx = 0; - uint8_t data_buffer[36]; + unsigned char data_buffer[36]; int ret; /* Indicate that we completed a segment */ @@ -310,10 +320,12 @@ { ret = tux_hid_write(36, data_buffer); } +#ifndef WIN32 else { ret = usb_send_commands(parser->dev_handle, data_buffer, 36); } +#endif #if (PRINT_DATA) printf("Status of the first packet sent: %d\n", ret); #endif @@ -338,10 +350,12 @@ { ret = tux_hid_write(34, data_buffer); } +#ifndef WIN32 else { ret = usb_send_commands(parser->dev_handle, data_buffer, 34); } +#endif #if (PRINT_DATA) printf("Status of the second packet sent: %d\n", ret); #endif @@ -363,14 +377,20 @@ */ if (HID) { +#ifdef WIN32 + ret = tux_hid_read(5, data_buffer); + counter ++; +#else ret = (wait_status(++counter, USB_TIMEOUT)); - tux_hid_read(5, data_buffer); +#endif } +#ifndef WIN32 else { ret = usb_get_commands(parser->dev_handle, data_buffer, 5); counter ++; } +#endif #if (PRINT_DATA) printf("Status of feedback from bootloader: %x\n", ret); #endif @@ -384,12 +404,14 @@ progress += step; } fflush (stdout); + sleep(0.05); return TRUE; } else { + printf("%d\n", 0xF0); fprintf(stderr, - "\nBootloading failed, program aborted at dongle reply.\n"); + "Bootloading failed, program aborted at dongle reply.\n"); exit(1); } } @@ -617,8 +639,11 @@ /** * Parses an intel hex file, calling the appropriate callbacks along the way */ - +#ifdef WIN32 +static int FILE_ParseFile(const char *fileName) +#else static int FILE_ParseFile(usb_dev_handle * dev_h, const char *fileName) +#endif { FILE *fs = NULL; Parser_t parser; @@ -631,7 +656,9 @@ parser.segLen = 0x40; /* XXX this is not a good way to pass the handle up to finishSegment, any better idea? */ +#ifndef WIN32 parser.dev_handle = dev_h; +#endif if ((parser.segmentData = malloc(parser.segLen + 2)) == NULL) { @@ -680,12 +707,15 @@ /** * Bootloads a CPU with the provided hex file */ - +#ifdef WIN32 +int bootload(uint8_t cpu_address, uint8_t mem_t, const char *filename) +#else int bootload(usb_dev_handle * dev_h, uint8_t cpu_address, uint8_t mem_t, const char *filename) +#endif { int rc = FALSE; - uint8_t data_buffer[5]; + unsigned char data_buffer[5]; uint8_t page_size = 64; /* XXX Should depend on CPU type */ uint8_t packet_total = 2; /* XXX should depend on CPU type */ int ret; @@ -694,10 +724,16 @@ /* Set global variable mem_type to the memory type */ mem_type = mem_t; +#ifndef WIN32 + /* For *nix system, display the memory type and prepare the progress bar. + * ex : FLASH [ ] + */ + /** \todo Find how works the escape sequences on windows */ if (mem_type == EEPROM) printf("EEPROM [\033[s\033[61C]\033[u\033[1B"); else printf("FLASH [\033[s\033[61C]\033[u\033[1B"); +#endif /* Bootloader initialization */ data_buffer[0] = LIBUSB_I2C_HEADER; data_buffer[1] = BOOT_INIT; @@ -714,11 +750,20 @@ ret = tux_hid_write(5, data_buffer); sleep(1); } +#ifndef WIN32 else { ret = usb_send_commands(dev_h, data_buffer, 5); } - +#endif +#ifdef WIN32 + tux_hid_read(5, data_buffer); + if (data_buffer[2] != BOOT_INIT_ACK) + { + fprintf(stderr, "\nInitialisazation failed \n"); + } + +#else if (HID) { if (!wait_status(BOOT_INIT_ACK, USB_TIMEOUT) || !ret) @@ -735,10 +780,17 @@ if (ret != 5) return FALSE; /* initialization failed */ } +#endif /* Bootloader: parse hex file and send data */ +#ifdef WIN32 + if (FILE_ParseFile(filename)) +#else if (FILE_ParseFile(dev_h, filename)) +#endif + { rc = TRUE; + } /* Exit bootloader */ data_buffer[0] = LIBUSB_I2C_HEADER; @@ -752,33 +804,44 @@ if (HID) { tux_hid_write(5, data_buffer); +#ifdef WIN32 + sleep(1); +#endif tux_hid_read(5, data_buffer); +#ifdef WIN32 + if (data_buffer[2] != BOOT_EXIT_ACK) +#else if (!wait_status(BOOT_EXIT_ACK, USB_TIMEOUT)) +#endif { fprintf(stderr, "\nBootloader exit failed \n"); return FALSE; } } +#ifndef WIN32 else { ret = usb_send_commands(dev_h, data_buffer, 5); ret = usb_get_commands(dev_h, data_buffer, 5); } +#endif return rc; } -/* - * Wait a specific ACK. + +/** + * \brief Wait a specific ACK. * This function wait for a specific value of the second parameter of the * bootloader ACK. */ -static bool wait_status(uint8_t value, int timeout) +#ifndef WIN32 +static bool wait_status(char value, int timeout) { - uint8_t data_buffer[5]; + unsigned char data_buffer[5]; uint8_t sttime = time(NULL); uint8_t edtime = 0; tux_hid_read(5, data_buffer); - while (data_buffer[2] != value || data_buffer[0] != 0xF0) + while ((data_buffer[2] != value) || (data_buffer[0] != 0xF0)) { edtime = time(NULL); if (difftime(edtime, sttime) > timeout) @@ -790,7 +853,15 @@ } return 1; } +#endif +/** + * \brief Compute the progress bar depending of the number of line in the file. + * One packet use 4 line. So, to know the number of packet to send, just divide + * the line number per 4. + * This progress bar display 60 "#" + * \todo Find a better way to now the number of packet. + */ static void compute_progress_bar(float line_nb) { line_nb = (line_nb / 4); Modified: firmware/tuxup/trunk/bootloader.h =================================================================== --- firmware/tuxup/trunk/bootloader.h 2008-06-04 09:10:38 UTC (rev 1213) +++ firmware/tuxup/trunk/bootloader.h 2008-06-04 09:37:42 UTC (rev 1214) @@ -23,8 +23,10 @@ #define bootloader_h #include <stdbool.h> extern bool HID; - +#ifdef WIN32 +int bootload(uint8_t cpu_address, uint8_t mem_type, const char *filename); +#else int bootload(usb_dev_handle * dev_h, uint8_t cpu_address, uint8_t mem_type, const char *filename); - #endif +#endif Modified: firmware/tuxup/trunk/main.c =================================================================== --- firmware/tuxup/trunk/main.c 2008-06-04 09:10:38 UTC (rev 1213) +++ firmware/tuxup/trunk/main.c 2008-06-04 09:37:42 UTC (rev 1214) @@ -26,19 +26,24 @@ #include <unistd.h> #include <time.h> #include <string.h> -#include <linux/limits.h> #include "tux-api.h" -#include "usb-connection.h" -#include "tux_hid_unix.h" #include "bootloader.h" #include "version.h" #include "common/defines.h" #include "tux_misc.h" - +#ifdef WIN32 +# include "tux_hid_win32.h" +# include <windows.h> +#else +# include "usb-connection.h" +# include "tux_hid_unix.h" +#endif #define countof(X) ( (size_t) ( sizeof(X)/sizeof*(X) ) ) +#define PATH_MAX 100 /* Messages. */ +#ifndef WIN32 static char const *msg_old_firmware = "\nERROR: Your dongle firmware is too old to support switching to bootloader" "\nmode automatically.\n" @@ -52,7 +57,7 @@ " you want to use).\n" "\nCheck http://www.tuxisalive.com/documentation/how-to/updating-the-firmware" "\nfor more details.\n"; - +#endif static char const *msg_dfu_programmer_not_installed = "\nERROR: dfu-programmer is not installed or is not in your path, tuxup uses" "\nit to reprogram the USB cpu so installing dfu-programmer is mandatory.\n"; @@ -73,8 +78,10 @@ static int pretend = 0; /* USB handle */ +#ifndef WIN32 static struct usb_device *device; static struct usb_dev_handle *dev_h; +#endif static int usb_connected = 0; /* Flag for usb connection status */ /* @@ -109,14 +116,16 @@ static void fux_connect(void) { +#ifndef WIN32 int wait = 5; - +#endif if (usb_connected) return; /* First, try to found a HID device */ if (!(tux_hid_capture(TUX_VID, TUX_PID))) { +#ifndef WIN32 /* Unable to capture the device : * Try with the libusb */ for (;;) @@ -140,6 +149,10 @@ /* The dongle is a libusb device */ HID = 0; } +#else + fprintf(stderr, "The dongle was not found, now exiting.\n"); + exit(1); +#endif } else { @@ -154,6 +167,7 @@ /* Check if we have the old firmware that requires entering * bootloader mode manually, exits with a message that explains what * to do in such a case. */ +#ifndef WIN32 if (!HID) { if (device->descriptor.bcdDevice < 0x030) @@ -169,6 +183,7 @@ exit(1); } } +#endif if (verbose) printf("Interface configured \n\n"); usb_connected = 1; @@ -184,11 +199,13 @@ { tux_hid_release(); } +#ifndef WIN32 else { usb_release_interface(dev_h, USB_COMMAND); usb_close(dev_h); } +#endif if (verbose) printf(" ... interface closed \n"); usb_connected = 0; @@ -290,14 +307,27 @@ if (pretend) return 0; - +#ifdef WIN32 + if (bootload(cpu_i2c_addr, FLASH, filename)) +#else if (bootload(dev_h, cpu_i2c_addr, FLASH, filename)) - { +#endif + { +#ifdef WIN32 + printf(" OK \n"); +#else printf("\033[2C[ \033[01;32mOK\033[00m ]\n"); +#endif return 0; } else + { +#ifdef WIN32 + printf(" FAIL \n"); +#else printf("\033[2C[\033[01;31mFAIL\033[00m]\n"); +#endif + } return 1; } @@ -328,21 +358,34 @@ if (pretend) return 0; - +#ifdef WIN32 + if (bootload(cpu_i2c_addr, EEPROM, filename)) +#else if (bootload(dev_h, cpu_i2c_addr, EEPROM, filename)) +#endif { +#ifdef WIN32 + printf("OK\n"); +#else printf("\033[2C[ \033[01;32mOK\033[00m ]\n"); +#endif return 0; } else + { +#ifdef WIN32 + printf("Fail \n"); +#else printf("\033[2C[\033[01;31mFAIL\033[00m]\n"); - return 1; +#endif + } + return 1; } static int prog_usb(char const *filename) { /* XXX include those as defines in commands.h */ - uint8_t send_data[5] = { 0x01, 0x01, 0x00, 0x00, 0xFF }; + unsigned char send_data[5] = { 0x01, 0x01, 0x00, 0x00, 0xFF }; char tmp_string[PATH_MAX]; int ret; version_bf_t version; @@ -405,6 +448,7 @@ tux_hid_write(5, send_data); sleep(1); } +#ifndef WIN32 else { ret = usb_send_commands(dev_h, send_data, 5); @@ -421,6 +465,7 @@ return 1; } } +#endif } ret = system("dfu-programmer at89c5130 erase"); if (ret) @@ -678,10 +723,12 @@ { tux_hid_write(5, send_data); } +#ifndef WIN32 else { ret = usb_send_commands(dev_h, send_data, 5); } +#endif fux_disconnect(); } Added: firmware/tuxup/trunk/tux_hid_win32.c =================================================================== --- firmware/tuxup/trunk/tux_hid_win32.c (rev 0) +++ firmware/tuxup/trunk/tux_hid_win32.c 2008-06-04 09:37:42 UTC (rev 1214) @@ -0,0 +1,224 @@ +/* + * Tux Droid - Hid interface (only for windows) + * Copyright (C) 2008 C2ME Sa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifdef WIN32 + +#include <windows.h> +#include <hidsdi.h> +#include <setupapi.h> +#include <dbt.h> +#include <stdbool.h> +#include <stdio.h> + +#include "tux_hid_win32.h" +#include "tux_misc.h" + +static char device_symbolic_name[256] = ""; +static HANDLE tux_device_hdl = NULL; +static COMMTIMEOUTS timeout; +/** + * \brief Open the device. + * \param vendor_id The vendor ID constant of the device. + * \param product_id The product ID of the device. + * This function search for a specified device and try to open the + * communication. + * \return True if the device has been correctly opened. + */ +bool LIBLOCAL +tux_hid_capture(int vendor_id, int product_id) +{ + GUID hid_guid; + HANDLE h_dev_info; + SP_DEVICE_INTERFACE_DATA dev_info_data; + PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; + int member_index = 0; + bool last_device = false; + long result; + unsigned long length = 0; + ULONG required; + HANDLE device_hdl = NULL; + HIDD_ATTRIBUTES attributes; + bool tux_found = false;; + + if (tux_device_hdl != NULL) + { + return false; + } + HidD_GetHidGuid(&hid_guid); + + h_dev_info = SetupDiGetClassDevs(&hid_guid, \ + NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); + + dev_info_data.cbSize = sizeof(dev_info_data); + + member_index = 0; + + do + { + result = SetupDiEnumDeviceInterfaces(h_dev_info, 0, + &hid_guid, member_index, &dev_info_data); + + if (result != 0) + { + result = SetupDiGetDeviceInterfaceDetail(h_dev_info, + &dev_info_data, NULL, 0, &length, NULL); + + detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(length); + detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + result = SetupDiGetDeviceInterfaceDetail(h_dev_info, + &dev_info_data, detail_data, length, &required, NULL); + + device_hdl = CreateFile(detail_data->DevicePath, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, 0, NULL); + + attributes.Size = sizeof(attributes); + result = HidD_GetAttributes(device_hdl, &attributes); + + if ((attributes.VendorID == vendor_id) && + (attributes.ProductID == product_id)) + { + printf(device_symbolic_name, "%s", detail_data->DevicePath); + + CloseHandle(device_hdl); + + tux_device_hdl = CreateFile(detail_data->DevicePath, + GENERIC_WRITE|GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, 0, NULL); + + timeout.ReadTotalTimeoutConstant = HID_RW_TIMEOUT; + timeout.WriteTotalTimeoutConstant = HID_RW_TIMEOUT; + SetCommTimeouts(tux_device_hdl, &timeout); + + tux_found = true; + + break; + } + + CloseHandle(device_hdl); + free(detail_data); + } + else + { + last_device = true; + } + + member_index++; + + } + while (last_device == false); + + if (tux_found) + { + return true; + } + else + { + return false; + } +} +/** + * \brief Release the actual device. + * This function close the device. + */ +void LIBLOCAL +tux_hid_release(void) +{ + if (tux_device_hdl != NULL) + { + CloseHandle(tux_device_hdl); + tux_device_hdl = NULL; + } +} + +/** + * \brief Write a frame on the USB bus. + * \param size The number of byte to write. + * \param buffer A pointer to a buffer containing the data. + * \return True if no error has been detected. + * Write a frame buffer on the USB device. + * For Tux, we don't use the report ID, so it's always null. + */ +bool LIBLOCAL +tux_hid_write(int size, const unsigned char *buffer) +{ + long wrt_count; + char report[65] = { [0 ... 64] = 0 }; + long result; + + if (tux_device_hdl == NULL) + { + return false; + } + + report[0] = 0; + memcpy(&report[1], buffer, size); + + result = WriteFile(tux_device_hdl, report, 65, &wrt_count, NULL); + + if (!result) + { + return false; + } + else + { + return true; + } +} + +/** + * \brief Read a byte on the USB bus. + * \param size The number of data to read. + * \param buffer Pointer to a buffer to write received data. + * \return True if no error has been detected. + * This function read 'size' bytes on the USB device. + * For Tux, we don't use the report ID, so the first byte of the received frame + * is always ignored. + * /!\ The report buffer size must be the same than the report of the device. + */ +bool LIBLOCAL +tux_hid_read(int size, unsigned char *buffer) +{ + long rd_count; + char report[65]; + long result; + + if (tux_device_hdl == NULL) + { + return false; + } + + result = ReadFile(tux_device_hdl, report, 65, &rd_count, NULL); + memcpy(buffer, &report[1], size); + + if (!result) + { + return false; + } + else + { + return true; + } +} + +#endif /* WIN32 */ Added: firmware/tuxup/trunk/tux_hid_win32.h =================================================================== --- firmware/tuxup/trunk/tux_hid_win32.h (rev 0) +++ firmware/tuxup/trunk/tux_hid_win32.h 2008-06-04 09:37:42 UTC (rev 1214) @@ -0,0 +1,34 @@ +/* + * Tux Droid - Hid interface (only for windows) + * Copyright (C) 2008 C2ME Sa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#ifdef WIN32 + +#ifndef _TUX_HID_H_ +#define _TUX_HID_H_ + +#define HID_RW_TIMEOUT 1000 + +extern bool tux_hid_capture(int vendor_id, int product_id); +extern void tux_hid_release(void); +extern bool tux_hid_write(int size, const unsigned char *buffer); +extern bool tux_hid_read(int size, unsigned char *buffer); + +#endif /* _TUX_HID_H_ */ + +#endif /* WIN32 */ |