|
|
View previous topic :: View next topic |
Author |
Message |
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
18F4550 PICUSB interface to Microchip mpusbapi.dll Delphi Ex |
Posted: Wed Aug 16, 2006 8:50 am |
|
|
English is the langua franca of this board so here is an english version.
Gracias a JIM for the original code posting in Spanish. This code is similar but different in some details.
Info:
a) This example is for Bulk transfer and is Bus powered
b) The PC delphi code example interfaces with mpusbapi.dll
c) After enumeration the device manager will show PIC 18XX5X USB Devices sub cat PicUSB
The PIC 18XX5X USB Devices is only visible in the device manager when enumerated correctly. Incorrect enumeration may result in a caution flag device not working or will display nothing ( a.k.a. a Microsoft politically correct multilanguage error message that's equally useful for the deaf dumb and blind).
d) Works with Win2000 should work with WinXP
e) vid is $04D8 and pid is $0011
these numbers are correlated with the data in the drivers install
file picusb.inf
This file has dependency files mchpusb.sys picusbci.dll picusb.cat
wdmstub.sys
Note:
If you can't find Jim's files go to
www.microchip.com and search for PICDEM Full Speed USB
and download MCHPFSUSB_Setup.exe run it and it will install the files
that are needed
Be aware
The files aren't the same as JIM used ( ex doesn't use picusbci.dll)
it uses mchpusb.inf for its install
Follow the instructions to alter the inf file for the PID 0011 if you you
use the code below or alternatively alter the PID in the pic
code descriptor
TB095 shows the install instructions and screen shots for the MCHPusb.sys driver If you use mchpfsusb then mchpusb.inf and not picusb.inf is the install file you'll be using
f) The file picusb.inf is used at install time ( done first time only) and results in the registration
HKey_LOCAL_MACHINE> SYSTEM>ControlSet001>Enum>USB
the external usb device (PIC18F4550) when enumerated will bind to
these Win 2000/XP drivers
g) The connections to the PIC are D- pin 23 Cable wire is white
D+ pin 24 Cable wire is Green
_____________
|XXXXXXXXXXX|
| |
| 1 2 3 4 |
|____________ |
5v D- D+ 0v
h) No need for external pullups on either D- or D+ ...PIC code
handles it
i)
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV2,VREGEN
// 20 mhz external crystal is pre scalled by div 5 (PLL5) to 4mhz
// PLL multiplies by 16 to 96Mhz USBDIV post scales with div by 2 to 48MHZ
// CPU clock is post scaled with
// CPUDIV1 by with div by 2 for 48 MHZ
// CPUDIV2 by with div by 3 for 32 MHZ
//
// Notes: working Aug6 2006
/// 1) PIC is powered from the usb port
// 2) if the PIC is removed without first being logically detached it will occasionally hang the port
// requiring a PC reboot to clear it
// 3) When running the debugger the ICDU40 can become desynched with the 18F4550
// Pressing the reset button on the PIC board before pressing go in the debugger
// will resysnc ( symptoms of desync are garbled printing in the monitor window
// garbage values of variables in the debugger .. the pic will appear to enumerate
// but all subsequent transfers are ruined.
// ICDU40 will show clock as 47.41 MHZ and is unstable if CPUDIV1 is used
// CPUDIV2 is used to give 32MHZ MCU clock
// to avoid 48MHZ CCS debugger issues above
// ( Note USB clock is set by USBDIV an is at 48MHZ)
///
/// 4) The PC interfaces in delphi via mpusbapi.dll
/// device manager will show after enumeration PIC18XX device
/// sub cat PICUSB
/// 5) this was installed via inf and sys files from microchip
// vid is $04D8 and pid is $0011
// these numbers are correlated with the data in the drivers install
// file picusb.inf
// this file has dependency files mchpusb.sys picusbci.dll picusb.cat
// wdmstub.sys
// the file picusb.inf is used at install time and results in the registration
// HKey_LOCAL_MACHINE> SYSTEM>ControlSet001>Enum>USB
// the external usb device (PIC18F4550) when enumerated will bind to these
// Win 2000/XP drivers
// 6) Changes to CCS config descriptor (PICUSB.h )to reflect bus powered
// 0xC0, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 reserved and bit7=1
// 0x80, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 reserved and bit7=1
// 0x64, //maximum bus power required (maximum milliamperes/2) (0x32 = 100mA 0x64 =200ma)
//
// Changes to device descriptor
// 0xD8,0x04, //vendor id Vid (0x04D8 is Microchip)
// 0x11,0x00, //product id Pid (0x0011)
// correlates with picusb.inf
// 7) example PC calls in this case Delphi
// function _MPUSBGetDLLVersion:DWORD; stdcall;external 'mpusbapi.dll';
// function _MPUSBGetDeviceCount(pVID_PID:PCHAR8):DWORD; stdcall;external 'mpusbapi.dll';
// function _MPUSBOpen(instance:DWORD;pVID_PID:PCHAR8;pEP:PCHAR8;dwDir:DWORD;dwReserved:DWORD):THANDLE; stdcall;external 'mpusbapi.dll';
// function _MPUSBRead(handle:THANDLE;var pData:PBYTE;dwLen:DWORD;var pLength:DWORD;dwMilliseconds:DWORD):DWORD; stdcall;external 'mpusbapi.dll';
// function _MPUSBReadInt(handle:THANDLE;var pData:PBYTE;dwLen:DWORD;var pLength:PDWORD;dwMilliseconds:DWORD):DWORD; stdcall;external 'mpusbapi.dll';
// function _MPUSBWrite(handle:THANDLE;pData:PBYTE;dwLen:DWORD;var pLength:DWORD;dwMilliseconds:DWORD):DWORD; stdcall;external 'mpusbapi.dll';
// function _MPUSBClose(handle:THANDLE):DWORD; stdcall;external 'mpusbapi.dll';
// vid_pid:PCHAR8='vid_04d8&pid_0011'; // VID and PID for Demo USB FS board
// out_pipe:PCHAR8='\MCHP_EP1';
// in_pipe:PCHAR8='\MCHP_EP1';
/// example of a PC call to turn on a led in th ePIC code below
/*
procedure led_control(mode:byte;red_green:byte;on_off:byte);
var
selection:DWORD;
send_buf:PBYTE;
receive_buf:PBYTE;
RecvLength:DWORD;
SentLength:DWORD;
label quit,finish;
begin
selection:=0; // USB device that have PID & VID as we configed.
myOutPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_WRITE,0);
myInPipe:= _MPUSBOpen(selection,vid_pid,in_pipe,MP_READ,0);
if ((myOutPipe = INVALID_HANDLE_VALUE) or (myInPipe = INVALID_HANDLE_VALUE)) then
begin
Form1.Edit1.text:='Status : USB Error';
exit;
end;
send_buf[0]:=mode; // ledmode command
send_buf[1]:=red_green; // red led
send_buf[2]:=on_off; // 0=off
RecvLength:=1;
// if write or read are successfull they return a handle ( non zero)
if(_MPUSBWrite(myOutPipe,send_buf,3,SentLength,1000)=0) then goto quit;
if( _MPUSBRead(myInPipe,receive_buf,1,RecvLength,1000)=0) then goto quit;
if (receive_buf[0] <> $55 ) then goto quit;
goto finish;
quit:
form1.Edit1.Text:='Status : LED Communication Error!';
finish:
_MPUSBClose(myOutPipe);
_MPUSBClose(myInPipe);
myInPipe:= INVALID_HANDLE_VALUE;
myOutPipe:=INVALID_HANDLE_VALUE;
end;
*/
////////////////////////////////// end of notes ///////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// on power connection RED LED flashes a heart beat when running
// green led is off until PIC is enumerated
// green led flashes when data is received
// yellow led flashes on a detach command
// PC delphi code controls red/green/yellow tristate led
// until a detach is made by delphi or a manual PIC button press
// after receipt of detach command yellow is flashed
//
#device ADC=10 /// select 10 bit value
/// special macros /////////////////////////////////////////////
/// #x id the litteral value of the variable x
/// suppose x is variable reboot then #x is the litteral "reboot"
#define debugnbr(x) printf("%s is %d\r\n",#x,x);
#define debughex(x) printf("%s is %X\r\n",#x,x);
#use delay(clock=32000000)
#define TRACE false
#define TRACE_HOST_REQ false
#use rs232(debugger)
// #USE RS232(STREAM=SIO,BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7) /* xmit pin c6 rcv c7 */
/////////////////////////////////////////////////////////////////////////////
//
// CCS Library dynamic defines. For dynamic configuration of the CCS Library
// for your application several defines need to be made. See the comments
// at usb.h for more information
//
/////////////////////////////////////////////////////////////////////////////
#define USB_HID_DEVICE FALSE //disable HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 64 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 64 //size to allocate for the rx endpoint 1 buffer
/////////////////////////////////////////////////////////////////////////////
//
// If you are using a USB connection sense pin, define it here. If you are
// not using connection sense, comment out this line. Without connection
// sense you will not know if the device gets disconnected.
// (connection sense should look like this:
// 100k
// 5V VBUS-----+----/\/\/\/\/\----- (USB_CON_SENSE_PIN ON PIC PIN_B5)
// |
// +----/\/\/\/\/\-----GND
// 100k
// (where VBUS is pin1 of the USB connector)
//
// USB power rail breaks connection after D- D+
/////////////////////////////////////////////////////////////////////////////
#define USB_CON_SENSE_PIN PIN_B5 // wired as above
//////////////////////////////////////////////
///
/// 5v ----/\/\/\--+--__\__---- GND
/// 100k | NO switch
/// |
/// B4 -------------
/////////////////////////////////////////////
#define MY_USB_DETACH_PIN PIN_B4
///// ADDITIONAL DEVICE PIN ASSIGNMENTS
#define ENUM_LED PIN_B0 /// green led for enumerated
/// flashes when data received
#define red_led PIN_B1
#define green_led PIN_B2
#define POWER_LED PIN_C0 /// flashes when not connected
/////////////////////////////////////////////////////////////////////////////
//
// Include the CCS USB Libraries. See the comments at the top of these
// files for more information
//
/////////////////////////////////////////////////////////////////////////////
/// without USB_USE_FULL_SPEED explicitly defined as FALSE (slow speed ) PIC defaults to high speed
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <PicUSB.h> //descriptors
/// Notes changes were made to the decriptors
/// see above note 6
#include <usb.c> //handles usb setup tokens and get descriptor reports
///// constant defines
#define LINK_CMD 0
#define LED_CMD 1
#define ADC_CMD 2
#define DETACH_CMD 3
#define LED_ON output_high
#define LED_OFF output_low
#define mode received[0]
#define param1 received[1]
#define param2 received[2]
#define result sent[0]
#define ack_connection 0x25
#define ack_led_cmd 0x55
#define ack_pot_cmd 0x65
#define BULK_SIZE 512
#define STOP_FLASHING 0
#define FOREVER 99
#define ALWAYS_OFF 98
#define ALWAYS_ON 97
/////////////////////////////////// GLOBALS ///////////////////////////////////////////////
char bulk_buffer[BULK_SIZE]; /// global environment string version file date time device clock
int16 index;
int8 yled_state,rled_state,yflashes,rflashes;
#INT_TIMER0
clock_isr()
{
switch (yflashes)
{
case STOP_FLASHING:
break;
case ALWAYS_ON:
yflashes=STOP_FLASHING;
LED_ON(green_led);
LED_ON(red_led);
break;
case ALWAYS_OFF:
yflashes=STOP_FLASHING;
LED_OFF(green_led);
LED_OFF(red_led);
break;
default:
if (yflashes!=FOREVER ) yflashes--;
if (yled_state)
{
LED_ON(green_led);
LED_ON(red_led);
yled_state=false;
}
else
{
LED_OFF(green_led);
LED_OFF(red_led);
yled_state=true;
}
}// end switch yflashes
switch(rflashes)
{
case STOP_FLASHING:
break;
case ALWAYS_ON:
LED_ON(POWER_LED);
rflashes=STOP_FLASHING;
break;
case ALWAYS_OFF:
LED_OFF(POWER_LED);
rflashes=STOP_FLASHING;
break;
default:
if (rflashes!=FOREVER ) rflashes--;
if (rled_state)
{
LED_ON(POWER_LED);
rled_state=false;
}
else
{
LED_OFF(POWER_LED);
rled_state=true;
}
}// end switch rflashes
}
void usb_print(char c)
{
/// called from printf char by char
if (index <BULK_SIZE) bulk_buffer[index++]=c;
}
void flash_yellow(int8 times)
{
yflashes=times; // assign gobal flashes for clock isr
}
void flash_power(int8 times)
{
rflashes=times; // assign gobal flashes for clock isr
}
/////////////////////////////////////////////////////////////////////////////
//
// usb_debug_task()
//
// When called periodically, displays debugging information over serial
// to display enumeration and connection states. Also lights green and red leds
// based upon enumeration and connection status.
//
/////////////////////////////////////////////////////////////////////////////
void usb_debug_task(void) {
static int8 last_connected;
static int8 last_enumerated;
int8 new_connected;
int8 new_enumerated;
new_connected=usb_attached();
new_enumerated=usb_enumerated();
if (new_connected)
flash_power(FOREVER);
else
flash_power(ALWAYS_ON);
if (new_enumerated)
LED_ON(ENUM_LED);
else
LED_OFF(ENUM_LED);
if (new_connected && !last_connected)
#IF TRACE
printf("\r\n\n attached ");
#ENDIF
if (!new_connected && last_connected)
#IF TRACE
printf("\r\n\n detached ");
#ENDIF
if (new_enumerated && !last_enumerated)
#IF TRACE
printf("\r\n\n enum ");
#ENDIF
if (!new_enumerated && last_enumerated)
#IF TRACE
printf("\r\n\n unenum ");
#ENDIF
last_connected=new_connected;
last_enumerated=new_enumerated;
}
void main(void) {
int8 received[3],i;
int8 data[2],reboots,sent[1];
int16 value;
rled_state=0;
yled_state=0;
set_timer0(0);
setup_counters(RTCC_INTERNAL,RTCC_DIV_32); //48mhz/4=12,000,000
// scaled by 256*256 (16 bit) includes every
// scaled by 32 12000000/256*256*32 .3 secs
flash_yellow(ALWAYS_OFF);
flash_power(ALWAYS_ON);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
setup_adc_ports( AN0_ANALOG);
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 ); ///// PIN A0
usb_init_cs();
reboots=0;
restart:
#IF TRACE
//debug(reboots);
printf("start=%X \n\r",reboots);
#ENDIF
// retreive environment info for LINK_CMD
index=0; /// begining of string id_string
printf(usb_print,"ver %s %s %s %s \n\r",getenv("VERSION_STRING"),__DATE__,__TIME__,getenv("DEVICE"));
printf(usb_print,"%s",__FILE__);
output_float(MY_USB_DETACH_PIN); /// allow 100k to pull pin high
while (TRUE)
{
usb_task();
usb_debug_task();
if(usb_enumerated())
{
if (input(MY_USB_DETACH_PIN)==0)
{
/// switch was closed
usb_put_packet(1, sent, 0, USB_DTS_TOGGLE); /// send 0 packet to terminate
usb_detach();
#IF TRACE
printf("detach manual\n\r");
#ENDIF
flash_yellow(FOREVER);
while(true); //freeze here waiting for unplugging
}
if (usb_kbhit(1))
{
LED_OFF(ENUM_LED); // flash to indicate data received
usb_get_packet(1, received, 3); //3bytes from pipe EP1 usb_get_packet(end pt, payload, payload size)
switch (mode) /// received[0] is mode
{
case LINK_CMD:
sent[0]=ack_connection;
usb_put_packet(1, sent, 1, USB_DTS_TOGGLE); //send 1byte via EP1 to PC 0x25 to acknowledge
//usb_get_packet(end pt, payload, payload size)
flash_yellow(ALWAYS_OFF); /// may have been on from prev detach
// printf("L"); ///!!!!!!!!!!!!!!!!!!!!!!!!!!!!! possible compiler bug work around
#IF TRACE
printf("\n\r mode=%X param1=%X param2=%X ACK",mode,param1,param2);
#ENDIF
usb_puts(1, bulk_buffer, index, 50); // data and length is sent
break;
case LED_CMD:
//// control tricolor both led red and green on gives yellow
flash_yellow(STOP_FLASHING); /// don't allow clock isr to control leds
if (param1 == 1 ) LED_ON(red_led);
if (param1 == 0 ) LED_OFF(red_led);
if (param2 == 1 ) LED_ON(green_led);
if (param2 == 0 ) LED_OFF(green_led);
sent[0]=ack_led_cmd;
usb_put_packet(1, sent, 1, USB_DTS_TOGGLE); //send 1byte via EP1 to PC 0x55 to acknowledge
#IF TRACE
printf("mode=%X param1=%X param2=%X\n\r",mode,param1,param2);
#ENDIF
break;
case ADC_CMD:
/// read the value of the center tap of a 50 k pot using the ADC
/// center tap is connected to A0 ADC channel0 outside legs to GND and 5V
sent[0]=ack_pot_cmd;
usb_put_packet(1, sent, 1, USB_DTS_TOGGLE); //send 1byte via EP1 to PC 0x55 to acknowledge
delay_ms(100);
value = Read_ADC(); /// 10 bit resolution data is overlayed on value
data[0]=make8(value,1);
data[1]=make8(value,0);
usb_put_packet(1, data, 2, USB_DTS_TOGGLE);
#IF TRACE
printf("mode=%X param1=%X param2=%X pot=%lu \n\r",mode,param1,param2,value);
#ENDIF
break;
case DETACH_CMD:
/// PC will issue a detach and PIC can be unplugged
usb_put_packet(1, sent, 0, USB_DTS_TOGGLE); /// send 0 packet to terminate
usb_detach(); // stop driving D- D+
#IF TRACE
printf("detach mode=%X\n\r",mode);
#ENDIF
flash_yellow(FOREVER);
break;
default:
//// unknown command so we detach and restart
usb_put_packet(1, sent, 0, USB_DTS_TOGGLE); /// send 0 packet to terminate
usb_detach();
#IF TRACE
printf("detach mode=%X\n\r",mode);
#ENDIF
flash_yellow(FOREVER);
goto restart;
} //end of switch
LED_ON(ENUM_LED); // end of flashing green enum to indicate data received LED
}// kbhit
}// enum
}// true
}
| [img][/img]
////////////////////////////// delphi pascal example PC code follows
////////// the pc needs the microchip driver installed to work
Code: | unit dkusb;
// uses the microchip interface dll mpusbapi.dll
// vid is $04D8 and pid is $0011
// these numbers are correlated with the data in the drivers install
// file picusb.inf
// this file has dependency files mchpusb.sys picusbci.dll picusb.cat
// wdmstub.sys
// the file picusb.inf is used at install time and results in the registration
// HKey_LOCAL_MACHINE> SYSTEM>ControlSet001>Enum>USB
// the external usb device (PIC18F4550) when enumerated will bind to these
// Win 2000/XP drivers
// the connections to the PIC are D- pin 23 Cable wire is white
// D+ pin 24 Cable wire is Green
// _____________
// |XXXXXXXXXXX|
// | |
// | 1 2 3 4 |
// |___________|
// 5v D- D+ 0v
//
// PIC18F4550 is coded to auto pull up on D+ to indicate High speed usb
// the PIC code contains the descriptors that will link and launch the
// the above PC system drivers
// Notes
// A USB message can be made up of one or more packets
// An in pipe and an out pipe are established
// more than one external device can use the system drivers
// using the same pid vid values.
///
// PIC sends $25 to acknowledge connection
// PIc sends $55 to acknowledge command ( led red/greem on/off)
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, dsled, ComCtrls, ExtCtrls, Buttons;
Const
MAXSIZE=64;
MPUSB_FAIL=0;
MPUSB_SUCCESS=1;
MP_WRITE:DWORD=0;
MP_READ:DWORD=1;
MAX_NUM_MPUSB_DEV=127;
type
DWORD = LongInt;
PCHAR8 = array[0..MAXSIZE] of char;
PBYTE = array[0..MAXSIZE] of BYTE;
PDWORD = array[0..MAXSIZE] of DWORD;
PVOID = Pointer;
UINT = Cardinal;
TForm1 = class(TForm)
Link_to_PC: TButton;
Label1: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Memo1: TMemo;
Devices: TButton;
dsled1: Tdsled;
detach: TButton;
Flash_blue: TTimer;
PICinfo: TLabel;
Label7: TLabel;
Image1: TImage;
Clear: TButton;
RS232_Tx: TButton;
RXtimer: TTimer;
RS232_Rx: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Link_to_PCClick(Sender: TObject);
procedure DevicesClick(Sender: TObject);
procedure detachClick(Sender: TObject);
procedure Flash_blueTimer(Sender: TObject);
procedure ClearClick(Sender: TObject);
procedure RS232_TxClick(Sender: TObject);
procedure RXtimerTimer(Sender: TObject);
procedure RS232RxClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function _MPUSBGetDLLVersion:DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBGetDeviceCount(pVID_PID:PCHAR8):DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBOpen(instance:DWORD;pVID_PID:PCHAR8;pEP:PCHAR8;dwDir:DWORD;dwReserved:DWORD):THANDLE; stdcall;external 'mpusbapi.dll';
function _MPUSBRead(handle:THANDLE;var pData:PBYTE;dwLen:DWORD;var pLength:DWORD;dwMilliseconds:DWORD):DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBReadInt(handle:THANDLE;var pData:PBYTE;dwLen:DWORD;var pLength:PDWORD;dwMilliseconds:DWORD):DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBWrite(handle:THANDLE;pData:PBYTE;dwLen:DWORD;var pLength:DWORD;dwMilliseconds:DWORD):DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBClose(handle:THANDLE):DWORD; stdcall;external 'mpusbapi.dll';
var
Form1: TForm1;
vid_pid:PCHAR8='vid_04d8&pid_0011'; // VID and PID for Demo USB FS board
out_pipe:PCHAR8='\MCHP_EP1';
in_pipe:PCHAR8='\MCHP_EP1';
myOutPipe:THANDLE;
myInPipe:THANDLE;
isConnected:boolean;
rcv_in_progress: boolean;
implementation
uses ShellAPI;
{$R *.DFM}
procedure CheckInvalidHandle;
begin
if(GetLastError=ERROR_INVALID_HANDLE) then
begin
_MPUSBClose(myOutPipe);
_MPUSBClose(myInPipe);
myInPipe:=INVALID_HANDLE_VALUE;
myOutPipe:=INVALID_HANDLE_VALUE;
end
else
ShowMessage('Error Code :'+inttostr(GetLastError()));
end;
Function GetSummary:Integer;
Var tempPipe:THandle;
count:DWORD;
max_Count:DWORD;
i:Byte;
dummy:pchar8;
Begin
tempPipe := INVALID_HANDLE_VALUE;
count:=0;
max_count := _MPUSBGetDeviceCount(vid_pid);
Form1.Memo1.Lines.Clear ;
if(max_count=0) then
Begin
result:= max_count;
Form1.Memo1.Lines.add('No device found');
exit;
End
Else
Form1.memo1.lines.add(IntToStr(max_Count) + ' device(s) with ' + vid_pid + ' currently attached');
count := 0;
For i:=0 to MAX_NUM_MPUSB_DEV-1 Do
Begin
tempPipe := _MPUSBOpen(i,vid_pid,dummy,MP_READ,0);
if(tempPipe <> INVALID_HANDLE_VALUE) then
Begin
Form1.memo1.lines.add('Instance Index ' + IntToStr(i));
_MPUSBClose(tempPipe);
Inc(count);
End;
if(count = max_count) Then break;
End;
result:= max_count;
End;//end GetSummary
function SendReceivePacket(SendData:PBYTE;SendLength:DWORD;var ReceiveData:PBYTE;
var ReceiveLength:DWORD;SendDelay:UINT;ReceiveDelay:UINT):DWORD; stdcall;
var
SentDataLength:DWORD ;
ExpectedReceiveLength:DWORD;
begin
ExpectedReceiveLength:= ReceiveLength;
if((myOutPipe <> INVALID_HANDLE_VALUE) and (myInPipe <> INVALID_HANDLE_VALUE)) then
begin
if(_MPUSBWrite(myOutPipe,SendData,SendLength,SentDataLength,SendDelay)<>0) then
if(_MPUSBRead(myInPipe,ReceiveData,ExpectedReceiveLength,ReceiveLength,ReceiveDelay)<>0) then
begin
if(ReceiveLength = ExpectedReceiveLength) then
begin
Result:=1; // OK
exit;
end
else
if(ReceiveLength < ExpectedReceiveLength) then
begin
Result:=2; // failed, incorrect receive length
exit;
end
end
else
CheckInvalidHandle()
else
CheckInvalidHandle()
end
else
begin
Result:=0; // Error
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var vers:dword;
begin
vers:=_MPUSBGetDLLVersion ;
myOutPipe:=INVALID_HANDLE_VALUE;
myInPipe:= INVALID_HANDLE_VALUE;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (myOutPipe <> INVALID_HANDLE_VALUE) then _MPUSBClose(myOutPipe);
if (myInPipe <> INVALID_HANDLE_VALUE) then _MPUSBClose(myInPipe);
myInPipe:= INVALID_HANDLE_VALUE;
myOutPipe:=INVALID_HANDLE_VALUE;
end;
procedure TForm1.Link_to_PCClick(Sender: TObject);
var
selection:DWORD;
send_buf:PBYTE;
receive_buf:PBYTE;
RecvLength:DWORD;
SentLength:DWORD;
Expected:DWORD;
i :integer;
label quit, finish;
begin
selection:=0; // USB device that have PID & VID as we configed.
RxTimer.Enabled:=false;
if (_MPUSBGetDeviceCount(vid_pid)=0) then
begin
Edit1.text:='Status : Device not connected';
Edit2.text:='Firmware version : unkhown';
exit;
end
else
begin
Edit1.text:='Status : Device connected';
Edit2.text:=vid_pid;
Flash_blue.Enabled:=false;
dsled1.ledon:=true;
end;
///////// open the pipes
myOutPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_WRITE,0);
myInPipe:= _MPUSBOpen(selection,vid_pid,in_pipe,MP_READ,0);
if ((myOutPipe = INVALID_HANDLE_VALUE) or (myInPipe = INVALID_HANDLE_VALUE)) then
begin
Edit1.text:='Status : USB Error';
exit;
end;
/// pipes are open
//// poll the PIC for a $25 acknowledge
send_buf[0]:=0; // link mode command
send_buf[1]:=0; // not validated
send_buf[2]:=0; // not validated
RecvLength:=1;
// if write or read are successfull they return a handle ( non zero)
if(_MPUSBWrite(myOutPipe,send_buf,3,SentLength,1000)=0) then goto quit;
if( _MPUSBRead(myInPipe,receive_buf,3,RecvLength,1000)=0) then goto quit;
// we have complete a handshake
if ((receive_buf[0] = $25 ) and (RecvLength = 3)) then
begin
Expected:=receive_buf[2]*256+receive_buf[1];
RS232_TX.Enabled:=true;
RS232_RX.Enabled:=true;
end;
RecvLength:=0; // read return actual length
/// PIC bulk transfer buffer size is 512
if( _MPUSBRead(myInPipe,receive_buf,512,RecvLength,1000)=0) then goto quit;
if not (RecvLength =Expected) then goto quit;
// we have received the PIC compile time enviroment
PICinfo.Caption:='PIC Firmware version : ';
for i:=0 to RecvLength-1 do PICinfo.Caption:=PICinfo.Caption+char(receive_buf[i]);
goto finish;
quit:
Edit1.Text:='Status : LNK Communication Error!';
finish:
_MPUSBClose(myOutPipe);
_MPUSBClose(myInPipe);
if rcv_in_progress then RxTimer.Enabled:=true;
myInPipe:= INVALID_HANDLE_VALUE;
myOutPipe:=INVALID_HANDLE_VALUE;
end;
procedure TForm1.DevicesClick(Sender: TObject);
begin
GetSummary;
end;
procedure TForm1.detachClick(Sender: TObject);
var
selection:DWORD;
send_buf:PBYTE;
receive_buf:PBYTE;
RecvLength:DWORD;
SentLength:DWORD;
ADC_value:integer;
label quit,finish;
begin
///////// open the pipes
selection:=0; // USB device that have PID & VID as we configed.
myOutPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_WRITE,0);
myInPipe:= _MPUSBOpen(selection,vid_pid,in_pipe,MP_READ,0);
if ((myOutPipe = INVALID_HANDLE_VALUE) or (myInPipe = INVALID_HANDLE_VALUE)) then
begin
Edit1.text:='Status : USB Error';
exit;
end;
/// pipes are open
//// poll the PIC for a $65 acknowledge
send_buf[0]:=3; // detach mode command
send_buf[1]:=0; // not validated
send_buf[2]:=0; // not validated
RecvLength:=1;
// if write or read are successfull they return a handle ( non zero)
if(_MPUSBWrite(myOutPipe,send_buf,3,SentLength,1000)=0) then goto quit;
Edit1.Text:='Status : Detached !';
Flash_blue.Enabled:=true;
goto finish;
quit:
Edit1.Text:='Status : Detach Communication Error!';
finish:
_MPUSBClose(myOutPipe);
_MPUSBClose(myInPipe);
myInPipe:= INVALID_HANDLE_VALUE;
myOutPipe:=INVALID_HANDLE_VALUE;
end;
procedure TForm1.Flash_blueTimer(Sender: TObject);
begin
dsled1.Oncolor:=ClNavy;
dsled1.OFFColor:=CLGray;
dsled1.Ledon:=not dsled1.ledon;
end;
procedure TForm1.ClearClick(Sender: TObject);
begin
Form1.Memo1.Lines.Clear ;
end;
procedure TForm1.RS232_TxClick(Sender: TObject);
var
selection:DWORD;
send_buf:PBYTE;
transmit_buf:PBYTE;
receive_buf:PBYTE;
RecvLength:DWORD;
SentLength:DWORD;
XmitLength:DWORD;
i :integer;
Expected:integer;
this_line:string;
label quit, finish;
begin
selection:=0; // USB device that have PID & VID as we configed.
///////// open the pipes
myOutPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_WRITE,0);
myInPipe:= _MPUSBOpen(selection,vid_pid,in_pipe,MP_READ,0);
if ((myOutPipe = INVALID_HANDLE_VALUE) or (myInPipe = INVALID_HANDLE_VALUE)) then
begin
Edit1.text:='Status : USB Error';
exit;
end;
this_line:=memo1.Lines.Strings[0];
Expected:=length(this_line);
for i:=0 to Expected-1 do transmit_buf[i]:=byte(this_line[i]);
send_buf[0]:=2; // Rs232 xmit mode command
send_buf[1]:=Expected div 256;
send_buf[2]:=Expected mod 256;
/// pipes are open
//// poll the PIC for a $65 acknowledge
RecvLength:=1;
// if write or read are successfull they return a handle ( non zero)
if(_MPUSBWrite(myOutPipe,send_buf,3,SentLength,1000)=0) then goto quit;
/// ecpected length is set to to 1
if( _MPUSBRead(myInPipe,receive_buf,1,RecvLength,1000)=0) then goto quit;
// we have complete a handshake
if ((receive_buf[0] = $65 ) and (RecvLength = 1)) then
begin
//// bulk transfer received buffer siz is 512
XmitLength:=expected;
if( _MPUSBWrite(myInPipe,transmit_buf,XmitLength,SentLength,1000)=0) then goto quit;
if not(SentLength =XmitLength) then goto quit;
end;
goto finish;
quit:
Edit1.Text:='Status : RS232TX Communication Error!';
finish:
_MPUSBClose(myOutPipe);
_MPUSBClose(myInPipe);
myInPipe:= INVALID_HANDLE_VALUE;
myOutPipe:=INVALID_HANDLE_VALUE;
end;
procedure TForm1.RXtimerTimer(Sender: TObject);
//// receive data from USB
var
selection:DWORD;
send_buf:PBYTE;
receive_buf:PBYTE;
RecvLength:DWORD;
SentLength:DWORD;
i :integer;
Expected:DWORD;
new_line:string;
label quit, finish;
begin
memo1.font.color:=ClGreen;
selection:=0; // USB device that have PID & VID as we configed.
///////// open the pipes
myOutPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_WRITE,0);
myInPipe:= _MPUSBOpen(selection,vid_pid,in_pipe,MP_READ,0);
if ((myOutPipe = INVALID_HANDLE_VALUE) or (myInPipe = INVALID_HANDLE_VALUE)) then
begin
Edit1.text:='Status : USB Error';
exit;
end;
/// pipes are open
//// poll the PIC for a $55 acknowledge
send_buf[0]:=1; // Rs232 recv mode command
send_buf[1]:=0; // not validated
send_buf[2]:=0; // not validated
RecvLength:=1;
// if write or read are successfull they return a handle ( non zero)
if(_MPUSBWrite(myOutPipe,send_buf,3,SentLength,1000)=0) then goto quit;
/// ecpected length is set to to 1
if( _MPUSBRead(myInPipe,receive_buf,3,RecvLength,1000)=0) then goto quit;
// we have complete a handshake
if ((receive_buf[0] = $55 ) and (RecvLength = 3)) then
begin
Expected:=receive_buf[2]*256+receive_buf[1];
if Expected=0 then goto finish; /// there is no data available yet
//// bulk transfer received buffer siz is 512
if( _MPUSBRead(myInPipe,receive_buf,512,RecvLength,1000)=0) then goto quit;
if not(RecvLength =Expected) then goto quit;
if (RecvLength > 0) then
begin
/// place data in memo box
new_line:='';
for i:=0 to RecvLength-1 do
begin
new_line:=new_line+char(receive_buf[i]);
end;
Memo1.lines.Text:=Memo1.lines.Text+new_line;
end;
end;
goto finish;
quit:
Edit1.Text:='Status : RS232RX Communication Error!';
finish:
_MPUSBClose(myOutPipe);
_MPUSBClose(myInPipe);
myInPipe:= INVALID_HANDLE_VALUE;
myOutPipe:=INVALID_HANDLE_VALUE;
end;
procedure TForm1.RS232RxClick(Sender: TObject);
begin
if RxTimer.enabled=false then
begin
RS232_Rx.Font.Color:=ClGreen;
rcv_in_progress:=true;
RxTimer.enabled:=true;
end
else
begin
RS232_Rx.Font.Color:=ClRed;
rcv_in_progress:=false;
RxTimer.enabled:=false;
end;
end;
end. |
Last edited by Douglas Kennedy on Thu Dec 30, 2010 8:24 am; edited 1 time in total |
|
|
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
|
Posted: Fri Nov 05, 2010 8:11 pm |
|
|
Hello man, I am from Brazil and I do not know I to speak in english very well.
I am working at this PicUSB project, but I am having some isues with the host part.
The problem is: The PC recognize the PIC, I installed the driver. But the host program did with the Visual C# can not control the PIC. It was working, but stoped and I do not know why!?
The PIC firmware is the same that J1M did, and I get this error when I try to debug the host program:
http://img443.imageshack.us/img443/1967/errofm.jpg
May you help me with this? I can not see any light at the end of the tunnel.
thanks
Matheus Lopes do Brasil |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|