Example #1
0
// transfer a byte for the monitor download, with or without acknowledge
int DownloadByte(tUartHandle serial_handle, unsigned char byte, bool bAck)
{
	unsigned char received;

	while (1)
	{
		UartWrite(serial_handle, &byte, 1);
		if (bAck)
		{
			UartRead(serial_handle, &received, 1);
			if (received == byte)
			{
				UartWrite(serial_handle, (UINT8*)"\x01", 1); // ack success
				break; // exit the loop
			}
			else
			{
				printf("Error transmitting monitor byte 0x%02X, got 0x%0X\n", byte, received);
				UartWrite(serial_handle, (UINT8*)"\x00", 1); // ack fail, try again
			}
		}
		else
			break; // no loop
	}
	return 1;
}
Example #2
0
// change baudrate using target monitor
int SetTargetBaudrate(tUartHandle serial_handle, long lClock, long lBaudrate)
{
	UINT8 send;
	UINT8 received;
	UINT8 brr;
	long lBRR;

	lBRR = lClock / lBaudrate;
	lBRR = ((lBRR + 16) / 32) - 1; // with rounding
	brr = (UINT8)lBRR;

	// send the command
	send = BAUDRATE;
	UartWrite(serial_handle, &send, 1);
	UartWrite(serial_handle, &brr, 1); // send the BRR value
	UartRead(serial_handle, &received, 1); // response ack

	if (received != BAUDRATE)
	{	// bad situation, now we're unclear about the baudrate of the target
		printf("Protocol error!\n");
		return 1;
	}

	SLEEP(100); // give it some time to settle

	// change our baudrate, too
	UartConfig(serial_handle, lBaudrate, eNOPARITY, eONESTOPBIT, 8); 

	return 0;
}
Example #3
0
// write many bytes using the target monitor
int FlashByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer)
{
	UINT8 send, received;

	// send the address command
	send = ADDRESS;
	UartWrite(serial_handle, &send, 1);

	// transmit the address, big endian
	send = (UINT8)((addr>>24) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>16) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>8) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)(addr & 0xFF);
	UartWrite(serial_handle, &send, 1);

	UartRead(serial_handle, &received, 1); // response
	if (received != ADDRESS)
	{
		printf("Protocol error!\n");
		return 1;
	}

	while (size)
	{
		if (size >= 16)
		{	// we can use a "burst" command
			send = BYTE_FLASH16;
			UartWrite(serial_handle, &send, 1); // send the write command
			UartWrite(serial_handle, pBuffer, 16); // transmit the data
			UartRead(serial_handle, &received, 1); // response
			if (received != BYTE_FLASH16)
			{
				printf("Protocol error!\n");
				return 1;
			}
			pBuffer += 16;
			size -= 16;
		}
		else
		{	// use single byte command
			send = BYTE_FLASH;
			UartWrite(serial_handle, &send, 1); // send the write command
			UartWrite(serial_handle, pBuffer++, 1); // transmit the data
			UartRead(serial_handle, &received, 1); // response
			if (received != BYTE_FLASH)
			{
				printf("Protocol error!\n");
				return 1;
			}
			size--;
		}
	}

	return 0;
}
Example #4
0
// do the baudrate configuration for the Player
int ConfigFirstlevelPlayer (tUartHandle serial_handle)
{
	UINT32 result_nbr;

	if(!UartConfig(serial_handle, 4800, eMARKPARITY, eTWOSTOPBITS, 8))
	{
		UINT32 dwErr = GET_LAST_ERR();
		printf("Error %lu setting up COM params for baudrate byte\n", dwErr);
		exit(1);
	}

	// this will read as 0x19 when viewed with 2300 baud like the player does
	result_nbr = UartWrite(serial_handle, (UINT8*)"\x86\xC0", 2);
	if (result_nbr != 2)
	{
		UINT32 dwErr = GET_LAST_ERR();
		printf("Error %lu setting up COM params for baudrate byte\n", dwErr);
	}

	SLEEP(100); // wait for the chars to be sent, is there a better way?

	// the read 0x19 means 14423 baud with 12 MHz
	if(!UartConfig(serial_handle, 14400, eNOPARITY, eONESTOPBIT, 8))
	{
		printf("Error setting up COM params for 1st level loader\n");
		exit(1);
	}

	return 0;
}
/*----------------------------------------------------------------------------*
 *  NAME
 *      SendDataToUart
 *
 *  DESCRIPTION
 *      Sends the received data over UART.
 *
 *  RETURNS
 *      Nothing
 *
 *----------------------------------------------------------------------------*/
extern void SendDataToUart(uint8 *data, uint16 size)
{
     /* We initially attempt to directly write to the UART and from there on
     * we send the data using callback mechanism, whenever the UART is ready
     * to accept more incoming data. This is to avoid data loss. The data is
     * buffered and sent to UART using callback mechanism.
     */
    if(!g_trigger_write_callback)
    {
        UartWrite(data, size);
        g_trigger_write_callback = TRUE;
        return;
    }

    /* Queue the incoming data to the queue. will be written when UART is ready
     */  
    if(g_trigger_write_callback)
    {
        /* First copy all the bytes received into the byte queue */
        BQSafeQueueBytes((const uint8 *)data, size,RECV_QUEUE_ID);

        /*Send Pending Data */
        sendPendingData();
    }
}
Example #6
0
// do the baudrate configuration for the Recoder/FM
int ConfigFirstlevelRecorder (tUartHandle serial_handle)
{
	UINT32 result_nbr;

	if(!UartConfig(serial_handle, 4800, eNOPARITY, eTWOSTOPBITS, 8))
	{
		UINT32 dwErr = GET_LAST_ERR();
		printf("Error %lu setting up COM params for baudrate byte\n", dwErr);
		exit(1);
	}

	// this will read as 0x08 when viewed with 2120 baud like the recorder does
	result_nbr = UartWrite(serial_handle, (UINT8*)"\x00\x00", 2);
	if(result_nbr != 2)
	{
		printf("Error transmitting baudrate byte\n");
		exit(1);
	}

	SLEEP(100); // wait for the chars to be sent, is there a better way?

	// the read 0x08 means 38400 baud with 11.0592 MHz
	if(!UartConfig(serial_handle, 38400, eNOPARITY, eONESTOPBIT, 8))
	{
		UINT32 dwErr = GET_LAST_ERR();
		printf("Error %lu setting up COM params for 1st level loader\n", dwErr);
		exit(1);
	}

	return 0;
}
/*----------------------------------------------------------------------------*
 *  NAME
 *      sendPendingData
 *
 *  DESCRIPTION
 *      Send buffered data over UART that was waiting to be sent. Perform some
 *      translation to ensured characters are properly displayed.
 *
 * PARAMETERS
 *      None
 *
 * RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
static void sendPendingData(void)
{
    /* Loop until the byte queue is empty */
        uint8  data[SERIAL_RX_DATA_LENGTH]; /* Data to be sent */
        uint16 size_val; /* Length of the data to be sent */

        /* Length of data available in the queue */
        uint16 length = BQGetDataSize(RECV_QUEUE_ID);

        /* Proceed only if byte queue is not empty */
        while (BQGetDataSize(RECV_QUEUE_ID) > 0)
        {
            /* Make sure that the maximum data length is not exceeded */
            size_val = length > SERIAL_RX_DATA_LENGTH ?
                       SERIAL_RX_DATA_LENGTH : length;

            if (BQPeekBytes(data, size_val,RECV_QUEUE_ID) > 0)
            {
                /* Check whether we are able to write */
                bool ok_to_commit = UartWrite( data,size_val );

                if(!ok_to_commit)
                {
                    /* exit on failure */
                    break;
                }
                else /* Pop the data out */
                    BQPopBytes(data, size_val,RECV_QUEUE_ID);
            }
        }
}
Example #8
0
/*
**	向串口读写数据.
**	@buf:		发送与接收数据缓冲区
**	@bufSize:	缓冲区长度
*/
U8 logic_sendAndRead(U8* buf, U16* bufSize, U32 timeout)
{
	UartWrite(buf, *bufSize, timeout, gpu);
	*bufSize = UartRead(buf, 100, timeout, gpu);
	if (*bufSize == 0) {//如果超时后没有读到数据, 返回错误
		return ERROR;
	}
	return NO_ERR;
}
Example #9
0
// read a byte using the target monitor
UINT8 ReadByte(tUartHandle serial_handle, UINT32 addr)
{
	UINT8 send;
	UINT8 received;

	// send the address command
	send = ADDRESS;
	UartWrite(serial_handle, &send, 1);

	// transmit the address, big endian
	send = (UINT8)((addr>>24) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>16) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>8) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)(addr & 0xFF);
	UartWrite(serial_handle, &send, 1);

	UartRead(serial_handle, &received, 1); // response
	if (received != ADDRESS)
	{
		printf("Protocol error!\n");
		return 1;
	}

	// send the read command
	send = BYTE_READ;
	UartWrite(serial_handle, &send, 1);

	UartRead(serial_handle, &received, 1); // response

	return received;
}
Example #10
0
// write a 16bit halfword using the target monitor
int WriteHalfword(tUartHandle serial_handle, UINT32 addr, UINT16 halfword)
{
	UINT8 send;
	UINT8 received;

	// send the address command
	send = ADDRESS;
	UartWrite(serial_handle, &send, 1);

	// transmit the address, big endian
	send = (UINT8)((addr>>24) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>16) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>8) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)(addr & 0xFF);
	UartWrite(serial_handle, &send, 1);

	UartRead(serial_handle, &received, 1); // response
	if (received != ADDRESS)
	{
		printf("Protocol error!\n");
		return 1;
	}

	// send the write command
	send = HALFWORD_WRITE;
	UartWrite(serial_handle, &send, 1);

	// transmit the data
	send = halfword >> 8; // highbyte
	UartWrite(serial_handle, &send, 1);
	send = halfword & 0xFF; // lowbyte
	UartWrite(serial_handle, &send, 1);
	
	UartRead(serial_handle, &received, 1); // response

	if (received != HALFWORD_WRITE)
	{
		printf("Protocol error!\n");
		return 1;
	}

	return 0;
}
Example #11
0
// send a sting and check the echo
int SendWithEcho(tUartHandle serial_handle, char* pszSend)
{
	int i = 0;
	unsigned char received;
	
	while(pszSend[i] != '\0')
	{
		UartWrite(serial_handle, (unsigned char*)(pszSend + i), 1); // send char
		do
		{
			UartRead(serial_handle, &received, 1); // receive echo
			printf("%c", received); // debug
		}
		while (received != pszSend[i]); // should normally be equal
		i++; // next char
	}
	return 0;
}
Example #12
0
/* Echo back recevied data in upper case */
int 
UartTest1(
    IN const char *pszPort
    )
{
    int Retval;
    uhandle_t hUart;
    char Buff[256];
    unsigned int BytesRead;
    unsigned int BytesWritten;

    DBG_MSG(DBG_TRACE, "%s\n", __FUNCTION__);

    Retval = UartCtor(&hUart);
    CHECK_RETVAL(Retval, ExitOnFailure);

    Retval = UartOpen(hUart, 
                      pszPort,
                      UART_RATE_57600, 
                      UART_DATA_BITS_8, 
                      UART_PARITY_NONE, 
                      UART_STOP_1);
    CHECK_RETVAL(Retval, ExitOnFailure);

    for ( ; ; )
    {
        Retval = UartRead(hUart, Buff, sizeof(Buff), &BytesRead, 1000);
    
        if (BytesRead)
        {	
            UartTestToUpper(Buff, BytesRead);

            Retval = UartWrite(hUart, Buff, BytesRead, &BytesWritten, 1000);
            CHECK_RETVAL(Retval, ExitOnFailure);
        }
    }
  
ExitOnFailure:

    UartDtor(hUart);

    return Retval;
}
Example #13
0
// write a byte using the target monitor
int WriteByte(tUartHandle serial_handle, UINT32 addr, UINT8 byte)
{
	UINT8 send;
	UINT8 received;

	// send the address command
	send = ADDRESS;
	UartWrite(serial_handle, &send, 1);

	// transmit the address, big endian
	send = (UINT8)((addr>>24) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>16) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>8) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)(addr & 0xFF);
	UartWrite(serial_handle, &send, 1);

	UartRead(serial_handle, &received, 1); // response
	if (received != ADDRESS)
	{
		printf("Protocol error, receiced 0x%02X!\n", received);
		return 1;
	}

	// send the write command
	send = BYTE_WRITE;
	UartWrite(serial_handle, &send, 1);

	// transmit the data
	UartWrite(serial_handle, &byte, 1);
	
	UartRead(serial_handle, &received, 1); // response

	if (received != BYTE_WRITE)
	{
		printf("Protocol error!\n");
		return 1;
	}

	return 0;
}
Example #14
0
// call a subroutine using the target monitor
int Execute(tUartHandle serial_handle, UINT32 addr, bool bReturns)
{
	UINT8 send;
	UINT8 received;

	// send the address command
	send = ADDRESS;
	UartWrite(serial_handle, &send, 1);

	// transmit the address, big endian
	send = (UINT8)((addr>>24) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>16) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>8) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)(addr & 0xFF);
	UartWrite(serial_handle, &send, 1);

	UartRead(serial_handle, &received, 1); // response
	if (received != ADDRESS)
	{
		printf("Protocol error!\n");
		return 1;
	}

	// send the execute command
	send = EXECUTE;
	UartWrite(serial_handle, &send, 1);
	if (bReturns)
	{	// we expect the call to return control to minimon
		UartRead(serial_handle, &received, 1); // response

		if (received != EXECUTE)
		{
			printf("Protocol error!\n");
			return 1;
		}
	}

	return 0;
}
Example #15
0
// read a 16bit halfword using the target monitor
UINT16 ReadHalfword(tUartHandle serial_handle, UINT32 addr)
{
	UINT8 send;
	UINT8 received;
	UINT16 halfword;

	// send the address command
	send = ADDRESS;
	UartWrite(serial_handle, &send, 1);

	// transmit the address, big endian
	send = (UINT8)((addr>>24) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>16) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)((addr>>8) & 0xFF);
	UartWrite(serial_handle, &send, 1);
	send = (UINT8)(addr & 0xFF);
	UartWrite(serial_handle, &send, 1);

	UartRead(serial_handle, &received, 1); // response
	if (received != ADDRESS)
	{
		printf("Protocol error!\n");
		return 1;
	}

	// send the read command
	send = HALFWORD_READ;
	UartWrite(serial_handle, &send, 1);

	UartRead(serial_handle, &received, 1); // response
	halfword = received << 8; // highbyte
	UartRead(serial_handle, &received, 1);
	halfword |= received; // lowbyte

	return halfword;
}
/*!
    \brief Test the spi communication

    \param[in]      none

    \return         upon successful, the function shall return 0.
                    Otherwise, -1 shall be returned

    \warning
*/
static int TestSpi()
{
    const _SlSyncPattern_t     H2NCnysPattern = H2N_CNYS_PATTERN;

    _SlFd_t FD = 0;
    unsigned int             irqCheck = 0;
    unsigned char            pBuf[8] = {'\0'};
    unsigned char            SyncCnt  = 0;
    unsigned char            ShiftIdx = 0;
  
    /* Start the state machine */
    SetTestStage(TEST_STAGE_SPI_TEST_BEGIN);
  
    /* Initialize the Spi interface */
    FD = sl_IfOpen(0, 0);
    SetTestStage(TEST_STAGE_SPI_OPEN_PASSED);
  
    /* Register IRQ handler */
    sl_IfRegIntHdlr((P_EVENT_HANDLER)DiagIrqHandler, 0);
  
    /*Make Sure that the device is turned off */
    sl_DeviceDisable();
    SetTestStage(TEST_STAGE_DISABLE_PASSED);
  
    /* Save IRQ counter before activating the Device */
    irqCheck = g_irqCounter;
  
    /* Turn on the device */
    sl_DeviceEnable();
    SetTestStage(TEST_STAGE_ENABLE_PASSED);
  
    /* Wait until we get an increment on IRQ value */
    while( irqCheck == g_irqCounter )
    {
    }  
  
    SetTestStage(TEST_STAGE_SPI_IRQ_PASSED);
  
    /* Generate the sync pattern for getting the response */
    sl_IfWrite(FD, (unsigned char *)&H2NCnysPattern, SYNC_PATTERN_LEN);
    SetTestStage(TEST_STAGE_SPI_WRITE_PASSED);
  
    /* Read 4 bytes from the Spi */
    sl_IfRead(FD, &pBuf[0], 4);
  
    /* Sync on read pattern */
    while ( ! N2H_SYNC_PATTERN_MATCH(pBuf, TxSeqNum))
    {
        /* Read next 4 bytes to Low 4 bytes of buffer */
        if(0 == (SyncCnt % SYNC_PATTERN_LEN))
        {
            sl_IfRead(FD, &pBuf[4], 4);
        }
     
        /* Shift Buffer Up for checking if the sync is shifted */
        for(ShiftIdx = 0; ShiftIdx < 7; ShiftIdx++)
        {
            pBuf[ShiftIdx] = pBuf[ShiftIdx+1];
        }
        pBuf[7] = 0;
        SyncCnt++;
    }
  
    /*Sync pattern found. If needed, complete number of read bytes to multiple
    * of 4 (protocol align) */
    SyncCnt %= SYNC_PATTERN_LEN;
  
    if(SyncCnt > 0)
    {
        *(UINT32 *)&pBuf[0] = *(UINT32 *)&pBuf[4];
        sl_IfRead(FD, &pBuf[SYNC_PATTERN_LEN - SyncCnt], SyncCnt);
    }
    else
    {
        sl_IfRead(FD, &pBuf[0], 4);
    }
  
    /* Scan for possible double pattern */
    while( N2H_SYNC_PATTERN_MATCH(pBuf, TxSeqNum))
    {
        sl_IfRead(FD, &pBuf[0], SYNC_PATTERN_LEN);
    }
  
    /* Read the Resp Specific header (4 more bytes) */
    sl_IfRead(FD, &pBuf[SYNC_PATTERN_LEN], 4);
    SetTestStage(TEST_STAGE_SPI_READ_PASSED);
  
    /* Check the init complete message opcode */
    if(SL_OPCODE_DEVICE_INITCOMPLETE != (*(unsigned short*)(pBuf)))
    {
        UartWrite((unsigned char *)"Error in Spi Testing\r\n");
        return -1; /* failed to read init complete */
    }
  
    SetTestStage(TEST_STAGE_INIT_COMPLETE_READ_PASSED);
    SetTestStage(TEST_STAGE_SPI_TEST_COMPLETE);
  
    return SUCCESS;
}
/*!
    \brief Update the state machine and write the output on Application UART

    \param[in]      stage - New state of the application

    \return         none

    \warning
*/
static void SetTestStage(testStage_e stage)
{
    g_testStage = stage;
    switch(stage)
   {
    case TEST_STAGE_SPI_TEST_BEGIN:
      UartWrite((unsigned char *)TEST_SPI_BEGIN);
      UartWrite((unsigned char *)"\r\n");
      break;
    case TEST_STAGE_SPI_OPEN_PASSED:
      UartWrite((unsigned char *)TEST_SPI_OPEN_PASSED);
      UartWrite((unsigned char *)"\r\n");
      break;
    case TEST_STAGE_DISABLE_PASSED:
      UartWrite((unsigned char *)TEST_DEVICE_DISABLE_PASSED);
      UartWrite((unsigned char *)"\r\n");
      break;
    case TEST_STAGE_ENABLE_PASSED:
      UartWrite((unsigned char *)TEST_DEVICE_ENABLE_PASSED);
      UartWrite((unsigned char *)"\r\n");
      break;
    case TEST_STAGE_SPI_WRITE_PASSED:
      UartWrite((unsigned char *)TEST_SPI_WRITE_PASSED);
      UartWrite((unsigned char *)"\r\n");
      break;
    case TEST_STAGE_SPI_READ_PASSED:
      UartWrite((unsigned char *)TEST_SPI_READ_PASSED);
      UartWrite((unsigned char *)"\r\n");
      break;
    case TEST_STAGE_SPI_IRQ_PASSED:
      UartWrite((unsigned char *)TEST_SPI_IRQ_PASSED);
      UartWrite((unsigned char *)"\r\n");
      break;
    case TEST_STAGE_INIT_COMPLETE_READ_PASSED:
      UartWrite((unsigned char *)SPI_INIT_COMPLETE_READ_PASSED);
      UartWrite((unsigned char *)"\r\n");
      break;
    case TEST_STAGE_SPI_TEST_COMPLETE:
      UartWrite((unsigned char *)SPI_TEST_COMPLETED);
      UartWrite((unsigned char *)"\r\n\r\n");
      break;
    }
}
Example #18
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      handleOperand
 *
 *  DESCRIPTION
 *      This function processes the received operand and the associated data.
 *      It calls the application handler function for the supported operands
 *      and send an appropriate response over the UART
 *
 * PARAMETERS
 *      Nothing
 *
 * RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
static void handleOperand(void)
{
    uint8 response[MAX_RESPONSE_LEN];
    uint8 length = 0;
    BD_ADDR_T bd_addr;
    uint16 key[SIZE_LTK_IN_WORDS];

    /* Check is it's a SET command or a GET command. */
    if(g_command == SET_REQUEST_CMD)
    {
        /* It's a SET command, Start preparing response for it.
         * The reponse will contain three fields:
         * 1. SET_RESPONSE_CMD [1 octet]
         * 2. OPERAND [1 octet]
         * 3. STATUS- RESPONSE_SUCCESS or RESPONSE_FAILURE [1 octet]
         */
        response[0] = SET_RESPONSE_CMD;

        response[1] = g_operand;

        /* Check which operand the SET request is for. */
        switch(g_operand)
        {
            /* Trunk Open or close request has been received. */
            case OPERAND_TRUNK_OPERATION:
            {
                /* This request will never fail. 
                 * The following two operations can be done:
                 * 0x00 - Open Trunk
                 * 0x01 - Close Trunk
                 * 
                 * The remote connected keyfob can also send an Open trunk 
                 * request to the automotive Host application. In this case, 
                 * the application shall send a notification about the trunk 
                 * status over the UART interface.
                 */
                if(SetVehicleInformationData(index_trunk_status, g_operandData))
                {
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    response[2] = RESPONSE_FAILURE; /* This error code will 
                                                     * never be returned for 
                                                     * this SET rquest.
                                                     */
                }
            }
            break;

#ifdef ENABLE_INFACTORY_PAIRING
            /* The request is for setting LTK for the connection */
            case OPERAND_LTK:
            {
                /* Pack the LTK into the key and pass it to the application */
                MemCopyPack(key, g_operandData, SIZE_LTK_IN_WORDS *2);

                if(SetLTKForTheConnection(key))
                {
                    /* Return Success for the Set request. */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return Failure for the Set request. */
                    response[2] = RESPONSE_FAILURE;
                }
            }
            break;

            /* The request is for setting the IRK of the paired keyfob */
            case OPERAND_IRK:
            {
                /* Pack the IRK into the key and pass it to the application */
                MemCopyPack(key, g_operandData, SIZE_IRK_IN_WORDS *2);

                if(SetIRKForTheConnection(key))
                {
                    /* Return Success for the Set request. */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return Failure for the Set request. */
                    response[2] = RESPONSE_FAILURE;
                }

            }
            break;


            /* The request is for setting the Bluetooth device address of the 
             * bonded keyfob.
             */
            case OPERAND_FOB_BDADDR:
            {
                /* Copy the BD Address of the Vehicle into the BD_ADDR_T 
                 * stucture and pass it application 
                 */
                /* LAP part is of 24 bits. */
                bd_addr.lap =  ((uint24)g_operandData[0])  |
                              (((uint24)g_operandData[1]) << 8) |
                              (((uint24)g_operandData[2]) << 16);

                /* UAP is of 8bits */
                bd_addr.uap =           g_operandData[3];

                /* NAP is of 16bits */
                bd_addr.nap =  ((uint16)g_operandData[4]) |
                              (((uint16)g_operandData[5]) << 8);

                if(SetBondedKeyFobAddress(&bd_addr))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }
            }
            break;

#endif /* ENABLE_INFACTORY_PAIRING */

            /* The request is for deleting phone-keyfob pairing information
             * present on the keyfob
             */
            case OPERAND_DELETE_PAIRING:
            {
                if(!DeletePhoneKeyFobPairing())
                {
                    /* Pairing deletion has failed. Return a failure. */
                    response[2] = RESPONSE_FAILURE;
                }
                else
                {
                    /* The application has written to the remote keyfob's 
                     * Delete pairing characteristic. Don't send any response 
                     * here. Once the application receives a response for the 
                     * write request, it will send a SET RESPONSE
                     * over the UART interface.
                     */
                    return;
                }
            }
            break;

            /* A handle hold has been detectecd.
             * For demo purposes, A SET REQUEST over UART with the handle hold 
             * operand will act as a trigger 
             */
            case OPERAND_CAR_HNDL_HOLD:
            {
                /* A success result in a SET RESPONSE shall be immediately sent 
                 * for this operand.
                 */
                response[2] = RESPONSE_SUCCESS;
                length = 3;
                UartWrite(response, length);

                /* For this operand, the application implements a passive entry 
                 * mechanism where the Automotive Host application will do some 
                 * proximity measurements. If it finds the keyfob in range, it 
                 * will execute the Special Authentication Challenge Response 
                 * procedure. If the Special Authentication Challenge Response
                 * procedures completes with a success, the application will 
                 * unlock the doors.
                 */
                if(AppIsDeviceConnected() && 
                   IsVehicleLocked()&& 
                   CheckProximity())
                {
#ifdef ENABLE_SPECIAL_AUTHENTICATION
                    SetUnlockRequestReceivedFlag();
                    ExecuteServiceDiscoverySplAuthProcedureOnHandleHold();
#else
                    UnlockTheVehicle();
#endif
                }
                return;
            }
            break;

            /* A Lock/Unlock command has been received over the UART interface.
             */
            case OPERAND_LOCK_STATUS:
            {
                /* This is a request from inside the vehicle itself. This 
                 * request shall never fail.
                 */
                if(SetVehicleInformationData(index_lock_unlock ,
                                                        g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }

                /* Depending upon the data received in the command, take 
                 * action. 
                 */
                if(g_operandData[0] == door_locked)
                {
                    LockTheVehicle();
                }
                else if(g_operandData[0] == door_unlocked)
                {
                    UnlockTheVehicle();
                }
            }
            break;

            /* This command is for Radio setting */
            case OPERAND_RADIO_SETTING:
            {
                /* Store the Radio setting received. */
                if(SetVehicleInformationData(index_radio_setting,
                                                            g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }
            }
            break;

            /* Latitude location of the vehicle is being set */
            case OPERAND_LATITUDE:
            {
                /* Store the new latitude location. */
                if(SetVehicleInformationData(index_location_latitude,
                                                            g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }

            }
            break;

            /* Longitude location of the vehicle is being set. */
            case OPERAND_LONGITUDE:
            {
                /* Store the new longitude location */
                if(SetVehicleInformationData(index_location_longitude,
                                                            g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }

            }
            break;

            /* Speed limit of the vehicle is being set */
            case OPERAND_SPEED_LIMIT:
            {
                /* Store the new speed limit. */
                if(SetVehicleInformationData(index_speed_limit,
                                                            g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }

            }
            break;

            /* Tyre pressure information  is being fed to the vehicle 
             * information service.
             */
            case OPERAND_TYRE_PRESSURE:
            {
                /* Store the tyre pressure information in the corresponding 
                 * characteristic in the Vehicle Information service.
                 */
                if(SetVehicleInformationData(index_tyre_pressure,
                                                            g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }

            }
            break;

            /* Licence number of the driver is being stored in the vehicle. */
            case OPERAND_LIC_NUMBER:
            {
                /* Store the licence number of the driver in the corresponding 
                 * characteristic
                 */
                if(SetVehicleInformationData(index_licence_plate,
                                                            g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }

            }
            break;

            /* Fuel level information is being stored in the Vehicle 
             * Information service. This information will be transferred to the 
             * keyfob and a user will be able to know the fuel level using his 
             * mobile phone even when he is not near the vehicle.
             */
            case OPERAND_FUEL_LEVEL:
            {
                /* Store the Fuel level information in the Vehicle Information 
                 * service.
                 */
                if(SetVehicleInformationData(index_fuel_info,
                                                            g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }

            }
            break;

            /* Mileage information is being stored in the Vehicle Information 
             * Service which will be transferred to the keyfob so that a user 
             * can see the mileage from his mobile phone even when he is not
             * near the vehicle.
             */
            case OPERAND_MILEAGE:
            {
                /* Store the mileage information in the vehicle Information 
                 * service. 
                 */
                if(SetVehicleInformationData(index_mileage_info,
                                                            g_operandData))
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }
            }
            break;

            case OPERAND_CONN_CHANNEL_MAP:
            {
                /* Set the connection channel map */
                if(GapSetConnChanMask(g_operandData) == ls_err_none)
                {
                    /* Return success for the SET REQUEST */
                    response[2] = RESPONSE_SUCCESS;
                }
                else
                {
                    /* Return failure for the SET REQUEST */
                    response[2] = RESPONSE_FAILURE;
                }
            }
            break;

            default:
            {
                /* No other opcode is supported for a SET REQUEST, return 
                 * failure 
                 */
                response[2] = RESPONSE_FAILURE;
            }
            break;

        }
        /* Total length of the response is 3 octets */
        length = 3;
    }



    /* A GET REQUEST has been received over the UART */
    else if(g_command == GET_REQUEST_CMD)
    {
        /* Prepare a GET RESPONSE. The response will have the following format:
         * 1. GET_RESPONSE_CMD [1 octet]
         * 2. OPERAND [1 octet]
         * 3. DATA [Variable number of octets]
         */
        response[0] = GET_RESPONSE_CMD;
        response[1] = g_operand;

        switch(g_operand)
        {
            case OPERAND_LOCK_STATUS:
            {
                /* Return 0x00- Unlocked 
                 *        0x01- Locked
                 * Depending upon whether doors are locked or unlocked.
                 */
                GetVehicleInformationData(index_lock_unlock, &response[2]);
                length = 2 + LENGTH_LOCK_UNLOCK_STATUS;
            }
            break;

            /* The received request is for Battery Level of the keyfob. */
            case OPERAND_BATTERY_LEVEL:
            {
                /* The application shall return the current stored Battery 
                 * level in a GET Response.
                 */
                response[2] = GetStoredKeyfobBatteryLevel();
                length = 3;
            }
            break;

            /* The received request is for Radio setting. */
            case OPERAND_RADIO_SETTING:
            {
                /* The application shall return the current radio setting from 
                 * the characteristic. 
                 */
                GetVehicleInformationData(index_radio_setting, &response[2]);
                length = 2 + LENGTH_RADIO_SETTING;
            }
            break;

            /* The received request is for Latitude location */
            case OPERAND_LATITUDE:
            {
                /* Return the currently stored latitude location from the 
                 * Vehicle Information service. 
                 */
                GetVehicleInformationData(index_location_latitude, 
                                          &response[2]);
                length = 2 + LENGTH_LATITUDE_LOCATION;
            }
            break;


            /* The received request is for longitude location */
            case OPERAND_LONGITUDE:
            {
                /* Return the currently stored longitude location from the 
                 * Vehicle Information service.
                 */
                GetVehicleInformationData(index_location_longitude,
                                          &response[2]);
                length = 2 + LENGTH_LONGITUDE_LOCATION;
            }
            break;

            /* The received request is for the Speed Limit currently set in the 
             * Vehicle Information Service. 
             */
            case OPERAND_SPEED_LIMIT:
            {
                /* Return the currently stored Speed Limit value from the 
                 * Vehicle Information service.
                 */
                GetVehicleInformationData(index_speed_limit,
                                              &response[2]);
                length = 2 + LENGTH_SPEED_LIMIT;
            }
            break;


            /* The received request is for Tyre pressure. */
            case OPERAND_TYRE_PRESSURE:
            {
                /* Return the current stored value from the Vehicle Information 
                 * Service.
                 */
                GetVehicleInformationData(index_tyre_pressure,
                                                  &response[2]);
                length = 2 + LENGTH_TYRE_PRESSURE;
            }
            break;

            /* The received request is for the Licese number stored in the 
             * Vehicle Information Service.
             */
            case OPERAND_LIC_NUMBER:
            {
                /* Store the Licence number information stored in the Vehicle 
                 * Information Service.
                 */
                GetVehicleInformationData(index_licence_plate,
                                          &response[2]);
                length = 2 + LENGTH_LICENCE_PLATE_INFO;
            }
            break;

            /* The request is for the Fuel level */
            case OPERAND_FUEL_LEVEL:
            {
                /* Return the Fuel Level information from the Vehicle 
                 * Information Service.
                 */
                GetVehicleInformationData(index_fuel_info,
                                              &response[2]);
                length = 2 + LENGTH_FUEL_LEVEL_INFO;
            }
            break;

            /* The received request is for the mileage information */
            case OPERAND_MILEAGE:
            {
                /* Return the current mileage information stored in the Vehicle 
                 * information service.
                 */
                GetVehicleInformationData(index_mileage_info,
                                          &response[2]);
                length = 2 + LENGTH_MILEAGE_INFO;
            }
            break;

            /* Device role has been requested. */
            case OPERAND_DEVICE_ROLE:
            {
                /* Device role has been requested.*/
                response[2] = DEVICE_ROLE_VEHICLE;
                length = 3;
            }
            break;

            /* The request is for getting the Bluetooth device address of the 
             * Automotive Host.
             */
            case OPERAND_CAR_BDADDR:
            {
#ifdef USE_RESOLVABLE_RANDOM_ADDRESS
                /* If privacy is enabled generate Resolvable random address 
                 * and use it as advAddress. 
                 */
                SMPrivacyRegenerateAddress(NULL);
                GapGetRandomAddress(&bd_addr);
#else
                /* Read the public BD address */
                CSReadBdaddr(&bd_addr);
#endif /* USE_RESOLVABLE_RANDOM_ADDRESS */

                /* First LAP part of the bluetooth address into the response 
                 * buffer. (LSB first).
                 */
                response[2] = (uint8 )bd_addr.lap;
                response[3] = (uint8 )(bd_addr.lap >> 8);
                response[4] = (uint8 )(bd_addr.lap >> 16);

                /* Copy UAP part into the response buffer */
                response[5] = (uint8 )(bd_addr.uap);

                /* Copy NAP part into the response buffer(LSB first) */
                response[6] = (uint8 )(bd_addr.nap);
                response[7] = (uint8 )(bd_addr.nap >> 8);
                length = 8;
            }
            break;

            case OPERAND_IRK:
            {
#ifdef USE_RESOLVABLE_RANDOM_ADDRESS
                uint16 irk[SIZE_IRK_IN_WORDS];

                /* Read the device IRK */
                SMPrivacyGetOwnIrk(irk);

                /* Copy IRK to the response buffer */
                MemCopyUnPack(&response[2], irk, SIZE_IRK_IN_WORDS * 2);
                length = 18;
#else
                /* Respond with operand un-supported if random address is
                 * not supported 
                 */
                response[0] = GET_RESPONSE_CMD;
                response[1] = OPERAND_ERROR_STATUS;
                response[2] = ERR_OPERAND_NOT_SUPPORTED;
                response[3] = OPERAND_IRK;
                length = 4;
#endif /* USE_RESOLVABLE_RANDOM_ADDRESS */
            }
            break;

            /* The received request is for connection status. */
            case OPERAND_CONNECTION_STATUS:
            {
                /* The application shall return the current connection state.
                 */
                if(AppIsDeviceConnected())
                {
                    response[2] = conn_status_connected;
                }
                else
                {
                    response[2] = conn_status_disconnected;
                }
                length = 3;
            }
            break;

            default:
            {
                /* No other GET REQUEST is supported, Ignore the received 
                 * request.
                 */
                length = 0;
            }
            break;
        }
    }
Example #19
0
// download our little monitor, the box must have been just freshly switched on for this to work
int DownloadMonitor(tUartHandle serial_handle, bool bRecorder, char* szFilename)
{
	FILE* pFile;
	size_t filesize;
	UINT8 byte;
	unsigned i;

	// hard-coded parameters
	bool bAck = true; // configure if acknowledged download (without useful for remote pin boot)
	UINT32 TargetLoad = 0x0FFFF000; // target load address

	pFile = fopen(szFilename, "rb");
	if (pFile == NULL)
	{
		printf("\nMonitor file %s not found, exiting\n", szFilename);
		exit(1);
	}

	// determine file size
	fseek(pFile, 0, SEEK_END);
	filesize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);

	// This is _really_ tricky! The box expects a BRR value in a nonstandard baudrate,
	//	which a PC can't generate. I'm using a higher one with some wild settings
	//	to generate a pulse series that:
	//	1) looks like a stable byte when sampled with the nonstandard baudrate
	//	2) gives a BRR value to the box which results in a baudrate the PC can also use
	if (bRecorder)
	{
		ConfigFirstlevelRecorder(serial_handle);
	}
	else
	{
		ConfigFirstlevelPlayer(serial_handle);
	}

	UartWrite(serial_handle, bAck ? (UINT8*)"\x01" : (UINT8*)"\x00", 1); // ACK mode

	// transmit the size, little endian
	DownloadByte(serial_handle, (UINT8)( filesize	   & 0xFF), bAck);
	DownloadByte(serial_handle, (UINT8)((filesize>>8)  & 0xFF), bAck);
	DownloadByte(serial_handle, (UINT8)((filesize>>16) & 0xFF), bAck);
	DownloadByte(serial_handle, (UINT8)((filesize>>24) & 0xFF), bAck);

	// transmit the load address, little endian
	DownloadByte(serial_handle, (UINT8)( TargetLoad 	 & 0xFF), bAck);
	DownloadByte(serial_handle, (UINT8)((TargetLoad>>8)  & 0xFF), bAck);
	DownloadByte(serial_handle, (UINT8)((TargetLoad>>16) & 0xFF), bAck);
	DownloadByte(serial_handle, (UINT8)((TargetLoad>>24) & 0xFF), bAck);

	// transmit the command byte
	DownloadByte(serial_handle, 0xFF, bAck); // 0xFF means execute the transferred image

	// transmit the image
	for (i=0; i<filesize; i++)
	{
		fread(&byte, 1, 1, pFile);
		DownloadByte(serial_handle, byte, bAck);
	}

	fclose (pFile);

	// now the image should have been started, red LED off

	return 0;
}
Example #20
0
// rarely used variant: download our monitor using the built-in Archos monitor
int DownloadArchosMonitor(tUartHandle serial_handle, char* szFilename)
{
	FILE* pFile;
	size_t filesize;
	UINT8 byte;
	UINT16 checksum = 0;
	unsigned i;

	// the onboard monitor uses 115200 baud
	if(!UartConfig(serial_handle, 115200, eNOPARITY, eONESTOPBIT, 8))
	{
		UINT32 dwErr = GET_LAST_ERR();
		printf("Error %lu setting up COM params for baudrate %d\n", dwErr, 115200);
		exit(1);
	}

	// wait for receiving "#SERIAL#"
	WaitForString(serial_handle, "#SERIAL#");
	
	// send magic "SRL" command to get interactive mode
	SendWithEcho(serial_handle, "SRL\r");
	
	// wait for menu completion: "ROOT>" at the end
	WaitForString(serial_handle, "ROOT>");
	
	// send upload command "UP"
	SendWithEcho(serial_handle, "UP\r");
	
	pFile = fopen(szFilename, "rb");
	if (pFile == NULL)
	{
		printf("\nMonitor file %s not found, exiting\n", szFilename);
		exit(1);
	}

	// determine file size
	fseek(pFile, 0, SEEK_END);
	filesize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);
	
	// calculate checksum
	for (i=0; i<filesize; i++)
	{
		fread(&byte, 1, 1, pFile);
		checksum += byte;
	}
	fseek(pFile, 0, SEEK_SET);
	
	// send header

	// size as 32 bit little endian
	byte = (UINT8)( filesize	  & 0xFF);
	UartWrite(serial_handle, &byte, 1);
	byte = (UINT8)((filesize>>8)  & 0xFF);
	UartWrite(serial_handle, &byte, 1);
	byte = (UINT8)((filesize>>16) & 0xFF);
	UartWrite(serial_handle, &byte, 1);
	byte = (UINT8)((filesize>>24) & 0xFF);
	UartWrite(serial_handle, &byte, 1);

	// checksum as 16 bit little endian
	byte = (UINT8)( checksum	  & 0xFF);
	UartWrite(serial_handle, &byte, 1);
	byte = (UINT8)((checksum>>8)  & 0xFF);
	UartWrite(serial_handle, &byte, 1);
	
	UartWrite(serial_handle, (unsigned char*)"\x00", 1); // kind (3 means flash)
	UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte

	// wait for monitor to accept data
	WaitForString(serial_handle, "#OKCTRL#");
	
	// transmit the image
	for (i=0; i<filesize; i++)
	{
		fread(&byte, 1, 1, pFile);
		UartWrite(serial_handle, &byte, 1); // payload
	}
	fclose (pFile);
	
	UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte

	// wait for menu completion: "ROOT>" at the end
	WaitForString(serial_handle, "ROOT>");

	// send start program command "SPRO"
	SendWithEcho(serial_handle, "SPRO\r");

	SLEEP(100); // wait a little while for startup

	return 0;
}