Ethernet.begin problem in teensy 4.1

MadMike

Member
In the code snippet below, "void InitEthernet(void)", the mere inclusion of the first line [ Ethernet.begin(mac, ip, gateway, gateway, subnet); ] causes the teensy to hang. If I comment this line out, teensy starts OK, but of course the Ethernet link fails. Even if I don't run "void InitEthernet(void)" the teensy hangs if that first line is not commented out. The most puzzling thing I've encountered. Any suggestions welcomed.


C:
void InitEthernet(void)
{

    Ethernet.begin(mac, ip, gateway, gateway, subnet);

    delay(200);

    if (Ethernet.hardwareStatus() == EthernetNoHardware)
    {
        mSerial->printf("Ethernet hardware not found\n");
        return;
    }
    if (Ethernet.linkStatus() == LinkOFF)
    {
        mSerial->printf("Ethernet cable is unplugged\n");
        return;
    }

    delay(100);
    mUdp.flush();
    mUdp.stop();
    delay(100);
    mUdp.begin(localPort);
    delay(100);
    mUdp.begin(localPort);
    delay(100);

    mSerial->printf("\nEthernet initialised\n");
}
 
Please post your entire sketch. Important details (what libraries are included, what is in your setup() function, etc.) are missing. Without these other details, any guesses would just be just that: a wild guess !! If you can't post your entire sketch, then try to post the smallest version of your sketch that others can use to reproduce your problem.

Mark J Culross
KD5RXT
 
I suspect it’s because you don’t have an Ethernet cable plugged in. The NativeEthernet library (if that’s what you’re using) waits until there’s a link. There’s been an issue filed in the library’s repo for that.

See: https://github.com/vjmuzik/NativeEthernet/issues/12

Have you tried the QNEthernet library? It doesn’t have this problem. Also, you don’t need to specify your own MAC address.
 
Definitely not an unplugged cable. I've tested that exhaustively. I've been asked for the sketch; I've included it below. Note that it;s not a conventional sketch. It's one of many files, using eclipse as the IDE.
C:
/* wavetable.cpp */

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

#include <NativeEthernetUdp.h>
#include <NativeEthernet.h>
#include <stdarg.h>
#include <string.h>
#include <limits.h>
#include <EEPROM.h>
#include <stdio.h>
#include <Wire.h>
#include <MIDI.h>
#include <SPI.h>
#include <SD.h>

#include "analyze_fft1024.h"
#include "wavetable.h"
#include "fileio.h"

#include "midi.h"
#include "mmi.h"

//#include "samples/pickedbs_samples.h"
//#include "samples/SynthBass1_samples.h"
//#include "samples/steelstrgtr_samples.h"
//#include "samples/honkytonk_samples.h"
//#include "samples/piano_samples.h"
#include "samples/JBRoomkit1_samples.h"    // /home/mja/Desktop/SoundFonts/Drum & Percussion Soundfonts/198-JB KiT.sf2
#include "samples/pianoelectrique_samples.h"
#include "samples/accousticbs_samples.h"
#include "samples/Castanets_samples.h"    // /home/mja/Desktop/SoundFonts/Ct4mgm.sf2
#include "samples/vibraphone_samples.h"
#include "samples/WoodBlock_samples.h"    // /home/mja/Desktop/SoundFonts/Ct4mgm.sf2

//#pragma GCC optimize ("O0") // ABM - ZZZ - For Debugger

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

#define RX1                         0
#define TX1                         1
#define TOTAL_MIXERS             (12)
#define DEFAULT_MIXER_VOLUME     (80)
#define DEFAULT_SGTL5000_VOLUME     (80)
#define DEFAULT_WAVETABLE_VOLUME (80)
#define BUFF_SZ                     (2048)

AudioAnalyzePeak         mPeak[TOTAL_MIXERS];
HardwareSerial*             mSerial;
AudioSynthWaveform         waveform;
AudioControlSGTL5000     sgtl5000;
AudioOutputI2S             i2s1;
AudioSynthWavetable         wavetable[NUM_TABLE_VOICES];
AudioAnalyzeFFT1024         FFT1024;
AudioMixer4                 mixer[TOTAL_MIXERS];
AudioEffectEnvelope         envelope;
tsVoices                 Voices[NUM_TABLE_VOICES];
int8_t                     sd_card;
tsPresets                 Presets[NUM_TABLE_VOICES];
tsPresets                 Drum_Preset_35;
tsPresets                 Drum_Preset_36;
tsPresets                 Drum_Preset_40;
tsPresets                 Drum_Preset_47;
tsPresets                 Drum_Preset_48;
tsPresets                 Drum_Preset_52;
tsPresets                 Drum_Preset_59;
tsPresets                 Drum_Preset_72;
IntervalTimer             OS_Timer;

static volatile bool Five_mS_Timer;
static volatile bool Startup;
static volatile bool LinkReady;
static volatile bool Run_FFT_StateMachine;
static volatile bool RunFFT;
static volatile bool Testing;

static uint32_t FFT_State;
static uint32_t SecondsCounter;

typedef enum
{
    FFT_idle,
    FFT_activate,
    FFT_wait_ready,
    FFT_send_2,
    FFT_send_3,
    FFT_send_4
} teFFTStates;

typedef union
{
    uint8_t by[2];
    int16_t sh;
} tuDest;

static tuDest Destination [BUFF_SZ];
static char   buffer[128];
static bool   visible;

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

uint8_t mac[] =  {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

IPAddress ip     (192, 168, 0, 226);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet (255, 255, 255, 0);

unsigned int localPort = 8888;               // local port to listen on

char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet,
char ReplyBuffer[UDP_TX_PACKET_MAX_SIZE];  // a string to send back
EthernetUDP mUdp;
unsigned int UdpSendIndex;

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void mProgramChange  (byte channel, byte program);
void FreeVoices         (void);

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

AudioConnection patchCord[] =
{
    {wavetable[0],  0, mixer[0], 0}, {wavetable[1],  0, mixer[0], 1}, {wavetable[2],  0, mixer[0], 2}, {wavetable[3],  0, mixer[0], 3},
    {wavetable[4],  0, mixer[1], 0}, {wavetable[5],  0, mixer[1], 1}, {wavetable[6],  0, mixer[1], 2}, {wavetable[7],  0, mixer[1], 3},
    {wavetable[8],  0, mixer[2], 0}, {wavetable[9],  0, mixer[2], 1}, {wavetable[10], 0, mixer[2], 2}, {wavetable[11], 0, mixer[2], 3},
    {wavetable[12], 0, mixer[3], 0}, {wavetable[13], 0, mixer[3], 1}, {wavetable[14], 0, mixer[3], 2}, {wavetable[15], 0, mixer[3], 3},

    {wavetable[16], 0, mixer[4], 0}, {wavetable[17], 0, mixer[4], 1}, {wavetable[18], 0, mixer[4], 2}, {wavetable[19], 0, mixer[4], 3},
    {wavetable[20], 0, mixer[5], 0}, {wavetable[21], 0, mixer[5], 1}, {wavetable[22], 0, mixer[5], 2}, {wavetable[23], 0, mixer[5], 3},
    {wavetable[24], 0, mixer[6], 0}, {wavetable[25], 0, mixer[6], 1}, {wavetable[26], 0, mixer[6], 2}, {wavetable[27], 0, mixer[6], 3},
    {wavetable[28], 0, mixer[7], 0}, {wavetable[29], 0, mixer[7], 1}, {wavetable[30], 0, mixer[7], 2}, {wavetable[31], 0, mixer[7], 3},

    {mixer[0], 0, mixer[8], 0}, {mixer[4], 0, mixer[9], 0},
    {mixer[1], 0, mixer[8], 1}, {mixer[5], 0, mixer[9], 1},
    {mixer[2], 0, mixer[8], 2},    {mixer[6], 0, mixer[9], 2},
    {mixer[3], 0, mixer[8], 3},    {mixer[7], 0, mixer[9], 3},

    {mixer[8], 0, mixer[10], 0}, {mixer[8], 0, mixer[11], 1},
    {mixer[9], 0, mixer[10], 1}, {mixer[9], 0, mixer[11], 2},

    {mixer[10], 0, i2s1, 0}, {mixer[10], 0, mixer[11], 0},
    {mixer[10], 0, i2s1, 1},

    {waveform, 0, envelope, 0},    {waveform, 0, mixer[11], 3}, {waveform, 0, mixer[10], 2},
    {envelope, 0, mixer[10], 3},

    {mixer[11], FFT1024},

    {mixer[0], 0, mPeak[0], 0}, {mixer[1], 0, mPeak[1], 0}, {mixer[2],  0, mPeak[2],  0}, {mixer[3],  0, mPeak[3], 0},
    {mixer[4], 0, mPeak[4], 0}, {mixer[5], 0, mPeak[5], 0}, {mixer[6],  0, mPeak[6],  0}, {mixer[7],  0, mPeak[7], 0},
    {mixer[8], 0, mPeak[8], 0}, {mixer[9], 0, mPeak[9], 0}, {mixer[10], 0, mPeak[10], 0}
};
/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void ShowPeaks(void)
{
    uint32_t lp;
    float_t  res;

    for (lp=0; lp<TOTAL_MIXERS; lp++)
    {
        if (mPeak[lp].available() == true)
        {
            res = mPeak[lp].readPeakToPeak();
            mSerial->printf("peak-to-peak %02u = %f\n", lp, res);

        }
        else
        {
            mSerial->printf("peak-to-peak %02u = na\n", lp);
        }
    }
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mAfterTouchPoly(uint8_t channel, uint8_t note, uint8_t pressure){mSerial->printf("AfterTouchPolt\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mControlChange(byte channel, byte control, byte value) {/*mSerial->printf("ControlChange: chan = %u, control = %u, value = %u\n", channel,control,value);*/}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//void mProgramChange(byte channel, byte program){mSerial->printf("ProgramChange: chan = %u, program = %u\n", channel, program);}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mAfterTouch(byte channel, byte pressure){mSerial->printf("AfterTouch\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mPitchChange(byte channel, int pitch){/*mSerial->printf("PitchChange: chan = %u, pitch = %u\n", channel,pitch);*/}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mSystemExclusiveChunk(const byte *data, uint16_t length, bool last){mSerial->printf("SystemExclusiveChunk\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mSystemExclusive(byte *data, unsigned int length){mSerial->printf("SystemExclusive\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mTimeCodeQuarterFrame(byte data){mSerial->printf("TimeCodeQuarterFrame\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mSongPosition(uint16_t beats){mSerial->printf("SongPosition\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mSongSelect(byte songNumber){mSerial->printf("SongSelect\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mTuneRequest(){mSerial->printf("TuneRequest\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mClock(){mSerial->printf("Clock\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mStart(){mSerial->printf("Start\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mContinue(){mSerial->printf("Continue\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mStop(){    mSerial->printf("Stop\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mActiveSensing(){mSerial->printf("ActiveSensing\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mSystemReset(){mSerial->printf("SystemReset\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void mRealTimeSystem(byte realtimebyte){mSerial->printf("RealTimeSystem\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//void mNoteOff(uint8_t channel, uint8_t note, uint8_t velocity){mSerial->printf("NoteOff\n");}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//void mNoteOn(uint8_t channel, uint8_t note, uint8_t velocity){mSerial->printf("NoteOn\n");}
/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void SetupMIDI(void)
{
    usbMIDI.setHandleAfterTouchPoly(mAfterTouchPoly);
    usbMIDI.setHandleControlChange(mControlChange);
    usbMIDI.setHandleAfterTouch(mAfterTouch);
    usbMIDI.setHandlePitchChange(mPitchChange);
    usbMIDI.setHandleSystemExclusive(mSystemExclusiveChunk);
    usbMIDI.setHandleTimeCodeQuarterFrame(mTimeCodeQuarterFrame);
    usbMIDI.setHandleSongPosition(mSongPosition);
    usbMIDI.setHandleSongSelect(mSongSelect);
    usbMIDI.setHandleTuneRequest(mTuneRequest);
    usbMIDI.setHandleClock(mClock);
    usbMIDI.setHandleStart(mStart);
    usbMIDI.setHandleContinue(mContinue);
    usbMIDI.setHandleStop(mStop);
    usbMIDI.setHandleActiveSensing(mActiveSensing);
    usbMIDI.setHandleSystemReset(mSystemReset);
    usbMIDI.setHandleRealTimeSystem(mRealTimeSystem);
    usbMIDI.setHandleProgramChange(mProgramChange);
    usbMIDI.setHandleNoteOff(midiNoteOff);
    usbMIDI.setHandleNoteOn (midiNoteOn);
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void PurrAndMeow(void)
{
    mSerial->printf("PurrAndMeow\n");

    //Ethernet.begin(mac, ip, gateway, gateway, subnet);

    delay(200);

    if (Ethernet.hardwareStatus() == EthernetNoHardware)
    {
        mSerial->printf("Ethernet hardware not found\n");
        return;
    }
    if (Ethernet.linkStatus() == LinkOFF)
    {
        mSerial->printf("Ethernet cable is unplugged\n");
        return;
    }

    delay(100);
    mUdp.flush();
    mUdp.stop();
    delay(100);
    mUdp.begin(localPort);
    delay(100);
    mUdp.begin(localPort);
    delay(100);

    mSerial->printf("\nEthernet initialised\n");
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void InitEthernet(void)
{
    Ethernet.begin(mac, ip, gateway, gateway, subnet);

    delay(200);

    if (Ethernet.hardwareStatus() == EthernetNoHardware)
    {
        mSerial->printf("Ethernet hardware not found\n");
        return;
    }
    if (Ethernet.linkStatus() == LinkOFF)
    {
        mSerial->printf("Ethernet cable is unplugged\n");
        return;
    }

    delay(100);
    mUdp.flush();
    mUdp.stop();
    delay(100);
    mUdp.begin(localPort);
    delay(100);
    mUdp.begin(localPort);
    delay(100);

    mSerial->printf("\nEthernet initialised\n");
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void UDP_On(void)
{
    mSerial->printf("Ready to Start\n");
    PurrAndMeow();
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void SetWavetableVolume(uint32_t v)
{
    uint32_t lp;
    float_t f;

    f = (v * DIV127);

    for(lp=0; lp<NUM_TABLE_VOICES; lp++)
    {
        wavetable[lp].amplitude(f);
    }
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void SetMixerVolume(uint32_t v)
{
    uint32_t i, j;
    float_t f;

    f = (v * DIV127);
    for (i = 0; i < TOTAL_MIXERS; i++)
    {
        for (j = 0; j < 4; j++)
        {
            mixer[i].gain(j, f);
        }
    }
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void ChooseVisible (bool ch) // false = none, true = all];
{
    visible = ch;
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void PrintIfVisable(const char * format, ...)
{
    if (visible == false)
    {
        return;
    }
    va_list args;
    va_start (args, format);
    vsprintf (buffer,format, args);
    va_end (args);
    mSerial->printf("%s", buffer);
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void SetSGTLVolume(uint32_t v)
{
    float_t f;

    f = (v * DIV127);
    sgtl5000.lineOutLevel(f);
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void mProgramChange(byte chan, byte program)
{
    //PrintFError("~~~ ProgramChange: chan = %u, program = %u ~~~\n", chan, program);
    mSerial->printf("ProgramChange: chan = %u, program = %u\n", chan, program);

    chan--; // Incoming MIDI channels go from  1 to 16

    switch (program)
    {
        //case 0:     Presets[chan].preset_ptr = &piano;Presets[chan].PatchID = 0;Presets[chan].name = "Grand Piano";break;
        case 2:
            Presets[chan].preset_ptr = &pianoelectrique;
            Presets[chan].PatchID = 2;
            Presets[chan].name = "Electric Piano";
        break;
        case 3:
            Presets[chan].preset_ptr = &mja; // Ja, 'mja' is Mike's DMAMEM HonkyTonk
            Presets[chan].PatchID = 3;
            Presets[chan].name = "HonkyTonk";
        break;
        case 11:
            Presets[chan].preset_ptr = &vibraphone;
            Presets[chan].PatchID = 11;
            Presets[chan].name = "Vibraphone";
        break;
        case 32:
            Presets[chan].preset_ptr = &accousticbs;
            Presets[chan].PatchID = 32;
            Presets[chan].name = "Accoustic Bass";
        break;
        default: mSerial->printf("Invalid Program-Change: %u\n",program);
    }
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void ShowPresets(void)
{
    uint32_t lp;

    for(lp=0; lp<NUM_TABLE_VOICES; lp++)
    {
        if (Presets[lp].PatchID != 0xff)
        {
            mSerial->printf("Preset No. %u patch is %s\n", (lp+1), Presets[lp].name );
        }
    }
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void Timex(void)
{
    Five_mS_Timer = true;
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void SendUDP(void)
{
    #define BUFFER_SIZE (2048)

    uint8_t mbuffer[BUFFER_SIZE];
    uint32_t lp;

    if (LinkReady == false)
    {
        mSerial->printf("Link not ready - Rx a packet first\n");
    }

    for (lp=0; lp<BUFFER_SIZE; lp++)
    {
        mbuffer[lp] = lp;
    }

    mUdp.beginPacket(mUdp.remoteIP(), mUdp.remotePort());
    mUdp.write(mbuffer, BUFFER_SIZE);
    mUdp.endPacket();
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void HandleUDP(void)
{
    int32_t res;

    if (mUdp.parsePacket())
    {
        mUdp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
        LinkReady = true;

        res = strncmp(packetBuffer, "GFT", 3);
        mSerial->printf("buff = %c%c%c, res = %d\n", packetBuffer[0], packetBuffer[1], packetBuffer[2], res);

        if (res == 0)
        {
            // Do_Some_Meaningful_Work_Pretty-Please_With_Catnip_and_Kitty_treats();
        }
    }
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void ChooseConfig(bool ch) // true = normal, false = test
{
    if (ch == true)
    {
        Testing = false;
        mSerial->printf("Mode: run\n");

        waveform.amplitude(0.0);

        mixer[10].gain(0, (DEFAULT_MIXER_VOLUME * DIV127));
        mixer[10].gain(1, (DEFAULT_MIXER_VOLUME * DIV127));
        mixer[10].gain(2, 0.0);
        mixer[10].gain(3, 0.0);

        mixer[11].gain(0, 0.8);
        mixer[11].gain(1, 0.0);
        mixer[11].gain(2, 0.0);
        mixer[11].gain(3, 0.0);
    }
    else
    {
        Testing = true;
        mSerial->printf("Mode: test\n");

        waveform.amplitude(0.8);
        waveform.frequency(440);
        waveform.begin(WAVEFORM_SINE);

        mixer[10].gain(0, 0.0);
        mixer[10].gain(1, 0.0);
        mixer[10].gain(2, 0.8);
        mixer[10].gain(3, 0.8);

        mixer[11].gain(0, 0.0);
        mixer[11].gain(1, 0.0);
        mixer[11].gain(2, 0.0);
        mixer[11].gain(3, 0.8);
    }
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void setup(void)
{
    pinMode(RX1,INPUT_PULLUP);
    pinMode(TX1,INPUT_PULLUP);

    AudioMemory(120);
    sgtl5000.enable();
//    sgtl5000.muteHeadphone();
    sgtl5000.volume(0.6); // Headphone
    sgtl5000.unmuteLineout();

    mSerial = &Serial1;
    mSerial->begin(57600);
    while(!mSerial);

    visible = false;

    SetSGTLVolume(DEFAULT_SGTL5000_VOLUME);
    SetMixerVolume(DEFAULT_MIXER_VOLUME);
    SetWavetableVolume(DEFAULT_WAVETABLE_VOLUME);

//    InitEthernet();
    SetupMIDI();
    ResetMMI();
    MIDIinit(); // Does nothing, for now
    FreeVoices();

    LinkReady = false;

    sd_card = 0;
    sd_card = check_sd_card();
    if (sd_card < 1)
    {
        mSerial->printf(F("SD Card Error\n"));
    }

    loadVoice(); // Operates on 'mja', which is Mike's DMAMEM HonkyTonk

    for (UdpSendIndex=0; UdpSendIndex<UDP_TX_PACKET_MAX_SIZE; UdpSendIndex++)
    {
        ReplyBuffer[UdpSendIndex] = 0;
    }

    ChooseConfig(true); // true = normal, false = test

    UdpSendIndex = 0;

    OS_Timer.begin(Timex, 5000);

    Five_mS_Timer = false;
    Run_FFT_StateMachine = false;

    RunFFT = false;

    FFT_State = FFT_idle;
    SecondsCounter = 0;

    Startup = true;

    mSerial->printf(F("<Initialisation Complete>\n"));
    Version();
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/



/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void TriggerFFT(void)
{
    RunFFT = true;
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void FFT_StateMachine_Test(void)
{
    static uint32_t lp;
    static int16_t* src;
    static uint8_t* ptr;

    switch (FFT_State)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_idle:
            if (RunFFT == false)
            {
                return;
            }
            FFT1024.startAcquisation();

            RunFFT = false;
            FFT_State = FFT_wait_ready;
        break;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_activate:
            if (SecondsCounter > 200)
            {
                SecondsCounter = 0;
                FFT1024.startAcquisation();
                FFT_State = FFT_wait_ready;
            }
        break;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_wait_ready:
            if (FFT1024.available() == true)
            {
                src = FFT1024.readBufferAddress();

                for (lp=0; lp<BUFF_SZ; lp++)
                {
                    Destination[lp].sh = *src;
                    src++;
                }

                ptr = &Destination[0].by[0];
                mUdp.beginPacket(mUdp.remoteIP(), mUdp.remotePort());
                mUdp.write(ptr, 1024);
                mUdp.endPacket();

                FFT_State = FFT_send_2;
            }
        break;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_send_2:
            ptr = &Destination[512].by[0];
            mUdp.beginPacket(mUdp.remoteIP(), mUdp.remotePort());
            mUdp.write(ptr, 1024);
            mUdp.endPacket();

            FFT_State = FFT_send_3;
        break;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_send_3:
            ptr = &Destination[1024].by[0];
            mUdp.beginPacket(mUdp.remoteIP(), mUdp.remotePort());
            mUdp.write(ptr, 1024);
            mUdp.endPacket();

            FFT_State = FFT_send_4;
        break;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_send_4:
            ptr = &Destination[1536].by[0];
            mUdp.beginPacket(mUdp.remoteIP(), mUdp.remotePort());
            mUdp.write(ptr, 1024);
            mUdp.endPacket();

            FFT_State = FFT_idle;
        break;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    }
}

#ifdef mike

void FFT_StateMachine_Test(void)
{
    static uint32_t lp;
    static int16_t* src;
    static uint8_t* ptr;
    uint16_t sz;

    switch (FFT_State)
    {
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_idle:
            if (RunFFT == false)
            {
                return;
            }
            FFT1024.startAcquisation();

            RunFFT = false;
            FFT_State = FFT_wait_ready;
        break;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_activate:
            if (SecondsCounter > 200)
            {
                SecondsCounter = 0;
                FFT1024.startAcquisation();
                FFT_State = FFT_wait_ready;
            }
        break;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_wait_ready:
            if (FFT1024.available() == true)
            {
                sz = FFT1024.getsize();

                mSerial->printf("sz = %u\n", sz);

                src = FFT1024.readBufferAddress();
                for (lp=0; lp<BUFF_SZ; lp++)
                {
                    Destination[lp].sh = *src;
                    src++;
                }
                FFT_State = FFT_send;
            }
        break;

        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        case FFT_send:
            ptr = &Destination[0].by[0];
            mUdp.beginPacket(mUdp.remoteIP(), mUdp.remotePort());
            mUdp.write(ptr, (BUFF_SZ * 2));
            mUdp.endPacket();
            FFT_State = FFT_idle;
        break;
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    }
}

#endif // of #ifdef mike

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

#ifdef mike

void loop(void)
{
    uint8_t  ch;
    uint32_t lp;
    float_t  res;
    int32_t     sz;

    if (Startup == true)
    {
        mSerial->printf(F("<ready>\n>"));
        Startup = false;
    }

    usbMIDI.read();
    HandleUDP();

    if (mSerial->available() > 0)
    {
        ch = mSerial->read();
        ServiceRx(ch);
    }

    if (Five_mS_Timer == true)
    {
        Five_mS_Timer = false;

        SecondsCounter++;

        if (Run_FFT_StateMachine == true)
        {
            //FFT_StateMachine();
            FFT_StateMachine_Test();
            Run_FFT_StateMachine = false;
        }
        else
        {
            Run_FFT_StateMachine = true;

            for(lp=0; lp<NUM_TABLE_VOICES; lp++)
            {
                if (Voices[lp].release == true)
                {
                    if (--Voices[lp].timer == 0)
                    {
                        Voices[lp].release = false;
                        Voices[lp].playing = false;
                    }
                }
            }
            if (LinkReady == true)
            {
                if (mPeak[UdpSendIndex].available() == true)
                {
                    res = mPeak[UdpSendIndex].readPeakToPeak();
                    sz  = sprintf(ReplyBuffer, "%03u %0.4f", UdpSendIndex, res);
                    mUdp.beginPacket(mUdp.remoteIP(), mUdp.remotePort());
                    mUdp.write(ReplyBuffer, sz);
                    mUdp.endPacket();
                }
                UdpSendIndex++;
                if (UdpSendIndex >= TOTAL_MIXERS)
                {
                    UdpSendIndex = 0;
                }
            }
        }
    }
}

#endif // of #ifdef mike

void loop(void)
{
    uint8_t  ch;
//    uint32_t lp;
//    float_t  res;
//    int32_t     sz;

    if (Startup == true)
    {
        mSerial->printf(F("<ready>\n>"));
        Startup = false;
    }

    usbMIDI.read();
    //HandleUDP();

    if (mSerial->available() > 0)
    {
        ch = mSerial->read();
        ServiceRx(ch);
    }

    /*

    if (Five_mS_Timer == true)
    {
        Five_mS_Timer = false;

        SecondsCounter++;

        if (Run_FFT_StateMachine == true)
        {
            FFT_StateMachine_Test();
            Run_FFT_StateMachine = false;
        }
        else
        {
            Run_FFT_StateMachine = true;

            for(lp=0; lp<NUM_TABLE_VOICES; lp++)
            {
                if (Voices[lp].release == true)
                {
                    if (--Voices[lp].timer == 0)
                    {
                        Voices[lp].release = false;
                        Voices[lp].playing = false;
                    }
                }
            }
            if (LinkReady == true)
            {
                if (Testing == false)
                {
                    if (mPeak[UdpSendIndex].available() == true)
                    {
                        res = mPeak[UdpSendIndex].readPeakToPeak();
                        sz  = sprintf(ReplyBuffer, "%03u %0.4f", UdpSendIndex, res);
                        mUdp.beginPacket(mUdp.remoteIP(), mUdp.remotePort());
                        mUdp.write(ReplyBuffer, sz);
                        mUdp.endPacket();
                    }
                    UdpSendIndex++;
                    if (UdpSendIndex >= TOTAL_MIXERS)
                    {
                        UdpSendIndex = 0;
                    }
                }
            }
        }
    }
    */
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void CheckBusyVoices(void)
{
    uint32_t lp, num;

    num = 0;

    for(lp=0; lp<NUM_TABLE_VOICES; lp++)
    {
        if (Voices[lp].playing == true)
        {
            num++;
        }
    }
    mSerial->printf("Busy voices = %u\n", num);
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

void FreeVoices(void)
{
    uint32_t lp;

    for(lp=0; lp<NUM_TABLE_VOICES; lp++)
    {
        Voices[lp].wavetable_ptr = &wavetable[lp];
        Voices[lp].playing         = false;
        Voices[lp].release         = false;
        Voices[lp].note             = 0xff;
        Voices[lp].chan             = 0xff;
        Voices[lp].release         = false;
        Presets[lp].preset_ptr     = &mja; // Ja, mja is Mike's DMAMEM HonkyTonk
        Presets[lp].PatchID         = 0xff;
        Presets[lp].IsItDrum     = false;
    }

    Drum_Preset_35.preset_ptr = &WoodBlock;
    Drum_Preset_36.preset_ptr = &JBRoomkit1;
    Drum_Preset_40.preset_ptr = &JBRoomkit1;
    Drum_Preset_47.preset_ptr = &JBRoomkit1;
    Drum_Preset_48.preset_ptr = &Castanets;
    Drum_Preset_52.preset_ptr = &JBRoomkit1;
    Drum_Preset_59.preset_ptr = &JBRoomkit1;

    Drum_Preset_35.DrumNote = 35; // woodblock B3
    Drum_Preset_36.DrumNote = 36; // kick1 C3
    Drum_Preset_40.DrumNote = 40; // kick5 E3
    Drum_Preset_47.DrumNote = 47; // sda4  B3
    Drum_Preset_48.DrumNote = 48; // cstnr C4
    Drum_Preset_52.DrumNote = 52; // roll1 E4
    Drum_Preset_59.DrumNote = 59; // hh2 B4

    Drum_Preset_35.Velocity = 120;
    Drum_Preset_36.Velocity = 120;
    Drum_Preset_40.Velocity = 120;
    Drum_Preset_47.Velocity = 120;
    Drum_Preset_48.Velocity = 120;
    Drum_Preset_52.Velocity = 120;
    Drum_Preset_59.Velocity = 120;
    //Drum_Preset_72.Velocity = 120;

    Drum_Preset_35.IsItDrum = true;
    Drum_Preset_36.IsItDrum = true;
    Drum_Preset_40.IsItDrum = true;
    Drum_Preset_47.IsItDrum = true;
    Drum_Preset_48.IsItDrum = true;
    Drum_Preset_52.IsItDrum = true;
    Drum_Preset_59.IsItDrum = true;
    //Drum_Preset_72.IsItDrum = true;
}

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

// void *memcpy(void *dest, const void * src, size_t n)
// memcpy(dest, src, strlen(src)+1);
// #define sz (262144) // 2^18 = Max. DMAMEM - Used by mja structure -
// See 'fileio.cpp'

/*■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

And the header:

C:
/* wavetable.h */

#ifndef WAVEFORMH
#define WAVEFORMH

#include <stdint.h>
#include <Audio.h>

#define NUM_TABLE_VOICES (32)
#define NUM_WAVE_VOICES     (1)
#define DIV127             (float_t(1.0 / 127.0))

typedef struct
{
    AudioSynthWavetable* wavetable_ptr;
    bool     playing;
    bool     release;
    uint8_t  note;
    uint8_t  chan;
    uint32_t timer;
} tsVoices;

typedef struct
{
    const AudioSynthWavetable::instrument_data* preset_ptr;
    uint32_t    PatchID;
    const char    *name;
    uint32_t    DrumNote;
    bool        IsItDrum;
    uint32_t    Velocity;
} tsPresets;

void SetWavetableVolume (uint32_t v);
void SetMixerVolume        (uint32_t v);
void SetSGTLVolume        (uint32_t v);
void FreeVoices            (void);
void ShowPeaks            (void);
void ShowPresets        (void);
void SetupTestPresets    (void);
void FoolWithDrum        (uint32_t freq, uint32_t length, float_t second_mix, float_t pitchMod);
void CheckBusyVoices    (void);
void SendUDP            (void);
void TriggerFFT            (void);
void ChooseConfig        (bool ch); // true = normal, false = test
void ChooseVisible        (bool ch); // false = none, true = all];
void PrintIfVisable        (const char * format, ...);
//void InitEthernet        (void);
void UDP_On(void);

#endif /*  WAVEFORMH */
 
Strongly recommend you switch from NativeEthernet to QNEthernet. NativeEthernet is obsolescent and has not been updated for a long time, including through the recent changes to GCC versions in Teensy. Quite a few libraries had to be updated to work correctly after TD 1.58 (something about object initialization) and I wouldn't be surprised if at least some aspects of NativeEthernet were subject to that type of issue.
 
Back
Top