⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpc21isp.c

📁 NXP公司的arm系列芯片LPCXXXX的ISP烧写程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
} TARGET;

typedef struct
{
    unsigned long id;
    unsigned Product;
    unsigned FlashSize;     /* in kiB, for informational purposes only */
    unsigned RAMSize;       /* in kiB, for informational purposes only */
    unsigned FlashSectors;  /* total number of sectors */
    unsigned MaxCopySize;   /* maximum size that can be copied to Flash in a single command */
    const int *SectorTable; /* pointer to a sector table with constant the sector sizes */
} LPC_DEVICE_TYPE;

typedef struct
{

#if !defined COMPILE_FOR_LPC21
    TARGET micro;                      /**< The type of micro that will be
                                         * programmed.                           */
    int debug_level;
    unsigned char TerminalAfterUpload;
    unsigned char FormatHex;
    unsigned char ControlLines;
    unsigned char LogFile;
    char *input_file;                   /**< Name of the file to get input from. */
    char *serial_port;                  /**< Name of the serial port to use to
                                         * communicate with the microcontroller.
                                         * Read from the command line.          */

#endif // !defined COMPILE_FOR_LPC21
    unsigned char TerminalOnly;
    unsigned char DetectOnly;
    unsigned char WipeDevice;
    unsigned char LocalEcho;
    unsigned char Verify;
    int           DetectedDevice;       /* index in LPCtypes[] array */
    char *baud_rate;                    /**< Baud rate to use on the serial
                                         * port communicating with the
                                         * microcontroller. Read from the
                                         * command line.                        */

    char StringOscillator[6];           /**< Holds representation of oscillator
                                          * speed from the command line.         */
    BINARY *BinaryContent;              /**< Binary image of the                 */
                                        /* microcontroller's memory.             */
    unsigned long BinaryLength;
    unsigned long BinaryOffset;
    unsigned long StartAddress;

#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
    HANDLE hCom;
#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN

#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
    int fdCom;
#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21

#if defined COMPILE_FOR_LINUX
    struct termios oldtio, newtio;
#endif // defined COMPILE_FOR_LINUX

    unsigned serial_timeout_count;   /**< Local used to track
                                      * timeouts on serial port read. */

} ISP_ENVIRONMENT;


static void DumpString(int level, const void *s, size_t size, const char *prefix_string);
static void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s);
static void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment, void *Answer, unsigned long MaxSize, unsigned long *RealSize, unsigned long WantedNr0x0A,unsigned timeOutMilliseconds);
static void PhilipsOutputErrorMessage(unsigned char ErrorNumber);
static unsigned char GetErrorNumber(const char *Answer);
static void SerialTimeoutSet(ISP_ENVIRONMENT *IspEnvironment, unsigned timeout_milliseconds);
static void SerialTimeoutTick(ISP_ENVIRONMENT *IspEnvironment);
static int SerialTimeoutCheck(ISP_ENVIRONMENT *IspEnvironment);

#if !defined COMPILE_FOR_LPC21

static int debug_level = 2;

static void DebugPrintf( int level, const char *fmt, ...);
static void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment);
static void ControlModemLines(ISP_ENVIRONMENT *IspEnvironment, unsigned char DTR, unsigned char RTS);
static unsigned char Ascii2Hex(unsigned char c);
#endif

static const int SectorTable_210x[] = { 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
                                        8192, 8192, 8192, 8192, 8192, 8192, 8192 };
static const int SectorTable_2103[] = { 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096 };
static const int SectorTable_211x[] = { 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
                                        8192, 8192, 8192, 8192, 8192, 8192, 8192, };
static const int SectorTable_212x[] = { 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
                                        65536, 65536, 8192, 8192, 8192, 8192, 8192, 8192,
                                        8192 };
static const int SectorTable_213x[] = { 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
                                        32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
                                        32768, 32768, 32768, 32768, 32768, 32768, 4096, 4096,
                                        4096, 4096, 4096 };
static int SectorTable_RAM[]  = { 65000 };

static LPC_DEVICE_TYPE LPCtypes[] =
{
  { 0, 0, 0 },  /* unknown */
  { 0x0004FF11, 2103,  32,  8,  8, 4096, SectorTable_2103 },
  { 0xFFF0FF12, 2104, 128, 16, 15, 8192, SectorTable_210x },
  { 0xFFF0FF22, 2105, 128, 32, 15, 8192, SectorTable_210x },
  { 0xFFF0FF32, 2106, 128, 64, 15, 8192, SectorTable_210x },
  { 0x0101FF12, 2114, 128, 16, 15, 8192, SectorTable_211x },
  { 0x0201FF12, 2119, 128, 16, 15, 8192, SectorTable_211x },
  { 0x0101FF13, 2124, 256, 16, 17, 8192, SectorTable_212x },
  { 0x0201FF13, 2129, 256, 16, 17, 8192, SectorTable_212x },
  { 0x0002FF01, 2131,  32,  8,  8, 4096, SectorTable_213x },
  { 0x0002FF11, 2132,  64, 16,  9, 4096, SectorTable_213x },
  { 0x0002FF12, 2134, 128, 16, 11, 4096, SectorTable_213x },
  { 0x0002FF23, 2136, 256, 32, 15, 4096, SectorTable_213x },
  { 0x0002FF25, 2138, 512, 32, 27, 4096, SectorTable_213x },
  { 0x0402FF01, 2141,  32,  8,  8, 4096, SectorTable_213x },
  { 0x0402FF11, 2142,  64, 16,  9, 4096, SectorTable_213x },
  { 0x0402FF12, 2144, 128, 16, 11, 4096, SectorTable_213x },
  { 0x0402FF23, 2146, 256, 40, 15, 4096, SectorTable_213x },
  { 0x0402FF25, 2148, 512, 40, 27, 4096, SectorTable_213x },
  { 0x0301FF13, 2194, 256, 16, 17, 8192, SectorTable_212x },
  { 0x0301FF12, 2210,   0, 16,  0, 8192, SectorTable_211x }, /* table is a "don't care" */
  { 0x0401FF12, 2212, 128, 16, 15, 8192, SectorTable_211x },
  { 0x0601FF13, 2214, 256, 16, 17, 8192, SectorTable_212x },
  /*            2290; same id as the LPC2210 */
  { 0x0401FF13, 2292, 256, 16, 17, 8192, SectorTable_212x },
  { 0x0501FF13, 2294, 256, 16, 17, 8192, SectorTable_212x },
  { 0x0603FB02, 2364, 128, 34, 11, 4096, SectorTable_213x },
  { 0x0603FB23, 2366, 256, 58, 15, 4096, SectorTable_213x },
  { 0x0603FB25, 2368, 512, 58, 27, 4096, SectorTable_213x },
  { 0x0703FF25, 2378, 512, 58, 27, 4096, SectorTable_213x },
  { 0x0503FF35, 2458, 512, 98, 27, 4096, SectorTable_213x },
  { 0x0603FF35, 2468, 512, 98, 27, 4096, SectorTable_213x }
};

/************* Portability layer. Serial and console I/O differences    */
/* are taken care of here.                                              */

#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
static int kbhit( void);
static int getch( void);
#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN

static void PrepareKeyboardTtySettings(void);
static void ResetKeyboardTtySettings(void);

#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
struct termios keyboard_origtty;
#endif


#if defined COMPILE_FOR_LINUX
static void Sleep(unsigned long MilliSeconds);
#endif // defined COMPILE_FOR_LINUX



#if !defined COMPILE_FOR_LPC21
static void OpenSerialPort(ISP_ENVIRONMENT *IspEnvironment)
{
    // Open COM-Port (different between Windows and Linux)

#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
    DCB    dcb;
    COMMTIMEOUTS commtimeouts;

    IspEnvironment->hCom = CreateFile(IspEnvironment->serial_port, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

    if(IspEnvironment->hCom == INVALID_HANDLE_VALUE)
    {
        DebugPrintf( 1, "Can't open COM-Port %s ! - Error: %ld\n", IspEnvironment->serial_port, GetLastError());
        exit(2);
    }

    DebugPrintf( 3, "COM-Port %s opened...\n", IspEnvironment->serial_port);

    GetCommState(IspEnvironment->hCom, &dcb);
    dcb.BaudRate    = atol(IspEnvironment->baud_rate);
    dcb.ByteSize    = 8;
    dcb.StopBits    = ONESTOPBIT;
    dcb.Parity      = NOPARITY;
    dcb.fDtrControl = DTR_CONTROL_DISABLE;
    dcb.fOutX       = FALSE;
    dcb.fInX        = FALSE;
    dcb.fNull       = FALSE;
    dcb.fRtsControl = RTS_CONTROL_DISABLE;
    if(SetCommState(IspEnvironment->hCom, &dcb) == 0)
    {
        DebugPrintf( 1, "Can't set baudrate %s ! - Error: %ld", IspEnvironment->baud_rate, GetLastError());
        exit(3);
    }

    SetCommMask(IspEnvironment->hCom,EV_RXCHAR | EV_TXEMPTY);

    commtimeouts.ReadIntervalTimeout         = MAXDWORD;
    commtimeouts.ReadTotalTimeoutMultiplier  =    0;
    commtimeouts.ReadTotalTimeoutConstant    =    1;
    commtimeouts.WriteTotalTimeoutMultiplier =    0;
    commtimeouts.WriteTotalTimeoutConstant   =    0;
    SetCommTimeouts(IspEnvironment->hCom, &commtimeouts);

#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN

#if defined COMPILE_FOR_LINUX

    IspEnvironment->fdCom = open(IspEnvironment->serial_port, O_RDWR | O_NOCTTY | O_NONBLOCK );

    if(IspEnvironment->fdCom < 0)
    {
        DebugPrintf( 1, "Can't open COM-Port %s !\n", IspEnvironment->serial_port);
        exit(2);
    }

    DebugPrintf( 3, "COM-Port %s opened...\n", IspEnvironment->serial_port);

    /* clear input & output buffers, then switch to "blocking mode" */
    tcflush(IspEnvironment->fdCom, TCOFLUSH);
    tcflush(IspEnvironment->fdCom, TCIFLUSH);
    fcntl(IspEnvironment->fdCom, F_SETFL, fcntl(IspEnvironment->fdCom, F_GETFL) & ~O_NONBLOCK);

    tcgetattr(IspEnvironment->fdCom, &IspEnvironment->oldtio); /* save current port settings */

    bzero(&IspEnvironment->newtio, sizeof(IspEnvironment->newtio));
    IspEnvironment->newtio.c_cflag = CS8 | CLOCAL | CREAD;

#ifdef __APPLE__
#define NEWTERMIOS_SETBAUDARTE(bps) IspEnvironment->newtio.c_ispeed = IspEnvironment->newtio.c_ospeed = bps;
#else
#define NEWTERMIOS_SETBAUDARTE(bps) IspEnvironment->newtio.c_cflag |= bps;
#endif

    switch(atol(IspEnvironment->baud_rate))
    {
#ifdef B1152000
        case 1152000: NEWTERMIOS_SETBAUDARTE( B1152000 ); break;
#endif // B1152000
#ifdef B576000
        case  576000: NEWTERMIOS_SETBAUDARTE( B576000 ); break;
#endif // B576000
#ifdef B230400
        case  230400: NEWTERMIOS_SETBAUDARTE( B230400 ); break;
#endif // B230400
#ifdef B115200
        case  115200: NEWTERMIOS_SETBAUDARTE( B115200 ); break;
#endif // B115200
#ifdef B57600
        case   57600: NEWTERMIOS_SETBAUDARTE( B57600 ); break;
#endif // B57600
#ifdef B38400
        case   38400: NEWTERMIOS_SETBAUDARTE( B38400 ); break;
#endif // B38400
#ifdef B19200
        case   19200: NEWTERMIOS_SETBAUDARTE( B19200 ); break;
#endif // B19200
#ifdef B9600
        case    9600: NEWTERMIOS_SETBAUDARTE( B9600 ); break;
#endif // B9600
        default:
        {
            DebugPrintf( 1, "unknown baudrate %s\n", IspEnvironment->baud_rate);
            exit(3);
        }
    }

    IspEnvironment->newtio.c_iflag = IGNPAR | IGNBRK | IXON | IXOFF;
    IspEnvironment->newtio.c_oflag = 0;

    /* set input mode (non-canonical, no echo,...) */
    IspEnvironment->newtio.c_lflag = 0;

    cfmakeraw(&IspEnvironment->newtio);
    IspEnvironment->newtio.c_cc[VTIME]    = 1;   /* inter-character timer used */
    IspEnvironment->newtio.c_cc[VMIN]     = 0;   /* blocking read until 0 chars received */

    tcflush(IspEnvironment->fdCom, TCIFLUSH);
    tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->newtio);

#endif // defined COMPILE_FOR_LINUX
}

static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment)
{
#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN

    CloseHandle(IspEnvironment->hCom);

#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN

#if defined COMPILE_FOR_LINUX

    tcflush(IspEnvironment->fdCom, TCOFLUSH);
    tcflush(IspEnvironment->fdCom, TCIFLUSH);
    tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->oldtio);

    close(IspEnvironment->fdCom);

#endif // defined COMPILE_FOR_LINUX
}

#endif // !defined COMPILE_FOR_LPC21

/***************************** SendComPortBlock *************************/
/**  Sends a block of bytes out the opened com port.
\param [in] s block to send.
\param [in] n size of the block.
*/
static void SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n)
{
#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN

    unsigned long realsize;

#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN

    DumpString( 4, s, n, "Sending ");

#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN

    WriteFile(IspEnvironment->hCom, s, n, &realsize, NULL);

#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN

#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21

    write(IspEnvironment->fdCom, s, n);

#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -