📄 picweb.c
字号:
/* 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 + -