mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
Merge pull request #498 from DrDoof/up/tick-block
rtlplayground: run the timed work once per tick
This commit is contained in:
5 files changed
+209
-82
No files matched your search
+110
-81
@@ -88,11 +88,14 @@ __xdata struct uip_eth_addr uip_ethaddr;
|
||||
volatile __xdata uint32_t ticks;
|
||||
volatile __xdata uint8_t sec_counter;
|
||||
volatile __xdata uint16_t sleep_ticks;
|
||||
__xdata uint8_t stp_clock;
|
||||
__xdata uint8_t stp_tick_last;
|
||||
__xdata uint8_t arp_age_secs;
|
||||
extern __xdata struct dhcp_state dhcp_state;
|
||||
|
||||
#define STP_TICK_DIVIDER 3
|
||||
#define STP_TICK_STEP (SYS_TICK_HZ / STP_HZ)
|
||||
#define STP_CATCH_UP 8
|
||||
#define SFP_TICK_STEP 10
|
||||
__xdata uint8_t sfp_tick_last;
|
||||
|
||||
/* Buffer for serial input, SBUF_SIZE must be power of 2 < 256
|
||||
* Writing to this buffer is under the sole control of the serial ISR
|
||||
@@ -134,10 +137,13 @@ __code const uint16_t bit_mask[16] = {
|
||||
|
||||
__xdata uint8_t linkbits_last[4];
|
||||
__xdata uint8_t linkbits_last_p89;
|
||||
volatile __bit link_irq;
|
||||
__xdata uint8_t idle_tick_last;
|
||||
// Last known state of the SFP detection/Loss of Signal pins
|
||||
__xdata bool button_last;
|
||||
__xdata uint8_t button_sec_counter_last;
|
||||
volatile __bit tx_buf_empty;
|
||||
__bit rx_seen;
|
||||
|
||||
|
||||
struct eth_in {
|
||||
@@ -489,14 +495,14 @@ void print_cmd_prompt(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* External IRQ 0 Service Routine: Called on link change?
|
||||
* Note that all registers are being put on the STACK because of calling a subroutine
|
||||
* External IRQ 0 Service Routine: the switch reports a link change. The
|
||||
* register access macros share the SFR data bytes with the main loop, so
|
||||
* the handler only latches the event; idle() reads and clears it.
|
||||
*/
|
||||
void isr_ext0(void) __interrupt(0)
|
||||
{
|
||||
EX0 = 0; // Disable interrupt for the moment
|
||||
IT0 = 1; // Trigger on falling edge of external interrupt
|
||||
EX0 = 1; // Re-enable interrupt
|
||||
EX0 = 0;
|
||||
link_irq = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -991,10 +997,14 @@ void handle_rx(void)
|
||||
__xdata uint8_t budget = RX_BUDGET;
|
||||
|
||||
while (budget--) {
|
||||
// Check the amount of data available on the NIC/ASIC side
|
||||
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
|
||||
if (!SFR_DATA_U16)
|
||||
break;
|
||||
if (rx_seen) {
|
||||
rx_seen = 0;
|
||||
} else {
|
||||
// Check the amount of data available on the NIC/ASIC side
|
||||
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
|
||||
if (!SFR_DATA_U16)
|
||||
break;
|
||||
}
|
||||
reg_read(RTL837X_REG_CPU_RX_CURR_PKT);
|
||||
uint16_t ring_ptr = SFR_DATA_U16;
|
||||
ring_ptr <<= 3;
|
||||
@@ -1169,57 +1179,8 @@ void handle_button(void)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// An idle function that sleeps for 1 tick and does all the house-keeping
|
||||
//
|
||||
void idle(void)
|
||||
void check_links(void)
|
||||
{
|
||||
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
|
||||
if (!SFR_DATA_U16)
|
||||
PCON |= 1;
|
||||
health_loop_start();
|
||||
if (sec_counter >= SYS_TICK_HZ) {
|
||||
sec_counter -= SYS_TICK_HZ;
|
||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||
uint8_t v = sfr_data[3];
|
||||
#ifdef DEBUG
|
||||
print_string(" Tick counter: "); print_long(ticks); write_char('\n');
|
||||
#endif
|
||||
v++;
|
||||
sfr_data[3] = v;
|
||||
if (!v) {
|
||||
v = sfr_data[2];
|
||||
v++;
|
||||
sfr_data[2] = v;
|
||||
if (!v) {
|
||||
v = sfr_data[1];
|
||||
v++;
|
||||
sfr_data[1] = v;
|
||||
if (!v) {
|
||||
v = sfr_data[0];
|
||||
v++;
|
||||
sfr_data[0] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
reg_write_m(RTL837X_REG_SEC_COUNTER);
|
||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||
|
||||
// Check for button presses once a second
|
||||
handle_button();
|
||||
// Age the ARP cache: uip_arp_timer() expects a 10 s cadence
|
||||
if (++arp_age_secs >= 10) {
|
||||
arp_age_secs = 0;
|
||||
uip_arp_timer();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
print_sfr_data();
|
||||
write_char('\n');
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check for Link changes
|
||||
reg_read_m(RTL837X_REG_LINKS_89);
|
||||
__xdata uint8_t linkbits_p89 = sfr_data[3];
|
||||
|
||||
@@ -1252,30 +1213,95 @@ void idle(void)
|
||||
cpy_4(linkbits_last, sfr_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// An idle function that sleeps for 1 tick and does all the house-keeping
|
||||
//
|
||||
static void handle_tick(void)
|
||||
{
|
||||
if (sec_counter >= SYS_TICK_HZ) {
|
||||
sec_counter -= SYS_TICK_HZ;
|
||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||
uint8_t v = sfr_data[3];
|
||||
#ifdef DEBUG
|
||||
print_string(" Tick counter: "); print_long(ticks); write_char('\n');
|
||||
#endif
|
||||
v++;
|
||||
sfr_data[3] = v;
|
||||
if (!v) {
|
||||
v = sfr_data[2];
|
||||
v++;
|
||||
sfr_data[2] = v;
|
||||
if (!v) {
|
||||
v = sfr_data[1];
|
||||
v++;
|
||||
sfr_data[1] = v;
|
||||
if (!v) {
|
||||
v = sfr_data[0];
|
||||
v++;
|
||||
sfr_data[0] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
reg_write_m(RTL837X_REG_SEC_COUNTER);
|
||||
reg_read_m(RTL837X_REG_SEC_COUNTER);
|
||||
|
||||
// Check for button presses once a second
|
||||
handle_button();
|
||||
link_irq = 1;
|
||||
// Age the ARP cache: uip_arp_timer() expects a 10 s cadence
|
||||
if (++arp_age_secs >= 10) {
|
||||
arp_age_secs = 0;
|
||||
uip_arp_timer();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
print_sfr_data();
|
||||
write_char('\n');
|
||||
#endif
|
||||
}
|
||||
|
||||
health_phase(HEALTH_PH_LINK);
|
||||
|
||||
// Check for changes with SFP modules
|
||||
handle_sfp();
|
||||
if (TICKS_DUE(sfp_tick_last, SFP_TICK_STEP)) {
|
||||
sfp_tick_last += SFP_TICK_STEP;
|
||||
handle_sfp();
|
||||
}
|
||||
health_phase(HEALTH_PH_SFP);
|
||||
|
||||
// Check new Packets RX
|
||||
handle_rx();
|
||||
health_phase(HEALTH_PH_RX);
|
||||
// Check UIP for packets to transmit
|
||||
handle_tx();
|
||||
health_phase(HEALTH_PH_TX);
|
||||
// If STP protocol enabled, decrease STP timers to trigger actions
|
||||
if (stp_enabled) {
|
||||
if (!stp_clock) {
|
||||
stp_clock = STP_TICK_DIVIDER;
|
||||
uint8_t n = STP_CATCH_UP;
|
||||
while (n-- && TICKS_DUE(stp_tick_last, STP_TICK_STEP)) {
|
||||
stp_tick_last += STP_TICK_STEP;
|
||||
stp_timers();
|
||||
} else {
|
||||
stp_clock--;
|
||||
}
|
||||
}
|
||||
health_phase(HEALTH_PH_STP);
|
||||
// Check whether a command is waiting in the cmd_buffer and execute
|
||||
}
|
||||
|
||||
|
||||
void idle(void)
|
||||
{
|
||||
reg_read(RTL837X_REG_NIC_RX_BUFF_DATA);
|
||||
rx_seen = SFR_DATA_U16 != 0;
|
||||
if (!rx_seen)
|
||||
PCON |= 1;
|
||||
health_loop_start();
|
||||
if (TICKS_DUE(idle_tick_last, 1)) {
|
||||
idle_tick_last = (uint8_t)ticks;
|
||||
handle_tick();
|
||||
}
|
||||
if (link_irq) {
|
||||
link_irq = 0;
|
||||
REG_SET(RTL837X_ISR_INT_PORT_LINK_CHG, 0x3ff);
|
||||
EX0 = 1;
|
||||
check_links();
|
||||
}
|
||||
health_phase(HEALTH_PH_LINK);
|
||||
handle_rx();
|
||||
health_phase(HEALTH_PH_RX);
|
||||
if (cmd_available) {
|
||||
cmd_available = 0;
|
||||
cmd_tokenize();
|
||||
@@ -1309,12 +1335,13 @@ void reset_chip(void)
|
||||
|
||||
void setup_external_irqs(void)
|
||||
{
|
||||
REG_SET(0x5f84, 0x42);
|
||||
REG_SET(0x5f34, 0x3ff);
|
||||
REG_SET(RTL837X_ISR_SW_INT_MODE, 0x42);
|
||||
REG_SET(RTL837X_ISR_INT_PORT_LINK_CHG, 0x3ff);
|
||||
REG_SET(RTL837X_IMR_INT_PORT_LINK_STS_CHG, 0x3ff);
|
||||
|
||||
// EX0 = 1; // Enable external IRQ 0 (Link-change)
|
||||
EX0 = 0;
|
||||
IT0 = 1; // External IRQ on falling edge
|
||||
link_irq = 1;
|
||||
IT0 = 1; // External IRQ 0 on falling edge (link change)
|
||||
EX0 = 1;
|
||||
|
||||
EX1 = 1; // External IRQ 1 enable
|
||||
EX2 = 1; // External IRQ 2 enable: bit EIE.0
|
||||
@@ -1597,7 +1624,9 @@ void check_and_flash_update_image(void)
|
||||
void main(void)
|
||||
{
|
||||
ticks = 0;
|
||||
stp_clock = STP_TICK_DIVIDER;
|
||||
stp_tick_last = (uint8_t)ticks;
|
||||
idle_tick_last = (uint8_t)ticks;
|
||||
sfp_tick_last = (uint8_t)ticks;
|
||||
dhcp_state.state = DHCP_OFF;
|
||||
sbuf_ptr = 0;
|
||||
|
||||
|
||||
Reference in new issue
Block a user