@jmosk, I used Quick’n Easy FTP Server light on windows:
http://www.pablosoftwaresolutions.com/html/quick__n_easy_ftp_server_lite.html
The Photon/Core code is a super easy adaptation of the Arduino code from the link I supplied:
/*
FTP passive client for IDE v1.0.1 and w5100/w5200
Posted October 2012 by SurferTim
Modified 6 June 2015 by SurferTim
*/
#include "SD.h"
// comment out next line to write to SD from FTP server
#define FTPWRITE
// change to your server
IPAddress server( 192, 168, 0, 158 ); //Local network connected
TCPClient client;
TCPClient dclient;
char outBuf[128];
char outCount;
#define SD_CS SS
byte doFTP();
byte eRcv();
void efail();
void readSD();
// change fileName to your file (8.3 format!)
char fileName[13] = "test.txt";
void setup()
{
Serial.begin(9600);
while(!Serial.available()) Particle.process();
if(!SD.begin(SD_CS))
{
Serial.println("SD init fail");
}
Serial.println("Ready. Press f or r");
}
void loop()
{
byte inChar;
inChar = Serial.read();
if(inChar == 'f')
{
if(doFTP()) Serial.println("FTP OK");
else Serial.println("FTP FAIL");
}
if(inChar == 'r')
{
readSD();
}
}
File fh;
byte doFTP()
{
#ifdef FTPWRITE
fh = SD.open(fileName,FILE_READ);
#else
SD.remove(fileName);
fh = SD.open(fileName,FILE_WRITE);
#endif
if(!fh)
{
Serial.println("SD open fail");
return 0;
}
#ifndef FTPWRITE
if(!fh.seek(0))
{
Serial.println("Rewind fail");
fh.close();
return 0;
}
#endif
Serial.println("SD opened");
if (client.connect(server,21)) {
Serial.println("Command connected");
}
else {
fh.close();
Serial.println("Command connection failed");
return 0;
}
if(!eRcv()) return 0;
client.println("USER particle");
if(!eRcv()) return 0;
client.println("PASS photon");
if(!eRcv()) return 0;
client.println("SYST");
if(!eRcv()) return 0;
client.println("Type I");
if(!eRcv()) return 0;
client.println("PASV");
if(!eRcv()) return 0;
char *tStr = strtok(outBuf,"(,");
int array_pasv[6];
for ( int i = 0; i < 6; i++) {
tStr = strtok(NULL,"(,");
array_pasv[i] = atoi(tStr);
if(tStr == NULL)
{
Serial.println("Bad PASV Answer");
}
}
unsigned int hiPort,loPort;
hiPort = array_pasv[4] << 8;
loPort = array_pasv[5] & 255;
Serial.print("Data port: ");
hiPort = hiPort | loPort;
Serial.println(hiPort);
if (dclient.connect(server,hiPort)) {
Serial.println("Data connected");
}
else {
Serial.println("Data connection failed");
client.stop();
fh.close();
return 0;
}
#ifdef FTPWRITE
client.print("STOR ");
client.println(fileName);
#else
client.print("RETR ");
client.println(fileName);
#endif
if(!eRcv())
{
dclient.stop();
return 0;
}
#ifdef FTPWRITE
Serial.println("Writing");
byte clientBuf[64];
int clientCount = 0;
while(fh.available())
{
clientBuf[clientCount] = fh.read();
clientCount++;
if(clientCount > 63)
{
dclient.write(clientBuf,64);
clientCount = 0;
}
}
if(clientCount > 0) dclient.write(clientBuf,clientCount);
#else
while(dclient.connected())
{
while(dclient.available())
{
char c = dclient.read();
fh.write(c);
Serial.write(c);
}
}
#endif
dclient.stop();
Serial.println("Data disconnected");
if(!eRcv()) return 0;
client.println("QUIT");
if(!eRcv()) return 0;
client.stop();
Serial.println("Command disconnected");
fh.close();
Serial.println("SD closed");
return 1;
}
byte eRcv()
{
byte respCode;
byte thisByte;
while(!client.available()) Spark.process();
respCode = client.peek();
outCount = 0;
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
if(outCount < 127)
{
outBuf[outCount] = thisByte;
outCount++;
outBuf[outCount] = 0;
}
}
if(respCode >= '4')
{
efail();
return 0;
}
return 1;
}
void efail()
{
byte thisByte = 0;
client.println("QUIT");
while(!client.available()) Spark.process();
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
client.stop();
Serial.println("Command disconnected");
fh.close();
Serial.println("SD closed");
}
void readSD()
{
fh = SD.open(fileName,FILE_READ);
if(!fh)
{
Serial.println("SD open fail");
return;
}
while(fh.available())
{
Serial.write(fh.read());
}
fh.close();
}
Of course, you need to add an SD library to that. I used a hardware SPI connected microSD.