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

📄 picweb.c

📁 《嵌入式系统 Web 服务器:TCP/IP Lean》
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Check for form arguments in HTTP request string */
void check_formargs(void)
{
    BOOL update=0;
    char c, d, temps[5];
#if PORTBINV
    portval = ~PORTB;               // Read O/P port, just in case
#else
    portval = PORTB;
#endif        
    while (rxout < rxcount)
    {                               // Each arg starts with '?' or '&'
        c = rxbuff[rxout++];
        if (c=='?' || c=='&')
        {                           // Copy string const from ROM to RAM
            strcpy(temps, "hrs=");
            if (match_str(temps))   // ..before matching it
            {
                                    // ..and updating clock value
                update |= get_hexbyte(rtc.b[2]);
                continue;
            }
            strcpy(temps, "min=");  // RTC minutes?
            if (match_str(temps))
            {
                update |= get_hexbyte(rtc.b[1]);
                continue;
            }
            strcpy(temps, "sec=");  // RTC secs?
            if (match_str(temps))
            {
                update |= get_hexbyte(rtc.b[0]);
                continue;
            }                       // O/P port bit change?
            strcpy(temps, "out");
            if (match_str(temps) && get_byte(c) && isdigit(c) &&
                match_byte('=') && get_byte(d) && isdigit(d))
            {
                if (d == '0')       // If off, switch bit on
                    portval |= 1 << (c-'0');
                else                // If on, switch bit off
                    portval &= ~(1 << (c-'0'));  
#if PORTBINV                    
                d = ~portval;       // Update hardware port
                PORTB = d;                                 
#else
                PORTB = portval;
#endif                                
            }
        }
    }
    if (update)                     // Update clock chip if time changed
        set_rtc_time();
}

/* Tx poll: send next SLIP character if possible, adding escape sequences */
#separate
void tx_poll(void)
{
    static BOOL escflag=0;
    BYTE b;

    if (txflag && TX_READY)             // If something to transmit
    {
#if TXDROP
        if (txout==0 && txin>4)         // Check if dropping frames for test
        {
            dropcount++;
            if ((dropcount % TXDROP) == 0)
            {
                txflag = 0;
                txin = txout = 0;
            }
        }
#endif
        if (txout == txin)              // If all RAM headers sent..
        {
            if (txi2c)                  // ..and ROM file to be sent..
            {
                open_file();            // ..open it for O/P
                txout++;
            }
            else                        // All sent: terminate SLIP frame
            {
                putchar(SLIP_END);
                txin = txout = 0;
                txflag = 0;
            }
        }
        else if (txout > txin)          // If sending ROM file
        {
                                        // ..and all sent..
            if (txi2c && !tx_file_byte())
            {                           // ..terminate frame, close file
                putchar(SLIP_END);
                close_file();
                txin = txout = 0;
                txflag = txi2c = 0;
            }
        }
        else                            // If sending RAM header..
        {
            b = read_txbuff(txout);     // ..encode next byte and send it
            if (escflag)
            {                           // Escape char sent, now send value
                putchar(b==SLIP_END ? ESC_END : ESC_ESC);
                txout++;
                escflag = 0;
            }                           // Escape char required
            else if (b==SLIP_END || b==SLIP_ESC)
            {
                putchar(SLIP_ESC);
                escflag = 1;
            }
            else                        // Send byte unmodified
            {
                putchar(b);
                txout++;
            }
        }
    }
}

/* Rx poll: check for modem command, send response */
void rx_poll(void)
{
    if (modemflag && !txflag)
    {
        strcpy(txbuff, "OK\r\n");       // Send OK in response to modem cmd
        txin = 4;
        txout = 0;
        txflag = 1;
        modemflag = 0;
    }                                   // Diagnostic; send index if '?'
    else if (rxbuff[0] == '?' && !txflag)
    {
        rxbuff[0] = rxin = 0;
        romdir.f.name[0] = 0;
        find_file();
        txflag = txi2c = 1;
    }
}

/* Get current time from Real-Time Clock */
void get_rtc_time(void)
{
    int i;

    i2c_start();
    i2c_write(RTC_ADDR);                // i2c address for write cycle
    i2c_write(2);                       // RTC register offset
    i2c_start();
    i2c_write(RTC_ADDR | 1);            // i2c address for read cycle
    for (i=0; i<sizeof(rtc); i++)       // Read bytes
        rtc.b[i] = i2c_read(i<sizeof(rtc)-1);
    i2c_stop();
}

/* Set current time in Real-Time Clock */
void set_rtc_time(void)
{
    int i;

    i2c_start();
    i2c_write(RTC_ADDR);                // i2c address for write cycle
    i2c_write(2);                       // RTC register offset
    for (i=0; i<sizeof(rtc); i++)       // Write bytes
        i2c_write(rtc.b[i]);
    i2c_stop();
}

/* Get current temperature from i2c or sensor */
void get_temperature(void)
{
    i2c_start();
    i2c_write(SENSOR_ADDR | 1);
    temphi = i2c_read(1);
    templo = i2c_read(0);
    i2c_stop();
}

/* Find a filename in ROM filesystem. Return false if not found
** Sets fileidx to 0 if ROM error, 1 if file is first in ROM, 2 if 2nd..
** and leaves directory info in 'romdir'
** If the first byte of name is zero, match first directory entry */
#separate
BOOL find_file(void)
{
    BOOL mismatch=1, end=0;
    int i;
    BYTE b;
    char temps[ROM_FNAMELEN];

    fileidx = 0;                        // Set ROM address pointer to 0
    i2c_start();
    i2c_write(EEROM_ADDR);
    i2c_write(0);
    i2c_write(0);
    i2c_stop();
    do
    {
        i2c_start();                    // Read next directory entry
        i2c_write(EEROM_ADDR | 1);
        if ((romdir.b[0] = i2c_read(1)) == 0xff)
        {                               // Abandon if no entry
            end = 1;
            i2c_read(0);
        }
        else
        {                               // Get file len, ptr, csum and flags
            for (i=1; i<7; i++)
                romdir.b[i] = i2c_read(1);
            mismatch = 0;               // Try matching name
            for (i=0; i<ROM_FNAMELEN; i++)
            {
                temps[i] = b = i2c_read(i<ROM_FNAMELEN-1);
                if (b != romdir.f.name[i])
                    mismatch = 1;
            }
            if (!romdir.f.name[0])      // If null name, match anything
                mismatch = 0;
        }
        i2c_stop();                     // Loop until matched
    } while (!end && fileidx++<MAXFILES && mismatch);
    if (mismatch)
        romdir.f.len = 0;
    return(!mismatch);
}

/* Open the previously-found file for transmission */
BOOL open_file(void)
{
    if (romdir.f.flags & EGI_ATVARS)    // If EGI '@' substitution
    {
        get_rtc_time();                 // ..get time and temperature
        get_temperature();
    }
    if (romdir.f.flags & EGI_HASHVARS)  // If EGI boolean '#' substitution
    {
        hashmask = barmask = 0x80;      // ..reset mask values
#if PORTBINV        
        portval = ~PORTB;               // ..and fetch port value
#else
        portval = PORTB;
#endif                
    }
    i2c_start();
    i2c_write(EEROM_ADDR);              // Write start pointer to eerom
    i2c_write(romdir.f.start >> 8);
    i2c_write(romdir.f.start);
    i2c_stop();
    i2c_start();
    i2c_write(EEROM_ADDR | 1);          // Restart ROM access as read cycle
}

/* Close the previously-opened file */
void close_file(void)
{
    i2c_read(0);                        // Dummy read cycle without ACK
    i2c_stop();
}

/* Transmit a byte from the current i2c file to the SLIP link
** Return 0 when complete file is sent
** If file has EGI flag set, perform run-time variable substitution */
BOOL tx_file_byte(void)
{
    int ret=0, idx;
    BYTE b;

    if (romdir.f.len)                   // Check if any bytes left to send
    {
        b = i2c_read(1);                // Get next byte from ROM
        if ((romdir.f.flags&EGI_ATVARS) && b=='@')
        {                               // If EGI var substitution..
            b = i2c_read(1);            // ..get 2nd byte
            romdir.f.len--;
            inv_byte = b > '@';         // Get variable index
            idx = inv_byte ? 0x50-b : b-0x30;
            if (idx>=0 && idx<=2)       // Index 0-2 are secs, mins, hrs
                printf(tx_byte_inv, "%02X", rtc.b[idx]);
            else if (idx == 3)          // Index 3 is temperature
            {
                printf(tx_byte_inv, "%2u", temphi);
                if (templo & 0x80)
                    printf(tx_byte_inv, ".5");
                else
                    printf(tx_byte_inv, ".0");
                i2c_read(1);            // Discard padding in ROM
                i2c_read(1);
                romdir.f.len -= 2;
            }
            else if (b == '?')          // @? - read input port
            {
                tx_byte('@');
                tx_byte(b);
                hashmask = barmask = 0x20;
                portval = ~PORTA;
            }
            else if (b == '!')          // @! - read output port
            {
                tx_byte('@');
                tx_byte(b);
                hashmask = barmask = 0x80;      
#if PORTBINV                
                portval = ~PORTB;
#else
                portval = PORTB;
#endif  
            }
            else                        // Unrecognised variable
                printf(tx_byte_inv, "??");
        }                               // '#' and '|' are for boolean values
        else if (romdir.f.flags&EGI_HASHVARS && (b=='#' || b=='|'))
        {
            if (b=='#')                 // Replace '|' with '1' or '0'
            {
                tx_byte(portval&hashmask ? '1' : '0');
                hashmask >>= 1;
            }
            else                        // Replace '|' with inverse
            {
                tx_byte(portval&barmask ? '|'+'#'-'1' : '|'+'#'-'0');
                barmask >>= 1;
            }
        }
        else                            // Non-EGI byte; send out unmodified
            tx_byte(b);
        romdir.f.len--;
        ret = 1;
    }
    return(ret);
}

/* Transmit a SLIP byte or its 'inverse' i.e. 80h minus the value
** Use by EGI functions to ensure data and its inverse add up to 80h */
void tx_byte_inv(BYTE b)
{
    tx_byte(inv_byte ? 0x80-b : b);
}

/* Update the current tick count, return non-zero if changed */
BOOL geticks(void)
{
    static unsigned tc, lastc=0;
    BOOL changed=0;

    tc = TIMER_1_HIGH;
    if (tc - lastc >= TIMER1_DIV)
    {
        tickcount++;
        lastc += TIMER1_DIV;
        changed = 1;
    }
    return(changed);
}

/* Check for timeout using the given tick counter */
BOOL timeout(int &var, int tout)
{
    BOOL ret=0;

    if (!tout || tickcount-var>=tout)
    {
        var = tickcount;
        ret = 1;
    }
    return(ret);
}

/* Set the diagnostic LED on or off, refresh its timers */
void setled(BOOL on)
{
    ledon = on;
    output_bit(DIAG_LED, !on);
    timeout(ledonticks, 0);
    timeout(ledoffticks, 0);
}
/* EOF */

⌨️ 快捷键说明

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