int IOButtonState(int io) { DWORD tdebounce2; tdebounce2 = TickGetDiv256(); if ((tdebounce2-tdebounce1)>5) { io = io - 1; int stat; stat = Status [io]; if (IOGet(io+1) > stat) { if (IOMode[io] == 2) { tdebounce1 = TickGetDiv256(); return 1; } else { tdebounce1 = TickGetDiv256(); return 2; } } if (IOGet(io+1) < stat) { if (IOMode[io] == 2) { tdebounce1 = TickGetDiv256(); return 2; } else { tdebounce1 = TickGetDiv256(); return 1; } } if (stat == Status[io]) return 0; return -1; } return 0; }
/****************************************************************************** * Function: void MACFlush(void) * * PreCondition: A packet has been created by calling MACPut() and * MACPutHeader(). * * Input: None * * Output: None * * Side Effects: None * * Overview: MACFlush causes the current TX packet to be sent out on * the Ethernet medium. The hardware MAC will take control * and handle CRC generation, collision retransmission and * other details. * * Note: After transmission completes (MACIsTxReady() returns TRUE), * the packet can be modified and transmitted again by calling * MACFlush() again. Until MACPutHeader() or MACPut() is * called (in the TX data area), the data in the TX buffer * will not be corrupted. *****************************************************************************/ void MACFlush(void) { // Reset the Ethernet TX logic. This is an errata workaround to // prevent the TXRTS bit from getting stuck set indefinitely, causing the // stack to lock up under certain bad conditions. ECON1bits.TXRST = 1; ECON1bits.TXRST = 0; // Wait at least 1.6us after TX Reset before setting TXRTS. // If you don't wait long enough, the TX logic won't be finished resetting. { volatile BYTE i = 8; while (i--); } EIRbits.TXERIF = 0; // Since we are about to transmit something (which usually results in RX // traffic), start a timer to look for RX traffic and control RX polarity // swapping. #if defined(ETH_RX_POLARITY_SWAP_TRIS) { // See if we have received a packet already or not. If we haven't the // RX polarity may not be correct. if (!flags.bits.bRXPolarityValid) { // See if we transmitted a packet and twidled with the polarity // already in the last 429ms. if (!flags.bits.bRXPolarityTimerOnTX) { // Reset the timer and swap the polarity wRXPolarityTimer = (WORD) TickGetDiv256(); flags.bits.bRXPolarityTimerOnTX = 1; if (flags.bits.bRXPolarityAtNextTX) ETH_RX_POLARITY_SWAP_IO = 1; else ETH_RX_POLARITY_SWAP_IO = 0; flags.bits.bRXPolarityAtNextTX ^= 1; // Swap for next time } } } #endif // Start the transmission // After transmission completes (MACIsTxReady() returns TRUE), the packet // can be modified and transmitted again by calling MACFlush() again. // Until MACPutHeader() is called, the data in the TX buffer will not be // corrupted. ECON1bits.TXRTS = 1; wTXWatchdog = clock_time(); }
/****************************************************************************** Function: void UDPTask(void) Summary: Performs periodic UDP tasks. Description: This function performs any required periodic UDP tasks. Each socket's state machine is checked, and any elapsed timeout periods are handled. Precondition: UDP is initialized. Parameters: None Returns: None ******************************************************************************/ void UDPTask(void) { UDP_SOCKET ss; for ( ss = 0; ss < MAX_UDP_SOCKETS; ss++ ) { // need to put Extra check if UDP has opened or NOT if((UDPSocketInfo[ss].smState == UDP_OPENED) || (UDPSocketInfo[ss].smState == UDP_CLOSED)) continue; // A timeout has occured. Respond to this timeout condition // depending on what state this socket is in. switch(UDPSocketInfo[ss].smState) { #if defined(STACK_CLIENT_MODE) #if defined(STACK_USE_DNS) case UDP_DNS_RESOLVE: if(DNSBeginUsage()) { // call DNS Resolve function and move to UDP next State machine UDPSocketInfo[ss].smState = UDP_DNS_IS_RESOLVED; if(UDPSocketInfo[ss].flags.bRemoteHostIsROM) DNSResolveROM((ROM BYTE*)(ROM_PTR_BASE)UDPSocketInfo[ss].remote.remoteHost, DNS_TYPE_A); else DNSResolve((BYTE*)(PTR_BASE)UDPSocketInfo[ss].remote.remoteHost, DNS_TYPE_A); } break; case UDP_DNS_IS_RESOLVED: { IP_ADDR ipResolvedDNSIP; // See if DNS resolution has finished. Note that if the DNS // fails, the &ipResolvedDNSIP will be written with 0x00000000. // MyTCB.remote.dwRemoteHost is unioned with // MyTCB.remote.niRemoteMACIP.IPAddr, so we can't directly write // the DNS result into MyTCB.remote.niRemoteMACIP.IPAddr. We // must copy it over only if the DNS is resolution step was // successful. if(DNSIsResolved(&ipResolvedDNSIP)) { if(DNSEndUsage()) { UDPSocketInfo[ss].remote.remoteNode.IPAddr.Val = ipResolvedDNSIP.Val; UDPSocketInfo[ss].smState = UDP_GATEWAY_SEND_ARP; UDPSocketInfo[ss].retryCount = 0; UDPSocketInfo[ss].retryInterval = (TICK_SECOND/4)/256; } else { UDPSocketInfo[ss].smState = UDP_DNS_RESOLVE; } } } break; #endif // #if defined(STACK_USE_DNS) case UDP_GATEWAY_SEND_ARP: // Obtain the MAC address associated with the server's IP address //(either direct MAC address on same subnet, or the MAC address of the Gateway machine) UDPSocketInfo[ss].eventTime = (WORD)TickGetDiv256(); ARPResolve(&UDPSocketInfo[ss].remote.remoteNode.IPAddr); UDPSocketInfo[ss].smState = UDP_GATEWAY_GET_ARP; break; case UDP_GATEWAY_GET_ARP: if(!ARPIsResolved(&UDPSocketInfo[ss].remote.remoteNode.IPAddr, &UDPSocketInfo[ss].remote.remoteNode.MACAddr)) { // Time out if too much time is spent in this state // Note that this will continuously send out ARP // requests for an infinite time if the Gateway // never responds if((WORD)TickGetDiv256() - UDPSocketInfo[ss].eventTime> (WORD)UDPSocketInfo[ss].retryInterval) { // Exponentially increase timeout until we reach 6 attempts then stay constant if(UDPSocketInfo[ss].retryCount < 6u) { UDPSocketInfo[ss].retryCount++; UDPSocketInfo[ss].retryInterval <<= 1; } // Retransmit ARP request UDPSocketInfo[ss].smState = UDP_GATEWAY_SEND_ARP; } } else { UDPSocketInfo[ss].smState = UDP_OPENED; } break; default: case UDP_OPENED: case UDP_CLOSED: // not used break; #endif // #if defined(STACK_CLIENT_MODE) } } }
int main(void) #endif { static TICK t = 0; TICK nt = 0; //TICK is DWORD, thus 32 bits BYTE loopctr = 0; //ML Debugging WORD lloopctr = 14; //ML Debugging static DWORD dwLastIP = 0; // Initialize interrupts and application specific hardware InitializeBoard(); // Initialize and display message on the LCD LCDInit(); DelayMs(100); DisplayString (0,"Olimex"); //first arg is start position on 32 pos LCD // Initialize Timer0, and low priority interrupts, used as clock. TickInit(); // Initialize Stack and application related variables in AppConfig. InitAppConfig(); // Initialize core stack layers (MAC, ARP, TCP, UDP) and // application modules (HTTP, SNMP, etc.) StackInit(); // Now that all items are initialized, begin the co-operative // multitasking loop. This infinite loop will continuously // execute all stack-related tasks, as well as your own // application's functions. Custom functions should be added // at the end of this loop. // Note that this is a "co-operative multi-tasking" mechanism // where every task performs its tasks (whether all in one shot // or part of it) and returns so that other tasks can do their // job. // If a task needs very long time to do its job, it must be broken // down into smaller pieces so that other tasks can have CPU time. while(1) { // Blink LED0 (right most one) every second. nt = TickGetDiv256(); if((nt - t) >= (DWORD)(TICK_SECOND/1024ul)) { t = nt; LED0_IO ^= 1; ClrWdt(); //Clear the watchdog } // This task performs normal stack task including checking // for incoming packet, type of packet and calling // appropriate stack entity to process it. StackTask(); // This tasks invokes each of the core stack application tasks StackApplications(); // Process application specific tasks here. // If the local IP address has changed (ex: due to DHCP lease change) // write the new IP address to the LCD display, UART, and Announce // service if(dwLastIP != AppConfig.MyIPAddr.Val) { dwLastIP = AppConfig.MyIPAddr.Val; #if defined(__SDCC__) DisplayIPValue(dwLastIP); // must be a WORD: sdcc does not // pass aggregates #else DisplayIPValue(AppConfig.MyIPAddr); #endif } }//end of while(1) }//end of main()