pi1541/uspi/lib/uspilibrary.c

387 lines
9.0 KiB
C

//
// uspilibrary.c
//
// USPi - An USB driver for Raspberry Pi written in C
// Copyright (C) 2014-2018 R. Stange <rsta2@o2online.de>
//
// 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
//
#include <uspi/uspilibrary.h>
#include <uspi.h>
#include <uspios.h>
#include <uspi/usbdevice.h>
#include <uspi/string.h>
#include <uspi/util.h>
#include <uspi/assert.h>
static const char FromUSPi[] = "uspi";
static TUSPiLibrary *s_pLibrary = 0;
int USPiInitialize (void)
{
assert (s_pLibrary == 0);
s_pLibrary = (TUSPiLibrary *) malloc (sizeof (TUSPiLibrary));
assert (s_pLibrary != 0);
DeviceNameService (&s_pLibrary->NameService);
DWHCIDevice (&s_pLibrary->DWHCI);
s_pLibrary->pEth0 = 0;
s_pLibrary->pEth10 = 0;
if (!DWHCIDeviceInitialize (&s_pLibrary->DWHCI))
{
LogWrite (FromUSPi, LOG_ERROR, "Cannot initialize USB host controller interface");
_DWHCIDevice (&s_pLibrary->DWHCI);
_DeviceNameService (&s_pLibrary->NameService);
free (s_pLibrary);
s_pLibrary = 0;
return 0;
}
s_pLibrary->pUKBD1 = (TUSBKeyboardDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "ukbd1", FALSE);
s_pLibrary->pUMouse1 = (TUSBMouseDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "umouse1", FALSE);
s_pLibrary->pMIDI1 = (TUSBMIDIDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "umidi1", FALSE);
for (unsigned i = 0; i < MAX_DEVICES; i++)
{
TString DeviceName;
String (&DeviceName);
StringFormat (&DeviceName, "umsd%u", i+1);
s_pLibrary->pUMSD[i] = (TUSBBulkOnlyMassStorageDevice *)
DeviceNameServiceGetDevice (DeviceNameServiceGet (), StringGet (&DeviceName), TRUE);
_String (&DeviceName);
}
s_pLibrary->pEth0 = (TSMSC951xDevice *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "eth0", FALSE);
s_pLibrary->pEth10 = (TLAN7800Device *) DeviceNameServiceGetDevice (DeviceNameServiceGet (), "eth10", FALSE);
for (unsigned i = 0; i < MAX_DEVICES; i++)
{
TString DeviceName;
String (&DeviceName);
StringFormat (&DeviceName, "upad%u", i+1);
s_pLibrary->pUPAD[i] = (TUSBGamePadDevice *)
DeviceNameServiceGetDevice (DeviceNameServiceGet (), StringGet (&DeviceName), FALSE);
_String (&DeviceName);
}
LogWrite (FromUSPi, LOG_DEBUG, "USPi library successfully initialized");
return 1;
}
int USPiKeyboardAvailable (void)
{
assert (s_pLibrary != 0);
return s_pLibrary->pUKBD1 != 0;
}
void USPiKeyboardRegisterKeyPressedHandler (TUSPiKeyPressedHandler *pKeyPressedHandler)
{
assert (s_pLibrary != 0);
assert (s_pLibrary->pUKBD1 != 0);
USBKeyboardDeviceRegisterKeyPressedHandler (s_pLibrary->pUKBD1, pKeyPressedHandler);
}
void USPiKeyboardRegisterShutdownHandler (TUSPiShutdownHandler *pShutdownHandler)
{
assert (s_pLibrary != 0);
assert (s_pLibrary->pUKBD1 != 0);
USBKeyboardDeviceRegisterShutdownHandler (s_pLibrary->pUKBD1, pShutdownHandler);
}
void USPiKeyboardRegisterKeyStatusHandlerRaw (TKeyStatusHandlerRaw *pKeyStatusHandlerRaw)
{
assert (s_pLibrary != 0);
assert (s_pLibrary->pUKBD1 != 0);
USBKeyboardDeviceRegisterKeyStatusHandlerRaw (s_pLibrary->pUKBD1, pKeyStatusHandlerRaw);
}
int USPiMouseAvailable (void)
{
assert (s_pLibrary != 0);
return s_pLibrary->pUMouse1 != 0;
}
void USPiMouseRegisterStatusHandler (TUSPiMouseStatusHandler *pStatusHandler)
{
assert (s_pLibrary != 0);
assert (s_pLibrary->pUMouse1 != 0);
USBMouseDeviceRegisterStatusHandler (s_pLibrary->pUMouse1, pStatusHandler);
}
int USPiMassStorageDeviceAvailable (void)
{
assert (s_pLibrary != 0);
unsigned i;
for (i = 0; i < MAX_DEVICES; i++)
{
if (s_pLibrary->pUMSD[i] == 0)
{
break;
}
}
return (int) i;
}
int USPiMassStorageDeviceRead (unsigned long long ullOffset, void *pBuffer, unsigned nCount, unsigned nDeviceIndex)
{
assert (s_pLibrary != 0);
if ( nDeviceIndex >= MAX_DEVICES
|| s_pLibrary->pUMSD[nDeviceIndex] == 0)
{
return -1;
}
if (USBBulkOnlyMassStorageDeviceSeek (s_pLibrary->pUMSD[nDeviceIndex], ullOffset) != ullOffset)
{
return -1;
}
return USBBulkOnlyMassStorageDeviceRead (s_pLibrary->pUMSD[nDeviceIndex], pBuffer, nCount);
}
int USPiMassStorageDeviceWrite (unsigned long long ullOffset, const void *pBuffer, unsigned nCount, unsigned nDeviceIndex)
{
assert (s_pLibrary != 0);
if ( nDeviceIndex >= MAX_DEVICES
|| s_pLibrary->pUMSD[nDeviceIndex] == 0)
{
return -1;
}
if (USBBulkOnlyMassStorageDeviceSeek (s_pLibrary->pUMSD[nDeviceIndex], ullOffset) != ullOffset)
{
return -1;
}
return USBBulkOnlyMassStorageDeviceWrite (s_pLibrary->pUMSD[nDeviceIndex], pBuffer, nCount);
}
unsigned USPiMassStorageDeviceGetCapacity (unsigned nDeviceIndex)
{
assert (s_pLibrary != 0);
if ( nDeviceIndex >= MAX_DEVICES
|| s_pLibrary->pUMSD[nDeviceIndex] == 0)
{
return 0;
}
return USBBulkOnlyMassStorageDeviceGetCapacity (s_pLibrary->pUMSD[nDeviceIndex]);
}
int USPiEthernetAvailable (void)
{
assert (s_pLibrary != 0);
return s_pLibrary->pEth0 != 0 || s_pLibrary->pEth10 != 0;
}
void USPiGetMACAddress (unsigned char Buffer[6])
{
assert (s_pLibrary != 0);
TMACAddress *pMACAddress;
if (s_pLibrary->pEth10 != 0)
{
pMACAddress = LAN7800DeviceGetMACAddress (s_pLibrary->pEth10);
}
else
{
assert (s_pLibrary->pEth0 != 0);
pMACAddress = SMSC951xDeviceGetMACAddress (s_pLibrary->pEth0);
}
assert (Buffer != 0);
MACAddressCopyTo (pMACAddress, Buffer);
}
int USPiSendFrame (const void *pBuffer, unsigned nLength)
{
assert (s_pLibrary != 0);
if (s_pLibrary->pEth10 != 0)
{
return LAN7800DeviceSendFrame (s_pLibrary->pEth10, pBuffer, nLength) ? 1 : 0;
}
assert (s_pLibrary->pEth0 != 0);
return SMSC951xDeviceSendFrame (s_pLibrary->pEth0, pBuffer, nLength) ? 1 : 0;
}
int USPiReceiveFrame (void *pBuffer, unsigned *pResultLength)
{
assert (s_pLibrary != 0);
if (s_pLibrary->pEth10 != 0)
{
return LAN7800DeviceReceiveFrame (s_pLibrary->pEth10, pBuffer, pResultLength) ? 1 : 0;
}
assert (s_pLibrary->pEth0 != 0);
return SMSC951xDeviceReceiveFrame (s_pLibrary->pEth0, pBuffer, pResultLength) ? 1 : 0;
}
int USPiGamePadAvailable (void)
{
assert (s_pLibrary != 0);
unsigned i;
for (i = 0; i < MAX_DEVICES; i++)
{
if (s_pLibrary->pUPAD[i] == 0)
{
break;
}
}
return (int) i;
}
void USPiGamePadRegisterStatusHandler (TGamePadStatusHandler *pStatusHandler)
{
assert (s_pLibrary != 0);
unsigned i;
for (i = 0; i < MAX_DEVICES; i++)
{
if (s_pLibrary->pUPAD[i] != 0)
{
USBGamePadDeviceRegisterStatusHandler (s_pLibrary->pUPAD[i], pStatusHandler);
}
}
}
const USPiGamePadState *USPiGamePadGetStatus (unsigned nDeviceIndex)
{
assert (s_pLibrary != 0);
if ( nDeviceIndex >= MAX_DEVICES
|| s_pLibrary->pUPAD[nDeviceIndex] == 0)
{
return 0;
}
USBGamePadDeviceGetReport (s_pLibrary->pUPAD[nDeviceIndex]);
return &s_pLibrary->pUPAD[nDeviceIndex]->m_State;
}
int USPiMIDIAvailable (void)
{
assert (s_pLibrary != 0);
return s_pLibrary->pMIDI1 != 0;
}
void USPiMIDIRegisterPacketHandler (TUSPiMIDIPacketHandler *pPacketHandler)
{
assert (s_pLibrary != 0);
assert (s_pLibrary->pMIDI1 != 0);
USBMIDIDeviceRegisterPacketHandler (s_pLibrary->pMIDI1, pPacketHandler);
}
int USPiDeviceGetInformation (unsigned nClass, unsigned nDeviceIndex, TUSPiDeviceInformation *pInfo)
{
assert (s_pLibrary != 0);
TUSBDevice *pUSBDevice = 0;
switch (nClass)
{
case KEYBOARD_CLASS:
if (nDeviceIndex == 0)
{
pUSBDevice = (TUSBDevice *) s_pLibrary->pUKBD1;
}
break;
case MOUSE_CLASS:
if (nDeviceIndex == 0)
{
pUSBDevice = (TUSBDevice *) s_pLibrary->pUMouse1;
}
break;
case STORAGE_CLASS:
if (nDeviceIndex < MAX_DEVICES)
{
pUSBDevice = (TUSBDevice *) s_pLibrary->pUMSD[nDeviceIndex];
}
break;
case ETHERNET_CLASS:
if (nDeviceIndex == 0)
{
if (s_pLibrary->pEth10 != 0)
{
pUSBDevice = (TUSBDevice *) s_pLibrary->pEth10;
}
else
{
pUSBDevice = (TUSBDevice *) s_pLibrary->pEth0;
}
}
break;
case GAMEPAD_CLASS:
if (nDeviceIndex < MAX_DEVICES)
{
pUSBDevice = (TUSBDevice *) s_pLibrary->pUPAD[nDeviceIndex];
}
break;
case MIDI_CLASS:
if (nDeviceIndex == 0)
{
pUSBDevice = (TUSBDevice *) s_pLibrary->pMIDI1;
}
break;
default:
break;
}
if (pUSBDevice == 0)
{
return 0;
}
const TUSBDeviceDescriptor *pDesc = USBDeviceGetDeviceDescriptor (pUSBDevice);
assert (pDesc != 0);
assert (pInfo != 0);
pInfo->idVendor = pDesc->idVendor;
pInfo->idProduct = pDesc->idProduct;
pInfo->bcdDevice = pDesc->bcdDevice;
pInfo->pManufacturer = USBStringGet (&pUSBDevice->m_ManufacturerString);
pInfo->pProduct = USBStringGet (&pUSBDevice->m_ProductString);
return 1;
}