Yeah, the SYSTEM_MODE flag is documented on the wiki on the
API reference page. As are the Oak specific function calls.
The Oak is mean to make it so you don't have to think about the wifi config at all (as is the Photon)... but since that isn't always what the user wants, the SYSTEM_MODE flag exists so that you can specify that it be automatic (default), semi-automatic (user manages particle connect/disconnect, wifi remains automatically connecting, but user manageable also) and manual (user code manages wifi and particle connections). I've done some stuff that does the semi-automatic wifi/particle management, but hadn't needed to do fully manual control yet.
re: SPI clock pin, that would be P9, per the Oak silkscreen. Don't know if it's "dedicated" or merely the default pin...
I'm trialling this code which makes it so the WiFi is enabled only when the NTP time request is called... and runs a single neopixel in the meantime. It seems to be working... the main loop is running at a steady 5120-5121 milliseconds per cycle (i.e. the animation takes around 5120 milliseconds to complete), and then there is a nearly double that (around 9134 millisecond - but will be variable as it is dependent on how quickly the wifi connects and the NTP request processes) loop when the wifi kicks in every five minutes for the time sync. Obviously it doesn't need to be that frequent... and is easily changed by simply updating the time sync interval variable. Just makes it more likely that if the wifi code makes it fail, it should do it a bit quicker

Edit: btw, both the P1 led blink and the 1 neopixel blinker have survived their first 24 hours and are still running fine. So that's two Oaks both doing NTP lookups every 5 minutes with particle and wifi on auto, and no lockups/failures (yet!)
/*
Time_NTP_manageWifi_NeoPixel
This sketch uses the ESP8266WiFi, WiFiUdp, Time and Adafruit_NeoPixel libraries
Code examples mashed together 2016 Peter Feerick
*/
SYSTEM_MODE(MANUAL)
// Which pin on the Oak is connected to the NeoPixels?
#define PIN 6
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 1
#define DEBUG
#define DEBUG_OI Serial
#ifdef DEBUG
#define DebugBegin(...) DEBUG_OI.begin(__VA_ARGS__)
#define DebugPrint(...) DEBUG_OI.print(__VA_ARGS__)
#define DebugPrintln(...) DEBUG_OI.println(__VA_ARGS__)
#else
// Define the counterparts that cause the compiler to generate no code
#define DebugBegin(...) (void(0))
#define DebugPrint(...) (void(0))
#define DebugPrintln(...) (void(0))
#endif
#include <Adafruit_NeoPixel.h>
#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
// NTP Servers:
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov
// IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov
const int timeZone = 10; // Australian Eastern Standard Time
WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
long lastUpdate = 0, lastBlink = 0;
long updateInterval = 5 * 60 * 1000; // five minutes
long blinkInterval = 1000; // 1 second
bool firstRun = true;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void startWiFi()
{
Oak.connect();
DebugPrint("Connecting to WiFi");
while (!Oak.connected())
{
digitalWrite(LED_BUILTIN, HIGH);
delay(250);
DebugPrint(".");
digitalWrite(LED_BUILTIN, LOW);
}
digitalWrite(LED_BUILTIN, LOW);
DebugPrintln("CONNECTED!");
}
void stopWiFi()
{
DebugPrintln("Stopping WiFi!");
WiFi.disconnect();
}
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
DebugBegin(115200);
DebugPrintln("setup()");
strip.begin();
strip.show(); // Initialize all pixels to 'off'
setSyncProvider(getNtpTime);
}
void loop()
{
unsigned long loopStartTime = millis();
if (millis() - lastUpdate > updateInterval || firstRun)
{
firstRun = false;
if (timeStatus() != timeNotSet)
{
digitalClockDisplay();
}
else
{
DebugPrintln("Haven't gotten time sync???");
}
lastUpdate = millis();
}
rainbow(20);
DebugPrint("loop() runtime (ms) = ");
DebugPrintln(millis() - loopStartTime);
}
void digitalClockDisplay() {
// digital clock display of the time
DebugPrint(hour());
printDigits(minute());
printDigits(second());
DebugPrint(" ");
DebugPrint(day());
DebugPrint(".");
DebugPrint(month());
DebugPrint(".");
DebugPrint(year());
DebugPrintln();
}
void printDigits(int digits) {
// utility for digital clock display: prints preceding colon and leading 0
DebugPrint(":");
if (digits < 10)
DebugPrint('0');
DebugPrint(digits);
}
/*-------- NTP code ----------*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime()
{
//start WiFi
startWiFi();
Udp.begin(localPort);
while (Udp.parsePacket() > 0) ; // discard any previously received packets
DebugPrintln("Transmit NTP Request");
sendNTPpacket(timeServer);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
DebugPrintln("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
//finished with WiFi for now...
Udp.stop();
stopWiFi();
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
DebugPrintln("No NTP Response :-(");
//finished with WiFi for now...
Udp.stop();
stopWiFi();
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
void rainbow(uint8_t wait) {
uint16_t j;
for (j = 0; j < 256; j++)
{
strip.setPixelColor(0, Wheel(j));
strip.show();
delay(wait);
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}