diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d9eaf2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +*.o + +Build/JennicModuleProgrammer diff --git a/Build/Makefile b/Build/Makefile index b757127..a824d7f 100644 --- a/Build/Makefile +++ b/Build/Makefile @@ -32,7 +32,7 @@ CFLAGS = -Wall -O2 # CFLAGS += -DDEBUG_BOOTLOADER # Define to trace firmware image info -# #CFLAGS += -DDEBUG_FIRMWARE +# CFLAGS += -DDEBUG_FIRMWARE # Define to trace serial comms # CFLAGS += -DDEBUG_UART diff --git a/Source/ChipID.h b/Source/ChipID.h index cf36453..4613a7c 100644 --- a/Source/ChipID.h +++ b/Source/ChipID.h @@ -88,6 +88,7 @@ extern "C" { #define CHIP_ID_COG04 0x00007686 /* Cougar COG04 */ #define CHIP_ID_JN5168 0x00008686 /* Cougar COG05 */ #define CHIP_ID_JN5168_COG07 0x10008686 /* Cougar COG07 */ +#define CHIP_ID_JN5169 0x6000B686 /* Cougar COG05 */ /* Macro to get just the Part ID from the chip ID */ diff --git a/Source/Firmware.c b/Source/Firmware.c index f885fa7..fd4e603 100644 --- a/Source/Firmware.c +++ b/Source/Firmware.c @@ -51,7 +51,9 @@ /****************************************************************************/ #include +#ifdef __linux__ #include +#endif #include #include #include diff --git a/Source/JN51xx_BootLoader.c b/Source/JN51xx_BootLoader.c index 8392f34..e5c8193 100644 --- a/Source/JN51xx_BootLoader.c +++ b/Source/JN51xx_BootLoader.c @@ -51,7 +51,9 @@ /****************************************************************************/ #include +#ifdef __linux__ #include +#endif #include #include #include @@ -101,6 +103,8 @@ /* Location of device configuration in memory map */ #define JN516X_INDEX_SECTOR_DEVICE_CONFIG_ADDR 0x01001500 +/* Location of Customer Settings in memory map */ +#define JN516X_INDEX_CUSTOMER_SETTINGS_ADDR 0x01001510 /****************************************************************************/ /*** Type Definitions ***/ @@ -267,6 +271,8 @@ teStatus BL_eGetChipId(int iUartFd, tsChipDetails *psChipDetails) return E_STATUS_NULL_PARAMETER; } + psChipDetails->u32CustomerSettings = 0xFFFFFFFF; + /* Send chip id request */ if(iBL_ReadChipId(iUartFd, &psChipDetails->u32ChipId) < 0) { @@ -327,6 +333,70 @@ teStatus BL_eGetChipId(int iUartFd, tsChipDetails *psChipDetails) DBG_vPrintf(TRACE_BOOTLOADER, "JN516x Supported firmware 0x%08x\n", psChipDetails->u32SupportedFirmware); } } + else if (CHIP_ID_PART(psChipDetails->u32ChipId) == CHIP_ID_PART(CHIP_ID_JN5169)) + { + + psChipDetails->u32BootloaderVersion = 0; + int bFlashLoad = 1; + int bFlashEnc = 1; + int iCRPLevel = 3; + int iVBOThr = 7; + int bCPUJTAG = 1; + + if (iBL_ReadRAM(iUartFd, JN516X_INDEX_CUSTOMER_SETTINGS_ADDR, 4, au8Buffer) < 0) + { + DBG_vPrintf(TRACE_BOOTLOADER, "Error Reading Customer Settings\n"); + return E_STATUS_ERROR; + } + else + { + bFlashLoad = (au8Buffer[3] >> 7) & 0x01; + bFlashEnc = (au8Buffer[3] >> 6) & 0x01; + iCRPLevel = (au8Buffer[3] >> 4) & 0x03; + iVBOThr = (au8Buffer[3] >> 1) & 0x07; + bCPUJTAG = (au8Buffer[3] >> 0) & 0x01; + + psChipDetails->u32CustomerSettings = au8Buffer[0] << 24; + psChipDetails->u32CustomerSettings |= au8Buffer[1] << 16; + psChipDetails->u32CustomerSettings |= au8Buffer[2] << 8; + psChipDetails->u32CustomerSettings |= au8Buffer[3] << 0; + + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x FLASH_LOAD %d (If 0 then loading firmware from external Flash is disabled)\n", bFlashLoad); + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x FLASH_ENC %d (If 0 then the contents of external Flash are decrypted as they are loaded into internal Flash memory)\n", bFlashEnc); + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x CRP_LEVEL %d\n", iCRPLevel); + DBG_vPrintf(TRACE_BOOTLOADER, "\t0 = CRP level 2 (no programming allowed via UART)\n"); + DBG_vPrintf(TRACE_BOOTLOADER, "\t1 = CRP level 1 (Flash read protection)\n"); + DBG_vPrintf(TRACE_BOOTLOADER, "\t2 = CRP level 2 (no programming allowed via UART)\n"); + DBG_vPrintf(TRACE_BOOTLOADER, "\t3 = CRP level 0 (no protection))\n"); + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x VBO_THR %d\n", iVBOThr); + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x CPU_JTAG %d (If 0 then CPU JTAG access is disabled)\n", bCPUJTAG); + } + + if (iBL_ReadRAM(iUartFd, JN516X_INDEX_SECTOR_DEVICE_CONFIG_ADDR, 4, au8Buffer) < 0) + { + DBG_vPrintf(TRACE_BOOTLOADER, "Error Reading config from flash index sector\n"); + return E_STATUS_ERROR; + } + else + { + psChipDetails->u32RamSize = (au8Buffer[3] & 0x07) >> 0; + psChipDetails->u32FlashSize = (au8Buffer[3] & 0x30) >> 4; + + psChipDetails->u32RamSize = 32/8-1; //!!! + psChipDetails->u32FlashSize = 512/32-1; //!!! + + psChipDetails->u32SupportedFirmware = ( + (psChipDetails->u32FlashSize << 16) | + (psChipDetails->u32RamSize << 24) | + (0x08)); + psChipDetails->u32SupportedFirmware = 0x0f03000b; //!!! + + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x RAM size %dk\n", (psChipDetails->u32RamSize * 8) + 8); + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x Flash size %dk\n", (psChipDetails->u32FlashSize * 32) + 32); + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x Bootloader version 0x%08x\n", psChipDetails->u32BootloaderVersion); + DBG_vPrintf(TRACE_BOOTLOADER, "JN516x Supported firmware 0x%08x\n", psChipDetails->u32SupportedFirmware); + } + } else { if (iBL_ReadRAM(iUartFd, JN514X_ROM_ID_ADDR, 4, au8Buffer) < 0) @@ -380,6 +450,7 @@ teStatus BL_eGetMacAddress(int iUartFd, tsChipDetails *psChipDetails) break; case CHIP_ID_PART(CHIP_ID_JN5168): + case CHIP_ID_PART(CHIP_ID_JN5169): /* First we read the customer specific MAC address, and if its not all F's, we use that */ iRetval = iBL_ReadRAM(iUartFd, JN516X_CUSTOMER_MAC_ADDRESS_LOCATION, 8, psChipDetails->au8MacAddress); @@ -476,6 +547,7 @@ teStatus BL_eReprogram(int iUartFd, tsChipDetails *psChipDetails, tsFW_Info *psF break; case CHIP_ID_PART(CHIP_ID_JN5168): + case CHIP_ID_PART(CHIP_ID_JN5169): break; default: @@ -537,49 +609,53 @@ teStatus BL_eReprogram(int iUartFd, tsChipDetails *psChipDetails, tsFW_Info *psF return E_STATUS_ERROR; } + if((psChipDetails->u32CustomerSettings&0x30) != 0x30){ + DBG_vPrintf(TRACE_BOOTLOADER, "Cannot check for Flash blankness, because of CRP\n"); + }else{ /* Ensure that flash is erased */ - DBG_vPrintf(TRACE_BOOTLOADER, "Checking flash is blank...\n"); - memset(au8Buffer2, 0xFF, 64); + DBG_vPrintf(TRACE_BOOTLOADER, "Checking flash is blank...\n"); + memset(au8Buffer2, 0xFF, 64); - if (iBL_ReadFlash(iUartFd, 0, 64, au8Buffer1) == -1) - { - DBG_vPrintf(TRACE_BOOTLOADER, "Error reading Flash at address 0x%08x\n", 0); - return E_STATUS_ERROR; - } - else - { - if (memcmp(au8Buffer1, au8Buffer2, 64)) + if (iBL_ReadFlash(iUartFd, 0, 64, au8Buffer1) == -1) { - printf("Failed to erase Flash: not blank!\n"); -#if 0 + DBG_vPrintf(TRACE_BOOTLOADER, "Error reading Flash at address 0x%08x\n", 0); + return E_STATUS_ERROR; + } + else + { + if (memcmp(au8Buffer1, au8Buffer2, 64)) { - /* Dump the contents in hex */ - DBG_vPrintf(TRACE_BOOTLOADER, "Dumping %d bytes\n", 64); - for(n = 0; n < 64; n++) + printf("Failed to erase Flash: not blank!\n"); +#if 0 { - - if((n % 16) == 0) + /* Dump the contents in hex */ + DBG_vPrintf(TRACE_BOOTLOADER, "Dumping %d bytes\n", 64); + for(n = 0; n < 64; n++) { - DBG_vPrintf(TRACE_BOOTLOADER, "\n%08x: ", n); - } - DBG_vPrintf(TRACE_BOOTLOADER, " %02x", au8Buffer1[n]); + if((n % 16) == 0) + { + DBG_vPrintf(TRACE_BOOTLOADER, "\n%08x: ", n); + } - } - DBG_vPrintf(TRACE_BOOTLOADER, "\n"); + DBG_vPrintf(TRACE_BOOTLOADER, " %02x", au8Buffer1[n]); - } + } + DBG_vPrintf(TRACE_BOOTLOADER, "\n"); + + } #endif - return E_STATUS_ERROR; - } - else - { - DBG_vPrintf(TRACE_BOOTLOADER, "Flash erase success\n"); - - if (iVerbosity > 0) + return E_STATUS_ERROR; + } + else { - printf("%c[AErasing: 100%%\n", 0x1B); + DBG_vPrintf(TRACE_BOOTLOADER, "Flash erase success\n"); + + if (iVerbosity > 0) + { + printf("%c[AErasing: 100%%\n", 0x1B); + } } } } @@ -614,41 +690,48 @@ teStatus BL_eReprogram(int iUartFd, tsChipDetails *psChipDetails, tsFW_Info *psF } } - if (iVerbosity > 0) + if((psChipDetails->u32CustomerSettings&0x30) != 0x30) { - printf("Verifying Program in Flash\n\n"); + DBG_vPrintf(TRACE_BOOTLOADER, "Cannot verify Flash, because of CRP\n"); } - - for(n = 0; n < psFWImage->u32ImageLength;) + else { - if((psFWImage->u32ImageLength - n) > 128) - { - u8ChunkSize = 128; - } - else + if (iVerbosity > 0) { - u8ChunkSize = psFWImage->u32ImageLength - n; + printf("Verifying Program in Flash\n\n"); } - if (iBL_ReadFlash(iUartFd, n, u8ChunkSize, au8Buffer1) == -1) - { - printf("Error reading at address 0x%08x\n", n); - return E_STATUS_ERROR; - } - else + for(n = 0; n < psFWImage->u32ImageLength;) { - if (memcmp(psFWImage->pu8ImageData + n, au8Buffer1, u8ChunkSize)) + if((psFWImage->u32ImageLength - n) > 128) + { + u8ChunkSize = 128; + } + else + { + u8ChunkSize = psFWImage->u32ImageLength - n; + } + + if (iBL_ReadFlash(iUartFd, n, u8ChunkSize, au8Buffer1) == -1) { - printf("Verify failed at address 0x%08x!\n", n); + printf("Error reading at address 0x%08x\n", n); return E_STATUS_ERROR; } - } + else + { + if (memcmp(psFWImage->pu8ImageData + n, au8Buffer1, u8ChunkSize)) + { + printf("Verify failed at address 0x%08x!\n", n); + return E_STATUS_ERROR; + } + } - n += u8ChunkSize; + n += u8ChunkSize; - if (iVerbosity > 0) - { - printf("%c[AVerifying: %3d%%\n", 0x1B, (n * 100) / psFWImage->u32ImageLength); + if (iVerbosity > 0) + { + printf("%c[AVerifying: %3d%%\n", 0x1B, (n * 100) / psFWImage->u32ImageLength); + } } } @@ -664,9 +747,11 @@ teStatus BL_eSetBaudrate(int iUartFd, uint32_t u32Baudrate) uint8_t au8Buffer[6]; uint32_t u32Divisor; - // Divide 1MHz clock bu baudrate to get the divisor - u32Divisor = 1000000 / u32Baudrate; - + // Divide 1MHz clock bu baudrate to get the divisor, round to closest + u32Divisor = (1000000+u32Baudrate/2) / u32Baudrate; + + DBG_vPrintf(TRACE_BOOTLOADER, "%s: Actual baud rate set %d\n", __FUNCTION__, 1000000/u32Divisor); + au8Buffer[0] = (uint8_t)u32Divisor; au8Buffer[1] = 0; au8Buffer[2] = 0; @@ -847,7 +932,7 @@ static int iBL_ReadChipId(int iUartFd, uint32_t *pu32ChipId) teBL_Response eResponse = 0; teBL_MessageType eRxType = 0; uint8_t u8RxDataLen = 0; - uint8_t au8Buffer[6]; + uint8_t au8Buffer[256]; // Was 6 bytes, but chip ID response is 11 bytes!!! As the length is given in a byte, this should always work. if(pu32ChipId == NULL) { @@ -1074,7 +1159,7 @@ static int iBL_ReadRAM(int iUartFd, uint32_t u32Address, uint8_t u8Length, uint8 eResponse = eBL_Request(iUartFd, BL_TIMEOUT_1S, E_BL_MSG_TYPE_RAM_READ_REQUEST, 6, au8CmdBuffer, 0, NULL, &eRxType, &u8RxDataLen, pu8Buffer); if(eResponse != E_BL_RESPONSE_OK || eRxType != E_BL_MSG_TYPE_RAM_READ_RESPONSE) { - DBG_vPrintf(TRACE_BOOTLOADER, "%s: Response %02x\n", __FUNCTION__, eResponse); + DBG_vPrintf(TRACE_BOOTLOADER, "%s: @%08x Response %02x\n", __FUNCTION__, u32Address, eResponse); return -1; } @@ -1382,7 +1467,7 @@ static teBL_Response eBL_ReadMessage(int iUartFd, int iTimeoutMicroseconds, teBL iTotalBytesRead += iBytesRead; iAttempts++; - } while((iTotalBytesRead < u8Length) && (iBytesRead > 0 || iAttempts < 10)); + } while((iTotalBytesRead < u8Length) && (iBytesRead > 0 || iAttempts < 256)); // Right now we are receiving the chars one by one. if(iTotalBytesRead != u8Length) { @@ -1407,7 +1492,7 @@ static teBL_Response eBL_ReadMessage(int iUartFd, int iTimeoutMicroseconds, teBL if(u8CalculatedCheckSum != 0x00) { -// DBG_vPrintf(TRACE_BOOTLOADER, "Checksum bad, got %02x expected %02x\n", u8CalculatedCheckSum, 0); + DBG_vPrintf(TRACE_BOOTLOADER, "Checksum bad, got %02x expected %02x\n", u8CalculatedCheckSum, 0); return(E_BL_RESPONSE_CRC_ERROR); } diff --git a/Source/JN51xx_BootLoader.h b/Source/JN51xx_BootLoader.h index 19115a3..854aabe 100644 --- a/Source/JN51xx_BootLoader.h +++ b/Source/JN51xx_BootLoader.h @@ -80,6 +80,8 @@ typedef struct uint32_t u32FlashSize; uint32_t u32BootloaderVersion; + + uint32_t u32CustomerSettings; uint8_t au8MacAddress[8]; } tsChipDetails; diff --git a/Source/main.c b/Source/main.c index 4200dc8..3aaefac 100644 --- a/Source/main.c +++ b/Source/main.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -209,6 +210,21 @@ int main(int argc, char *argv[]) return -1; } + UART_eSetRTS(iUartFd, 1); // nRESET + UART_eSetDTR(iUartFd, 1); // nPROG + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 100000000; // 100 ms + nanosleep(&ts, NULL); + UART_eSetRTS(iUartFd, 0); // nRESET + ts.tv_sec = 0; + ts.tv_nsec = 100000000; // 100 ms + nanosleep(&ts, NULL); + UART_eSetDTR(iUartFd, 0); // nPROG + ts.tv_sec = 0; + ts.tv_nsec = 100000000; // 100 ms + nanosleep(&ts, NULL); + if (iInitialSpeed != iProgramSpeed) { if (iVerbosity > 1) @@ -256,7 +272,8 @@ int main(int argc, char *argv[]) case (CHIP_ID_JN5142_REV1C): pcPartName = "JN5142J01"; break; case (CHIP_ID_JN5168): pcPartName = "JN516x"; break; - + case (CHIP_ID_JN5169): pcPartName = "JN5169"; break; + default: pcPartName = "Unknown"; break; } diff --git a/Source/uart.c b/Source/uart.c index 78a2742..f1b9be0 100644 --- a/Source/uart.c +++ b/Source/uart.c @@ -66,7 +66,11 @@ #include +#ifdef __linux__ #include +#elif defined(__MACH__) && defined(__APPLE__) +#include +#endif #include "uart.h" #include "common.h" @@ -131,9 +135,23 @@ teStatus UART_eInitialise(char *pcDevice, int iBaudRate, int *piFileDescriptor, return E_STATUS_ERROR; } +#ifdef __linux__ psOptions->c_iflag &= ~(INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IUCLC | IXON | IXANY | IXOFF); +#elif defined(__MACH__) && defined(__APPLE__) + psOptions->c_iflag &= ~(INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); +#else +#error "No support for this architecture (yet)" +#endif + psOptions->c_iflag = IGNBRK | IGNPAR; +#ifdef __linux__ psOptions->c_oflag &= ~(OPOST | OLCUC | ONLCR | OCRNL | ONOCR | ONLRET); +#elif defined(__MACH__) && defined(__APPLE__) + psOptions->c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET); +#else +#error "No support for this architecture (yet)" +#endif + psOptions->c_cflag &= ~(CSIZE | CSTOPB | PARENB | CRTSCTS); psOptions->c_cflag |= CS8 | CREAD | HUPCL | CLOCAL; psOptions->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN); @@ -179,38 +197,55 @@ teStatus UART_eClose(int iFileDescriptor) teStatus UART_eSetBaudRate(int iFileDescriptor, struct termios *psOptions, int iBaudRate) { int iBaud; - + +#if (defined(__MACH__) && defined(__APPLE__)) + int bSetNonPOSIXBaudRate = 0; +#endif + DBG_vPrintf(TRACE_UART, "Changing baud rate to %d\n", iBaudRate); switch (iBaudRate) { case 38400: iBaud = B38400; - break; + break; case 115200: iBaud = B115200; - break; + break; case 230400: iBaud = B230400; - break; + break; +#ifdef B460800 case 460800: iBaud = B460800; - break; + break; +#endif +#ifdef B500000 case 500000: iBaud = B500000; - break; + break; +#endif +#ifdef B921600 case 921600: iBaud = B921600; break; +#endif +#ifdef B1000000 case 1000000: iBaud = B1000000; break; - +#endif + default: +#if !(defined(__MACH__) && defined(__APPLE__)) DBG_vPrintf(TRACE_UART, "Unsupported baud rate: %d\n", iBaudRate); return E_STATUS_BAD_PARAMETER; +#else + bSetNonPOSIXBaudRate = 1; + iBaud = B38400; +#endif } - + if(tcflush(iFileDescriptor, TCIOFLUSH) == -1) { DBG_vPrintf(TRACE_UART, "Error flushing uart\n"); @@ -234,10 +269,105 @@ teStatus UART_eSetBaudRate(int iFileDescriptor, struct termios *psOptions, int i DBG_vPrintf(TRACE_UART, "Error changing port settings\n"); return E_STATUS_ERROR; } + +#if defined(__MACH__) && defined(__APPLE__) + + if(bSetNonPOSIXBaudRate) + { + DBG_vPrintf(TRACE_UART, "Trying to set non-POSIX baud rate: %d\n", iBaudRate); + // The IOSSIOSPEED ioctl can be used to set arbitrary baud rates + // other than those specified by POSIX. The driver for the underlying serial hardware + // ultimately determines which baud rates can be used. This ioctl sets both the input + // and output speed. + + speed_t speed = iBaudRate; + if(ioctl(iFileDescriptor, IOSSIOSPEED, &speed) == -1) + { + DBG_vPrintf(TRACE_UART, "Error calling ioctl(..., IOSSIOSPEED, ...) %s(%d).\n", strerror(errno), errno); + return E_STATUS_BAD_PARAMETER; + } + } + +#endif + + return E_STATUS_OK; +} + +/**************************************************************************** + * + * NAME: UART_eSetRTS + * + * DESCRIPTION: + * Set or clear the RTS signal for the specified UART + * + * RETURNS: + * teStatus + * + ****************************************************************************/ +teStatus UART_eSetRTS(int iFileDescriptor, int bValue) +{ + + int status; + + if(ioctl(iFileDescriptor, TIOCMGET, &status) == -1) + { + perror("UART_eSetRTS(): TIOCMGET"); + return E_STATUS_ERROR; + } + if(bValue) + { + status |= TIOCM_RTS; + } + else + { + status &= ~TIOCM_RTS; + } + if(ioctl(iFileDescriptor, TIOCMSET, &status) == -1) + { + perror("UART_eSetRTS(): TIOCMSET"); + return E_STATUS_ERROR; + } return E_STATUS_OK; } +/**************************************************************************** + * + * NAME: UART_eSetDTR + * + * DESCRIPTION: + * Set or clear the DTR signal for the specified UART + * + * RETURNS: + * teStatus + * + ****************************************************************************/ +teStatus UART_eSetDTR(int iFileDescriptor, int bValue) +{ + + int status; + + if(ioctl(iFileDescriptor, TIOCMGET, &status) == -1) + { + perror("UART_eSetDTR(): TIOCMGET"); + return E_STATUS_ERROR; + } + if (bValue) + { + status |= TIOCM_DTR; + } + else + { + status &= ~TIOCM_DTR; + } + if(ioctl(iFileDescriptor, TIOCMSET, &status) == -1) + { + perror("UART_eSetDTR(): TIOCMSET"); + return E_STATUS_ERROR; + } + + return E_STATUS_OK; +} /**************************************************************************** * @@ -313,7 +443,7 @@ teStatus UART_eRead(int iFileDescriptor, int iTimeoutMicroseconds, int iBufferLe } else if (iResult == 0) { - DBG_vPrintf(TRACE_UART, "Timeout reading from UART\n"); + DBG_vPrintf(TRACE_UART, "Timeout reading from UART %.6fs\n", iTimeoutMicroseconds/1000000.); } else { diff --git a/Source/uart.h b/Source/uart.h index 8bf0ba5..efd37f2 100644 --- a/Source/uart.h +++ b/Source/uart.h @@ -77,6 +77,8 @@ extern "C" { teStatus UART_eInitialise(char *pcDevice, int iBaudRate, int *piFileDescriptor, struct termios *psOptions); teStatus UART_eClose(int iFileDescriptor); teStatus UART_eSetBaudRate(int iFileDescriptor, struct termios *psOptions, int iBaudRate); +teStatus UART_eSetRTS(int iFileDescriptor, int bValue); +teStatus UART_eSetDTR(int iFileDescriptor, int bValue); teStatus UART_eFlush(int iFileDescriptor); teStatus UART_eRead(int iFileDescriptor, int iTimeoutMicroseconds, int iBufferLen, uint8_t *pu8Buffer, int *piBytesRead); teStatus UART_eWrite(int iFileDescriptor, uint8_t *pu8Data, int iLength);