tml_hid.c 4.43 KB
Newer Older
Gus Grubba's avatar
Gus Grubba committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
/*
*         Copyright (c), NXP Semiconductors Caen / France
*
*                     (C)NXP Semiconductors
*       All rights are reserved. Reproduction in whole or in part is
*      prohibited without the written consent of the copyright owner.
*  NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
*                          arising from its use.
*/

#include <TML/inc/tool.h>
#include <TML/inc/tml.h>
#include "TML/inc/lpcusbsio.h"
#include "TML/inc/lpcusbsio_i2c.h"
#include "TML/inc/framework_Interface.h"
#include "TML/inc/framework_Timer.h"

#define I2C_ADD 0x28

static I2C_PORTCONFIG_T  lCfgParam;
static LPC_HANDLE mDriverHandle = NULL;
static bool isAborted;

static uint8_t tml_Tx(uint8_t *pBuff, uint16_t buffLen) {
    int lRes = 0x00;
    int j=0;

    do {
       lRes = I2C_DeviceWrite(mDriverHandle, I2C_ADD, pBuff+j, (buffLen-j>=MAX_WRITE_LENGTH)?MAX_WRITE_LENGTH:buffLen-j,
           I2C_TRANSFER_OPTIONS_START_BIT | I2C_TRANSFER_OPTIONS_STOP_BIT);
       if(lRes < 0) return 0;
       j += MAX_WRITE_LENGTH;
    } while (j <= buffLen);

    return 1;
}

static void tml_Rx(uint8_t *pBuff, uint16_t buffLen, uint16_t *pBytesRead) {
    int lRes = 0x00;
    lRes = I2C_DeviceRead( mDriverHandle, I2C_ADD, pBuff, 3, I2C_TRANSFER_OPTIONS_START_BIT | I2C_TRANSFER_OPTIONS_STOP_BIT | I2C_TRANSFER_OPTIONS_NACK_LAST_BYTE);
    if (lRes > 0) *pBytesRead = pBuff[2] + 3;
    else *pBytesRead = 0;
}

static bool tml_Init(void) {
    int lRes = 0x00;

    if(NULL != mDriverHandle) return true;

    lRes = I2C_GetNumPorts();
    if (lRes < 0) return false;

    mDriverHandle = I2C_Open(0); 
    if(NULL == mDriverHandle) return false;

    memset(&lCfgParam, 0x00, sizeof(I2C_PORTCONFIG_T));
    lCfgParam.ClockRate = I2C_CLOCK_FAST_MODE;
    lRes = I2C_Init(mDriverHandle, &lCfgParam);
    if (lRes < 0){
        I2C_Close(mDriverHandle);
        mDriverHandle = NULL;
        return false;
    }
    return true;
}

static void tml_Reset(void) {
    uint8_t buffer[30];
    uint16_t nbBytes;

    if (mDriverHandle == NULL) return;

    I2C_Reset(mDriverHandle);

    GPIO_SetVENValue(mDriverHandle, 0x00);
    GPIO_SetDWLValue(mDriverHandle, 0x00);
    Sleep(10);    
    GPIO_SetVENValue(mDriverHandle, 0x01);

    /* Insure I2C fragmentation is enabled */
    tml_Tx((uint8_t*)"\x20\x00\x01\x01", 4);
    tml_Tx((uint8_t*)"\x20\x00\x01\x01", 4);
    tml_Rx(buffer, sizeof(buffer), &nbBytes);
    tml_Tx((uint8_t*)"\x20\x01\x00", 3);
    tml_Rx(buffer, sizeof(buffer), &nbBytes);
    tml_Tx((uint8_t*)"\x20\x02\x05\x01\xA0\x05\x01\x10", 8);
    tml_Rx(buffer, sizeof(buffer), &nbBytes);

    GPIO_SetVENValue(mDriverHandle, 0x00);
    Sleep(10);    
    GPIO_SetVENValue(mDriverHandle, 0x01);
}

int tml_hid_Connect(void) {
    if(!tml_Init()) return 1;
    tml_Reset();
    return 0;
}

void tml_hid_Disconnect(void){
    /*    I2C_Reset(mDriverHandle);
    I2C_CancelAllRequest(mDriverHandle);
    I2C_Close(mDriverHandle);
    Sleep(2000);*/
}

void tml_hid_Send(uint8_t *pBuffer, uint16_t BufferLen, uint16_t *pBytesSent){
    if(tml_Tx(pBuffer, BufferLen) == 0)
    {
        *pBytesSent = 0;
    }
    else
    {
        *pBytesSent = BufferLen;
    }
}

static void timeoutCb(void* pContext)
{
    uint8_t dummy[] = {0x20, 0x00, 0x00};
    I2C_CancelAllRequest(mDriverHandle);
    /* Send dummy frame to re-align reception */
    tml_Tx(dummy, sizeof(dummy));
    isAborted = true;
}

void tml_hid_Receive(uint8_t *pBuffer, uint16_t BufferLen, uint16_t *pBytes, uint16_t timeout){
    if (timeout == TIMEOUT_INFINITE) tml_Rx(pBuffer, BufferLen, pBytes);
    else {
        void *timer;
        uint32_t timerId;
        framework_TimerCreate(&timer);
        timerId = *(uint32_t*)timer;
        *pBytes = 0;
        isAborted = false;
        framework_TimerStart(&timerId, timeout, timeoutCb, NULL);
        tml_Rx(pBuffer, BufferLen, pBytes);
        if(isAborted) *pBytes = 0;
        framework_TimerStop(&timerId);
        framework_TimerDelete(&timerId);
    }
}

void tml_hid_Cancel(void)
{
    I2C_CancelAllRequest(mDriverHandle);
}