void run() { // declare an instance of the USART and the stream that we'll use to write to it _usart=new MyUsart(57600); _outputStream=new UsartPollingOutputStream(*_usart); // declare the RTC that that stack requires. it's used for cache timeouts, DHCP lease expiry // and such like so it does not have to be calibrated for accuracy. A few seconds here or there // over a 24 hour period isn't going to make any difference. Start it ticking at zero which is // some way back in 1970 but that doesn't matter to us Rtc<RtcLsiClockFeature<Rtc32kHzLsiFrequencyProvider>,RtcSecondInterruptFeature> rtc; rtc.setTick(0); // declare an instance of the network stack MyNetworkStack::Parameters params; _net=new MyNetworkStack; // the stack requires the RTC params.base_rtc=&rtc; // It's nice to give the DHCP client a host name because then it'll show up in DHCP // 'active leases' page. In a home router this is often called 'attached devices' params.dhcp_hostname="stm32plus"; // spy on the DHCP announcements for IP address, subnet mask, default gateway and DNS servers // by subscribing to the notification events passed around the network stack. we will // also receive notification that the DHCP lease will be renewed via this event. _net->NetworkNotificationEventSender.insertSubscriber(NetworkNotificationEventSourceSlot::bind(this,&NetDhcpClientTest::onNotification)); // subscribe to error events from the network stack _net->NetworkErrorEventSender.insertSubscriber(NetworkErrorEventSourceSlot::bind(this,&NetDhcpClientTest::onError)); // Initialise the stack. This will reset the PHY, initialise the MAC // and attempt to create a link to our link partner. Ensure your cable // is plugged in when you run this or be prepared to handle the error if(!_net->initialise(params)) error(); // start the ethernet MAC Tx/Rx DMA channels // this will trigger the DHCP transaction if(!_net->startup()) error(); // nothing more to do for(;;); }
/** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. */ int main(void) { if (cleanRegisters()) { Usb usb; Rtc rtc; Settings settings; Control control(settings.getEmitters(), rtc.now()); while (1) { // one second tick if (rtc.tick()) { DateTime now = rtc.now(); control.tick(now); } } } }
void run() { // declare an instance of the USART and the stream that we'll use to write to it _usart=new MyUsart(57600); _outputStream=new UsartPollingOutputStream(*_usart); // declare the RTC that that stack requires. it's used for cache timeouts, DHCP lease expiry // and such like so it does not have to be calibrated for accuracy. A few seconds here or there // over a 24 hour period isn't going to make any difference. Start it ticking at zero which is // some way back in 2000 but that doesn't matter to us Rtc<RtcLsiClockFeature<Rtc32kHzLsiFrequencyProvider>,RtcSecondInterruptFeature> rtc; rtc.setTick(0); // declare an instance of the network stack MyNetworkStack::Parameters params; _net=new MyNetworkStack; // the stack requires the RTC params.base_rtc=&rtc; // It's nice to give the DHCP client a host name because then it'll show up in DHCP // 'active leases' page. In a home router this is often called 'attached devices' params.dhcp_hostname="stm32plus"; // subscribe to error events from the network stack _net->NetworkErrorEventSender.insertSubscriber(NetworkErrorEventSourceSlot::bind(this,&NetHttpClientTest::onError)); // Initialise the stack. This will reset the PHY, initialise the MAC // and attempt to create a link to our link partner. Ensure your cable // is plugged in when you run this or be prepared to handle the error if(!_net->initialise(params)) error(); // start the ethernet MAC Tx/Rx DMA channels // this will trigger the DHCP transaction if(!_net->startup()) error(); // look up the IP address for www.st.com *_outputStream << "Looking up the DNS address for www.st.com\r\n"; IpAddress address; if(!_net->dnsHostnameQuery("www.st.com",address)) { *_outputStream << "Failed to look up www.st.com\r\n"; error(); } *_outputStream << "Connecting to www.st.com:80\r\n"; // create the connection TcpClientConnection *ptr; if(!_net->tcpConnect<TcpClientConnection>(address,80,ptr)) { *_outputStream << "Failed to connect to www.st.com\r\n"; error(); } { // manage the connection pointer in a scoped_ptr so it's automatically deleted (and closed) // when it goes out of scope scoped_ptr<TcpClientConnection> conn(ptr); HttpClient httpClient(*conn); // set the parameters for the HTTP GET httpClient.setUri("/"); // get the root document httpClient.setHost("www.st.com"); // host header is mandatory for HTTP/1.1 // send it *_outputStream << "Sending request to server\r\n"; if(!httpClient.sendRequest()) { *_outputStream << "Failed to send the request to the server\r\n"; error(); } // must have a content-length for this test call int32_t contentLength; if((contentLength=httpClient.getResponseContentLength())==-1) { *_outputStream << "Server did not send a Content-Length header\r\n"; error(); } // read back the response in 100 byte chunks with a 60 second timeout uint8_t buffer[100]; uint32_t actuallyRead; *_outputStream << "Reading response body from the server\r\n"; while(contentLength) { // read a chunk if(!conn->receive(buffer,Min(contentLength,100L),actuallyRead,60000)) { *_outputStream << "Timed out waiting for data from the server\r\n"; error(); } if(actuallyRead==0) { *_outputStream << "The remote end has closed the connection\r\n"; error(); } // push out to the USART _outputStream->write(buffer,actuallyRead); // decrease amount remaining contentLength-=actuallyRead; } *_outputStream << "Finished reading response body\r\n"; } // finished, reset the board to try again for(;;); }
void run() { // nothing arrived yet _datagramArrived=false; // declare an instance of the USART and the stream that we'll use to write to it _usart=new MyUsart(57600); UsartPollingOutputStream usartStream(*_usart); _outputStream=new TextOutputStream(usartStream); // declare the RTC that that stack requires. it's used for cache timeouts, DHCP lease expiry // and such like so it does not have to be calibrated for accuracy. A few seconds here or there // over a 24 hour period isn't going to make any difference. Start it ticking at zero which is // some way back in 2000 but that doesn't matter to us Rtc<RtcLsiClockFeature<Rtc32kHzLsiFrequencyProvider>,RtcSecondInterruptFeature> rtc; rtc.setTick(0); // declare an instance of the network stack MyNetworkStack::Parameters params; _net=new MyNetworkStack; // the stack requires the RTC params.base_rtc=&rtc; // It's nice to give the DHCP client a host name because then it'll show up in DHCP // 'active leases' page. In a home router this is often called 'attached devices' params.dhcp_hostname="stm32plus"; // subscribe to error events from the network stack _net->NetworkErrorEventSender.insertSubscriber(NetworkErrorEventSourceSlot::bind(this,&NetUdpReceiveAsyncTest::onError)); // subscribe to incoming datagrams from the UDP module _net->UdpReceiveEventSender.insertSubscriber(UdpReceiveEventSourceSlot::bind(this,&NetUdpReceiveAsyncTest::onReceive)); // Initialise the stack. This will reset the PHY, initialise the MAC // and attempt to create a link to our link partner. Ensure your cable // is plugged in when you run this or be prepared to handle the error if(!_net->initialise(params)) error(); // start the ethernet MAC Tx/Rx DMA channels // this will trigger the DHCP transaction if(!_net->startup()) error(); for(;;) { char buffer[20]; if(_datagramArrived) { // a datagram has been received, print the address of the sender const_cast<IpAddress&>(_remoteAddress).toString(buffer); *(_outputStream) << "From: " << buffer << ": "; // now print out the first 10 bytes for(uint16_t i=0;i<_datagramDataSize;i++) (*_outputStream) << (uint16_t) _datagramData[i] << " "; (*_outputStream) << "\r\n"; // ready for another _datagramArrived=false; } } }
void run() { // reset state _linkStatusChanged=false; // declare an instance of the USART and the stream that we'll use to write to it _usart=new MyUsart(57600); _outputStream=new UsartPollingOutputStream(*_usart); // declare the RTC that that stack requires. it's used for cache timeouts, DHCP lease expiry // and such like so it does not have to be calibrated for accuracy. A few seconds here or there // over a 24 hour period isn't going to make any difference. Rtc<RtcLsiClockFeature<Rtc32kHzLsiFrequencyProvider>,RtcSecondInterruptFeature> rtc; rtc.setTick(0); // declare an instance of the network stack MyNetworkStack::Parameters params; _net=new MyNetworkStack; params.base_rtc=&rtc; // declare our IP address and subnet mask params.staticip_address="192.168.0.10"; params.staticip_subnetMask="255.255.255.0"; params.staticip_defaultGateway="192.168.0.1"; // Initialise the stack. This will reset the PHY, initialise the MAC // and attempt to create a link to our link partner. Ensure your cable // is plugged in when you run this or be prepared to handle the error if(!_net->initialise(params)) error(); // we'd like to be notified when there's a change in the link status so configure the // PHY interrupt mask to report that change. My development board has the PHY interrupt // line on PB14 so we'll need an active-low EXTI configured for that GpioB<DefaultDigitalInputFeature<14> > pb; Exti14 exti(EXTI_Mode_Interrupt,EXTI_Trigger_Falling,pb[14]); exti.ExtiInterruptEventSender.insertSubscriber( ExtiInterruptEventSourceSlot::bind(this,&NetPingClientTest::onLinkStatusChange) ); if(!_net->phyEnableInterrupts(DP83848C::INTERRUPT_LINK_STATUS_CHANGE)) error(); // subscribe to error events from the network stack _net->NetworkErrorEventSender.insertSubscriber(NetworkErrorEventSourceSlot::bind(this,&NetPingClientTest::onError)); // start the ethernet MAC Tx/Rx DMA channels if(!_net->startup()) error(); for(;;) { char buf[20]; uint32_t elapsed; // send a ping every 2 seconds if(_net->ping("192.168.1.2",elapsed)) { StringUtil::modp_uitoa10(elapsed,buf); *_outputStream << "Reply received in " << buf << "ms.\r\n"; } else *_outputStream << "Timed out waiting for a reply\r\n"; MillisecondTimer::delay(1000); // check on the link state if(_linkStatusChanged) { *_outputStream << "The link state changed\r\n"; _linkStatusChanged=false; } } }
void run() { // declare an instance of the USART and the stream that we'll use to write to it _usart=new MyUsart(57600); _outputStream=new UsartPollingOutputStream(*_usart); // declare the RTC that that stack requires. it's used for cache timeouts, DHCP lease expiry // and such like so it does not have to be calibrated for accuracy. A few seconds here or there // over a 24 hour period isn't going to make any difference. Start it ticking at zero which is // some way back in 2000 but that doesn't matter to us Rtc<RtcLsiClockFeature<Rtc32kHzLsiFrequencyProvider>,RtcSecondInterruptFeature> rtc; rtc.setTick(0); // declare an instance of the network stack MyNetworkStack::Parameters params; _net=new MyNetworkStack; // the stack requires the RTC params.base_rtc=&rtc; // It's nice to give the DHCP client a host name because then it'll show up in DHCP // 'active leases' page. In a home router this is often called 'attached devices' params.dhcp_hostname="stm32plus"; // subscribe to error events from the network stack _net->NetworkErrorEventSender.insertSubscriber(NetworkErrorEventSourceSlot::bind(this,&NetTcpClientTest::onError)); // Initialise the stack. This will reset the PHY, initialise the MAC // and attempt to create a link to our link partner. Ensure your cable // is plugged in when you run this or be prepared to handle the error if(!_net->initialise(params)) error(); // start the ethernet MAC Tx/Rx DMA channels // this will trigger the DHCP transaction if(!_net->startup()) error(); *_outputStream << "The TCP client is ready to run\r\n"; TcpClientConnection *ptr; uint32_t actuallyReceived,actuallySent; char buffer[100]; for(;;) { // connect to the remote end using a random local ephemeral port if(_net->tcpConnect<TcpClientConnection>("192.168.1.3",12345,ptr)) { // manage the connection pointer in a scoped_ptr so it's automatically deleted (and closed) // when it goes out of scope scoped_ptr<TcpClientConnection> conn(ptr); // send 11 bytes of text and a newline to the other end (blocking). We have to copy the data to // a sram buffer before sending because the STM32 Ethernet DMA peripheral cannot transmit from // flash memory. (string constants are compiled into flash). strcpy(buffer,"Hello World\n"); if(conn->send(buffer,12,actuallySent) && actuallySent==12) { // receive the response line from the other end (blocking) if(conn->receive(buffer,100,actuallyReceived) && actuallyReceived>0) { // write the response to the USART stream _outputStream->write(buffer,actuallyReceived); } } } else *_outputStream << "Timed out while trying to connect, trying again...\r\n"; // pause for 5 seconds to avoid flooding the network before doing it again MillisecondTimer::delay(5000); } }