//////////////////////////////////////////////////////////// // LOAD PORT INFO FROM EEPROM void loadPortInfo(byte forceReload) { byte cs = 0; for(int i=0; i<NUM_PORTS; ++i) { PORT_INFO *p = port[i]; memset(p, 0, sizeof(PORT_INFO)); int eepromAddr = 16 * i; p->cfg.triggerChannel = eeprom_read(eepromAddr + 0); p->cfg.triggerNote = eeprom_read(eepromAddr + 1); p->cfg.durationMax = (int)eeprom_read(eepromAddr + 2) << 8; p->cfg.durationMax |= (int)eeprom_read(eepromAddr + 3); p->cfg.durationModulator = eeprom_read(eepromAddr + 4); p->cfg.dutyMax = eeprom_read(eepromAddr + 5); p->cfg.dutyModulator = eeprom_read(eepromAddr + 6); byte flags = eeprom_read(eepromAddr + 7); p->cfg.invert = !!(flags & EEPROM_FLAG_INVERT); // default to full duration/duty p->status.duration = p->cfg.durationMax; p->status.duty = p->cfg.dutyMax; calcCheckSum((byte*)&p->cfg, sizeof(PORT_CONFIG), &cs); } if(forceReload || eeprom_read(EEPROM_ADDR_CHECKSUM) != cs) { // failed checksum (possibly no previous stored config) flashLed(10); initPortInfo(); savePortInfo(); } }
/* * initExpprocSocket() * * Creates the listen socket for communication to Expproc fro other processes * * instead of signal handler etc, this routine create a thread to handle the accept * thus removing the need for socketfuncs.c and asyncIO.c * * Author greg Brissey 3/12/2006 */ int initExpprocSocket() { int status, ival; int applPort; void *AcceptConnection( void *arg); pApplSocket = createSocket( SOCK_STREAM ); if (pApplSocket == NULL) /* each call to program in */ return( -1 ); /* sockets.c sets errno */ ival = openSocket( pApplSocket ); if (ival != 0) return( -1 ); ival = bindSocketAnyAddr( pApplSocket ); if (ival != 0) { errLogSysRet(ErrLogOp,debugInfo,"initExpprocSocket: bindSocketAnyAddr failed:" ); return( -1 ); } applPort = returnSocketPort( pApplSocket ); ival = listenSocket( pApplSocket ); if (ival != 0) { errLogSysRet(ErrLogOp,debugInfo,"initExpprocSocket: listenSocket failed:" ); return( -1 ); } savePortInfo( applPort ); pAcceptQueue = rngBlkCreate(128,"AcceptQ", 1); /* accepted socket queue */ /* create thread to handle the accept */ status = pthread_create (&AcceptThreadId, NULL, AcceptConnection, (void*) pApplSocket); return( 0 ); }
//////////////////////////////////////////////////////////// // MAIN void main() { int i; // osc control / 16MHz / internal osccon = 0b01111010; apfcon0 = APFCON0_MASK; // configure io. Initially all outputs are // disabled except for the LED and all outputs // states are zeroed trisa = 0b11111111; trisc = 0b11111111; T_LED = 0; ansela = 0b00000000; anselc = 0b00000000; porta = 0b00000000; portc = 0b00000000; P_WPU = 1; // weak pull up on switch input option_reg.7 = 0; // weak pull up enable // initialise MIDI comms init_usart(); intcon.7 = 1; //GIE intcon.6 = 1; //PEIE // Configure timer 0 (controls systemticks) // timer 0 runs at 4MHz // prescaled 1/16 = 250kHz // rollover at 250 = 1kHz // 1ms per rollover option_reg.5 = 0; // timer 0 driven from instruction cycle clock option_reg.3 = 0; // timer 0 is prescaled option_reg.2 = 0; // } option_reg.1 = 1; // } 1/16 prescaler option_reg.0 = 1; // } intcon.5 = 1; // enabled timer 0 interrrupt intcon.2 = 0; // clear interrupt fired flag // enable interrupts intcon.7 = 1; //GIE intcon.6 = 1; //PEIE // Initialise the table of port info pointers port[0] = &port0; port[1] = &port1; port[2] = &port2; port[3] = &port3; port[4] = &port4; port[5] = &port5; port[6] = &port6; port[7] = &port7; // allow time for input to settle then load // EEPROM settings, allowing a hold of MODE // to restore default settings delay_ms(5); loadPortInfo((!P_MODE)); #ifdef RELAY_SWITCHER // In relay switching mode set all output latches LOW // and set default tristate (INPUT/1 selected for OFF) T_OUT0 = !port0.cfg.invert; T_OUT1 = !port1.cfg.invert; T_OUT2 = !port2.cfg.invert; T_OUT3 = !port3.cfg.invert; T_OUT4 = !port4.cfg.invert; T_OUT5 = !port5.cfg.invert; T_OUT6 = !port6.cfg.invert; T_OUT7 = !port7.cfg.invert; P_OUT0 = 0; P_OUT1 = 0; P_OUT2 = 0; P_OUT3 = 0; P_OUT4 = 0; P_OUT5 = 0; P_OUT6 = 0; P_OUT7 = 0; #else // In transistor switching mode set default "off" // states and enable digital outputs P_OUT0 = !!port0.cfg.invert; P_OUT1 = !!port1.cfg.invert; P_OUT2 = !!port2.cfg.invert; P_OUT3 = !!port3.cfg.invert; P_OUT4 = !!port4.cfg.invert; P_OUT5 = !!port5.cfg.invert; P_OUT6 = !!port6.cfg.invert; P_OUT7 = !!port7.cfg.invert; T_OUT0 = 0; T_OUT1 = 0; T_OUT2 = 0; T_OUT3 = 0; T_OUT4 = 0; T_OUT5 = 0; T_OUT6 = 0; T_OUT7 = 0; #endif int ledCount = 0; int modeHeld = 0; byte enableNrpn = 0; byte nrpnLo = 0; byte nrpnHi = 0; byte pwm=0; int cycles = 0; for(;;) { // Fetch the next MIDI message byte msg = receiveMessage(); if(msg && !ledCount) ledCount = LEDCOUNT_BRIEF; // NOTE ON if(((msg & 0xf0) == 0x90) && midiParams[1]) { handleNoteOn(msg&0xF, midiParams[0], midiParams[1]); } // NOTE OFF else if((((msg & 0xf0) == 0x80)||((msg & 0xf0) == 0x90))) { handleNoteOff(msg&0xF, midiParams[0]); } // CONTROLLER else if((msg & 0xf0) == 0xb0) { if(enableNrpn) { switch(midiParams[0]) { case MIDI_NRPN_HI: nrpnHi = midiParams[1]; break; case MIDI_NRPN_LO: nrpnLo = midiParams[1]; break; case MIDI_DATA_HI: case MIDI_DATA_LO: if(nrpnHi < NUM_PORTS) handleNrpn(port[nrpnHi], nrpnLo, midiParams[1], (midiParams[0] == MIDI_DATA_LO)); else if(nrpnHi == NRPN_HI_EEPROM && nrpnLo == NRPN_LO_SAVE) savePortInfo(); break; default: handleCC(msg&0xF, midiParams[0], midiParams[1]); break; } } else { handleCC(msg&0xF, midiParams[0], midiParams[1]); } } // PITCH BEND else if((msg & 0xf0) == 0xe0) { handlePitchBend(msg&0xF, midiParams[0]); } if(ledCount) P_LED = !!(--ledCount); // EVERY MS if(timerTicked) { timerTicked = 0; // Decrement nonzero port latch counts for(i=0;i<NUM_PORTS;++i) { if(port[i]->status.count>0) --port[i]->status.count; } // If the MODE button is held for 1 second // this enables the receiving of config info if(!enableNrpn) { if(P_MODE)//mode button released { modeHeld = 0; } else if(++modeHeld >= 1000)// mode button pressed for more than 1 second { P_LED = 1; delay_s(1); P_LED = 0; enableNrpn = 1; } } else if(isDirtyConfig)//config has been updated { if(!P_MODE)// { P_LED = 1; delay_s(1); P_LED = 0; savePortInfo(); isDirtyConfig = 0; } else { ++cycles; if(!(cycles & 0x1FF) && !ledCount) ledCount = LEDCOUNT_MEDIUM; } } else { ++cycles; if(!(cycles & 0x7FF) && !ledCount) ledCount = LEDCOUNT_LONG; } } #ifdef RELAY_SWITCHER // Manage outputs for relay switcher. PWM is ignored and switching // is done on the TRIS bit. The outputs are active low for ON and // floating for OFF #define OUT_STATE(P) !(P.status.count) #define OUT_STATEN(P) !!(P.status.count) T_OUT0 = port0.cfg.invert? OUT_STATEN(port0) : OUT_STATE(port0); T_OUT1 = port1.cfg.invert? OUT_STATEN(port1) : OUT_STATE(port1); T_OUT2 = port2.cfg.invert? OUT_STATEN(port2) : OUT_STATE(port2); T_OUT3 = port3.cfg.invert? OUT_STATEN(port3) : OUT_STATE(port3); T_OUT4 = port4.cfg.invert? OUT_STATEN(port4) : OUT_STATE(port4); T_OUT5 = port5.cfg.invert? OUT_STATEN(port5) : OUT_STATE(port5); T_OUT6 = port6.cfg.invert? OUT_STATEN(port6) : OUT_STATE(port6); T_OUT7 = port7.cfg.invert? OUT_STATEN(port7) : OUT_STATE(port7); P_OUT0 = 0; P_OUT1 = 0; P_OUT2 = 0; P_OUT3 = 0; P_OUT4 = 0; P_OUT5 = 0; P_OUT6 = 0; P_OUT7 = 0; #elif TRS_SWITCHER // Manage outputs for TRS relay switcher. PWM is ignored and switching // is active high #define OUT_STATE(P) !!(P.status.count) #define OUT_STATEN(P) !(P.status.count) P_OUT0 = port0.cfg.invert? OUT_STATEN(port0) : OUT_STATE(port0); P_OUT1 = port1.cfg.invert? OUT_STATEN(port1) : OUT_STATE(port1); P_OUT2 = port2.cfg.invert? OUT_STATEN(port2) : OUT_STATE(port2); P_OUT3 = port3.cfg.invert? OUT_STATEN(port3) : OUT_STATE(port3); P_OUT4 = port4.cfg.invert? OUT_STATEN(port4) : OUT_STATE(port4); P_OUT5 = port5.cfg.invert? OUT_STATEN(port5) : OUT_STATE(port5); P_OUT6 = port6.cfg.invert? OUT_STATEN(port6) : OUT_STATE(port6); P_OUT7 = port7.cfg.invert? OUT_STATEN(port7) : OUT_STATE(port7); #else // Manage outputs for transistor switchers. PWM is used and switching // is active high #define OUT_STATE(P) (P.status.count && (pwm < P.status.duty)) #define OUT_STATEN(P) (!P.status.count && (pwm < P.status.duty)) P_OUT0 = port0.cfg.invert? OUT_STATEN(port0) : OUT_STATE(port0); P_OUT1 = port1.cfg.invert? OUT_STATEN(port1) : OUT_STATE(port1); P_OUT2 = port2.cfg.invert? OUT_STATEN(port2) : OUT_STATE(port2); P_OUT3 = port3.cfg.invert? OUT_STATEN(port3) : OUT_STATE(port3); P_OUT4 = port4.cfg.invert? OUT_STATEN(port4) : OUT_STATE(port4); P_OUT5 = port5.cfg.invert? OUT_STATEN(port5) : OUT_STATE(port5); P_OUT6 = port6.cfg.invert? OUT_STATEN(port6) : OUT_STATE(port6); P_OUT7 = port7.cfg.invert? OUT_STATEN(port7) : OUT_STATE(port7); if(++pwm>100) pwm=0; #endif } }