Greetings
I hope this is the proper place to post this since it covers two topics (TI-84 plus ce and C) at once.
I am working on a Windows application program written in C of which one of it's features is accessing the TI-84 Plus ce via the USB cable. Rummaging around this site I was not able to find any posts that cover this particular subject. What posts I found seem to deal with using assembly, so I have had to figure this out on my own.
In this post I would like to present a function that will detect if the TI-84 Plus ce or a SilverLink cable is plugged into any USB port on a Windows computer. I included the SilverLink cable because I just bought my 84 Plus and I still have a TI-83+ with the SilverLink cable so it was easy to add.
The function below will return an integer flag. A zero (0) means neither the SilverLink nor a TI-84 Plus ce was found connected to the USB. A one (1) is returned if the SilverLink cable was found. The SilverLink will be detected even if no calculator is connected to it. (Figuring out if a calculator is attached to the SilverLink will be saved for another day). A two (2) is returned only if a TI-84 plus ce is attached to its USB cable and the calculator is awake. If the TI-84 plus ce is not connected or if the calculator is connected but is 'asleep' it will not be detected and the function will return a zero as not found. Finally, a three (3) will be returned if both a SilverLink and a TI-84 Plus ce are found to be connected to the USB ports.
Again, I would like to point out that this function is specify to a Windows frame based or dialog based application program. (Sorry Mac and others).
I am assuming that if you are going to use this function you are a competent Windows application programmer. To use this function you need to include both the header files dbt.h and setupapi.h. And when you compile your program you will need to link to the setupapi library.
In your main Window application Callback function you need to include a couple of things. First, when your program first starts up it will receive a WM_CREATE message from Windows. Here you should include a call to my function to tell you if the user has already plugged either a ti-84plus ce or silverlink cable into the USB port before they started up your application.
If the user plugs in or unplugs any USB device after your application program is running your program will receive a WM_DEVICECHANGE message along with the submessage DBT_DEVNODS_CHANGED. When you receive these messages you should again call the function to find out if the change was caused by someone plugging or unplugging a calculator from the USB. Here is a snippet:
Code:
I would very much be interested in anyone who knows more about this subject adding your comments to this post or correcting my errors.
Here is the function that will check to find out if a TI-84 Plus CE or a SilverLink cable is plugged into the USB port on your computer. Please feel free to use it.
Code:
Vendor ID and Product ID:
-------------------------------------
All USB objects are assigned a unique ID. This ID consists of it's Vendor ID (VID) and it's Product ID (PID). Texas Instrument's vendor ID is 0451 and the TI-84 Plus CE product ID is E008. The TI SilverLink cable product ID is E001. I don't know what E002 through E007 are.
It is really easy to find out the VID and PID of any USB device. Simply plug it into your computer then select 'Devices and Printers'. You will find in 'Unspecified' your TI-84 Plus CE listed. For the SilverLink cable it is listed as TI-GRAPHLINK USB. Right click on the icon and select 'Properties'. Now select the 'Hardware' tab and click the 'Properties' button. Next, at long last, click on the 'Details' tab. From the pull down menu select 'Hardware ids'. Here you will find the VID and PID for the calculator: "USB\VID_0451&PID_E008" and a similiar one with the revision number, but we don't need that. For the SilverLink you will find "USB\VID_0451&PID_E001.
The first thing you do to access your calculator is tell Windows what object on the computer bus you want to access. We want to access the USB ports so in a C program we call the function: hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
This function gets a handle for "USB" devices. If you wanted this information for PCI devices instead you would set this to TEXT("PCI"). The DIGCF_PRESENT flag tells it to only get devices that are plugged in and 'active'. Therefore, if your calculator is plugged in but it is asleep, you will not be able to find it. Using the handle from this function you next loop through each USB device by setting the index to 0, and then incrementing index each time you call this function: SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData));
This function fills in the DeviceInfoData structure. You will loop through this function until you receive an ERROR_NO_MORE_ITEMS error message. This message means you have checked all the active USB ports (active because that is what we told the first function we were looking for) Using the InfoData structure the next function is able to get the VID & PID which we then check using the strstr() function.
I really hope that this helps some with there own programming. I'll post more about sending data from the computer to the calculator using C when I get that all worked out (I pretty much got it worked out, I just need to work out a few problems and do some testing).
See ya,
S. Thomas Bradley
I hope this is the proper place to post this since it covers two topics (TI-84 plus ce and C) at once.
I am working on a Windows application program written in C of which one of it's features is accessing the TI-84 Plus ce via the USB cable. Rummaging around this site I was not able to find any posts that cover this particular subject. What posts I found seem to deal with using assembly, so I have had to figure this out on my own.
In this post I would like to present a function that will detect if the TI-84 Plus ce or a SilverLink cable is plugged into any USB port on a Windows computer. I included the SilverLink cable because I just bought my 84 Plus and I still have a TI-83+ with the SilverLink cable so it was easy to add.
The function below will return an integer flag. A zero (0) means neither the SilverLink nor a TI-84 Plus ce was found connected to the USB. A one (1) is returned if the SilverLink cable was found. The SilverLink will be detected even if no calculator is connected to it. (Figuring out if a calculator is attached to the SilverLink will be saved for another day). A two (2) is returned only if a TI-84 plus ce is attached to its USB cable and the calculator is awake. If the TI-84 plus ce is not connected or if the calculator is connected but is 'asleep' it will not be detected and the function will return a zero as not found. Finally, a three (3) will be returned if both a SilverLink and a TI-84 Plus ce are found to be connected to the USB ports.
Again, I would like to point out that this function is specify to a Windows frame based or dialog based application program. (Sorry Mac and others).
I am assuming that if you are going to use this function you are a competent Windows application programmer. To use this function you need to include both the header files dbt.h and setupapi.h. And when you compile your program you will need to link to the setupapi library.
In your main Window application Callback function you need to include a couple of things. First, when your program first starts up it will receive a WM_CREATE message from Windows. Here you should include a call to my function to tell you if the user has already plugged either a ti-84plus ce or silverlink cable into the USB port before they started up your application.
If the user plugs in or unplugs any USB device after your application program is running your program will receive a WM_DEVICECHANGE message along with the submessage DBT_DEVNODS_CHANGED. When you receive these messages you should again call the function to find out if the change was caused by someone plugging or unplugging a calculator from the USB. Here is a snippet:
Code:
switch(Message) //Which WM_ message?
{
case WM_CREATE:
status = ti_GetTIUSBStatus();
if(status >1)
EnableFlag = TRUE; // ti-84plus ce was found
else
EnableFlag = FALSE; //no ti-84plus ce found
break;
case WM_DEVICECHANGE:
switch (wParam)
{
case DBT_DEVNODES_CHANGED:
status = ti_GetTIUSBStatus();
if(status >1)
EnableFlag = TRUE; //being activated
else
EnableFlag = FALSE; //being de-activated
break;
}
}
I would very much be interested in anyone who knows more about this subject adding your comments to this post or correcting my errors.
Here is the function that will check to find out if a TI-84 Plus CE or a SilverLink cable is plugged into the USB port on your computer. Please feel free to use it.
Code:
/////////////////////////////////////////////////
/// @brief Detects if a TI-84 Plus CE or a SilverLink cable is present in USB port.
///
/// @param None
/// @return 0 = no TI device found, 1 = TI SilverLink cable found,
/// 2 = TI-84 Plus CE found, 3 = both SilverLink & TI-84 Plus found.
///
/////////////////////////////////////////////////
int GetTIUSBStatus()
{
unsigned index, status = 0;
char str[40];
DWORD error;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
TCHAR HardwareID[1024];
// We want to access the USB port on the bus:
hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL,
DIGCF_PRESENT | DIGCF_ALLCLASSES);
// Loop through each USB device and check the VID and PID until NO MORE ITEMS:
for (index = 0; ; index++)
{
// Get each instance of USB device
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData))
{
error = GetLastError();
if(ERROR_NO_MORE_ITEMS == error)
return status; // All done, finished checking all active USB objects
}
// If not done get the Hardware ID (i.e. VID&PID)
SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData,
SPDRP_HARDWAREID, NULL,
(BYTE*)HardwareID,
sizeof(HardwareID),
NULL);
if (strstr(HardwareID, "VID_0451"))
{
if(strstr(HardwareID, "PID_E001"))
status = status + 1;
if (strstr(HardwareID, "PID_E008"))
status = status + 2;
}
}
return status;
}
Vendor ID and Product ID:
-------------------------------------
All USB objects are assigned a unique ID. This ID consists of it's Vendor ID (VID) and it's Product ID (PID). Texas Instrument's vendor ID is 0451 and the TI-84 Plus CE product ID is E008. The TI SilverLink cable product ID is E001. I don't know what E002 through E007 are.
It is really easy to find out the VID and PID of any USB device. Simply plug it into your computer then select 'Devices and Printers'. You will find in 'Unspecified' your TI-84 Plus CE listed. For the SilverLink cable it is listed as TI-GRAPHLINK USB. Right click on the icon and select 'Properties'. Now select the 'Hardware' tab and click the 'Properties' button. Next, at long last, click on the 'Details' tab. From the pull down menu select 'Hardware ids'. Here you will find the VID and PID for the calculator: "USB\VID_0451&PID_E008" and a similiar one with the revision number, but we don't need that. For the SilverLink you will find "USB\VID_0451&PID_E001.
The first thing you do to access your calculator is tell Windows what object on the computer bus you want to access. We want to access the USB ports so in a C program we call the function: hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
This function gets a handle for "USB" devices. If you wanted this information for PCI devices instead you would set this to TEXT("PCI"). The DIGCF_PRESENT flag tells it to only get devices that are plugged in and 'active'. Therefore, if your calculator is plugged in but it is asleep, you will not be able to find it. Using the handle from this function you next loop through each USB device by setting the index to 0, and then incrementing index each time you call this function: SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData));
This function fills in the DeviceInfoData structure. You will loop through this function until you receive an ERROR_NO_MORE_ITEMS error message. This message means you have checked all the active USB ports (active because that is what we told the first function we were looking for) Using the InfoData structure the next function is able to get the VID & PID which we then check using the strstr() function.
I really hope that this helps some with there own programming. I'll post more about sending data from the computer to the calculator using C when I get that all worked out (I pretty much got it worked out, I just need to work out a few problems and do some testing).
See ya,
S. Thomas Bradley