예제 #1
0
파일: main.c 프로젝트: mike-audi/m-audi
main()
{
	unsigned int x=0;
	setupIO();
	_asm("rim\n");
	PB_ODR |= 0x20;
	
	while(1){
		sendStandby();
		sendByte(0x55);
		sendByte(0xa0);
		sendByte(0x03);
		sendByte(0x00);
		sendByte(0x00);
		b1 = readByte();
		b2 = readByte();
		b3 = lastRead();
	
		for(x=0;x<60000;x++);
		for(x=0;x<60000;x++);
		for(x=0;x<60000;x++);
		for(x=0;x<60000;x++);
		for(x=0;x<60000;x++);
	}

}
예제 #2
0
int main(void)
{
	DO_TEST_HARNESS_SETUP();
	
	WD_DISABLE();
	
	setupIO();
	readTestMode();
		
	setupTimers();
	
	smIndex = setupStateMachine();
	
	TS_Setup();
	
	Threshold_Init();
	
	Filter_Init();
	
	Flush_Reset();
		
	COMMS_Init();
		
	sei();
	
	runNormalApplication();
}	
예제 #3
0
int main(void)
{
	
	DO_TEST_HARNESS_PRE_INIT();

	setupIO();
	setupADC();
	setupTimer();
	setupStateMachine();
	
	pAverager = AVERAGER_GetAverager(U16, BUFFER_SIZE);
	
	sei();
	
	WD_DISABLE();
	
	DO_TEST_HARNESS_POST_INIT();
	
	while (true)
	{
		DO_TEST_HARNESS_RUNNING();
		
		if (ADC_TestAndClear(&adc))
		{
			adcHandler();
		}
		
		if (TMR8_Tick_TestAndClear(&appTick))
		{
			applicationTick();
		}		
	}

	return 0;
}
예제 #4
0
void HodginDidItApp::setup()
{
	setupIO();
	setupCiCamera();
	setupGraphics();
	setupShaders();
	setupFbos();
}
예제 #5
0
	Chordid(t_symbol * sym, long ac, t_atom * av)
		: c(frameSize, sampleRate), chordspotter()
	{ 
		c.setChromaCalculationInterval(512);
		frame.resize(frameSize);
		m_outlets = (void **)sysmem_newptr(sizeof(void *) * numoutlets);
		for (unsigned int i = 0; i < numoutlets; i++){
			m_outlets[numoutlets - i - 1] = outlet_new(this, NULL); // generic outlet
		}
		setupIO(1, 1);
		// post("object created"); 
	}
예제 #6
0
/*
 *Class Constructor
 * Initializes our Callback.
 */
MUEAudioIO::MUEAudioIO()
{
    printf("Construcing New MUE Audio Engine\n");
    m_inputBuffer = NULL;
    m_inputBufferList = NULL;
    m_curNumEffects = 0; //we have no effects registered at startup
    
    printf("Configuring Audio Session...\n");
    configureAudioSession();
    
    printf("Setting up IO Audio Unit + Callbacks...\n");
    setupIO();
    
    //printf("Initializing Callbacks...\n");
    //init_callbacks();

}
예제 #7
0
파일: cangc2.c 프로젝트: rocrail/GCA
void initIO(void) {
    int idx = 0;

    INTCON = 0;
    EECON1 = 0;

    IPR3 = 0; // All IRQs low priority for now
    IPR2 = 0;
    IPR1 = 0;
    PIE3 = 0;
    PIE2 = 0;
    PIE1 = 0;
    INTCON3 = 0;
    INTCON2 = 0; // Port B pullups are enabled
    INTCON = 0;
    PIR3 = 0;
    PIR2 = 0;
    PIR1 = 0;
    RCONbits.IPEN = 1; // enable interrupt priority levels

    // Set up TMR0 for DCC bit timing with 58us period prescaler 4:1,
    // 8 bit mode
    T0CON = 0x41; //or 4MHz resonat
    //T0CON = 0x42; //or 8MHz resonat
    TMR0L = 0;
    TMR0H = 0;
    INTCONbits.TMR0IE = 1;
    T0CONbits.TMR0ON = 1;
    INTCON2bits.TMR0IP = 1;

    tmr0_reload = TMR0_NORMAL;

    // Start slot timeout timer
    led500ms_timer = 2000; // 500ms
    io_timer = 200; // 50ms
    led_timer = 20; // 5ms

    // Set up global interrupts
    RCONbits.IPEN = 1; // Enable priority levels on interrupts
    INTCONbits.GIEL = 1; // Low priority interrupts allowed
    INTCONbits.GIEH = 1; // Interrupting enabled.

    setupIO(FALSE);
}
예제 #8
0
/** 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)
{
	SetupHardware();
	setupIO();
	interruptInit();
	/* Create a regular character stream for the interface so that it can be used with the stdio.h functions */
	CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream);

	sei();
	
	while (1)
	{
		
		/* Must throw away unused bytes from the host, or it will lock up while waiting for the device */
		CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
		CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
		USB_USBTask();
	}
}
예제 #9
0
int main(void)
{

	/* Disable watchdog: not required for this application */
	MCUSR &= ~(1 << WDRF);
	wdt_disable();

	setupTimer();
	setupIO();
	
	UI_Init();

	/* All processing interrupt based from here*/

	DO_TEST_HARNESS_SETUP();
	
	sei();

	// Update display on first application tick
	s_settings = Strobe_Init();
	s_bSettingsChanged = true;
	
	while (true)
	{
		DO_TEST_HARNESS_RUNNING();
		
		UI_Tick();
		
		if (TMR8_Tick_TestAndClear(&appTick))
		{
			applicationTick();
			DO_TEST_HARNESS_TICK();
		}

		if (TMR8_Tick_TestAndClear(&heartbeatTick))
		{
			IO_Control(IO_PORTB, 5, IO_TOGGLE);
		}
	}

	return 0;
}
예제 #10
0
void setup(void) {
  
  // Turn off interrupts  
  cli();

  // Reset buffer locations
  LightBuffer.bufferLocation = 0;
  SoundBuffer.bufferLocation = 0;

  setupIO();

  prepareADC();

  enableSPI();

  setupTimer();

  // Unleash the interrupts!
  sei();
}
예제 #11
0
파일: main.cpp 프로젝트: grefab/flakysworld
int main(int argc, char *argv[])
{
    QCoreApplication* app = new QCoreApplication(argc, argv);

    /* brain contains a collection of things */
    Brain* brain = new Brain();

    /* start neuron IO */
    UniverseClient* universeClient = setupIO(brain);
    universeClient->initiateConnection();

    /* preparation is done. let if flow! */
    qDebug() << "started.";
    return app->exec();

    /* when we reach this, the program is finished. delete everything in reverse order. */
    delete universeClient;
    delete brain;
    delete app;
}
예제 #12
0
wsserver::wsserver(t_symbol *s, long ac, t_atom * av)
: mCtx(NULL)
{
  setupIO(1, 1);

  long port = DEFAULT_PORT;
  long numconnections = DEFAULT_CONNECTIONS;
  long updaterate = DEFAULT_UPDATE_RATE_MS;
  long debug = DEFAULT_DEBUG;
  
  if (ac && av) 
  {
    if (ac > 0)
      port = atom_getlong(&av[0]);
    
    if (ac > 1)
      numconnections = atom_getlong(&av[1]);
    
    if (ac > 2)
      updaterate = atom_getlong(&av[2]);
    
    if (ac > 3)
      debug = atom_getlong(&av[3]);
  }
  
  if (port > 0 && port < 65535)
    mPortNumber.SetFormatted(32, "%ld", port);
  
  if (numconnections > 0 && numconnections < MAX_CONNECTIONS)
    mNumConnectionsToAllocate = numconnections;
  
  if (updaterate > MIN_UPDATE_RATE && updaterate < MAX_UPDATE_RATE)
    mClientUpdateRateMs = updaterate;
  
  if (debug > 0)
    mDebug = true;
  
  mClock = clock_new(this, TO_METHOD_NONE(wsserver, onTimer));
}
예제 #13
0
/**
* @brief prepares SPI and GPIO access (to control CE pin)
* this method must be executed succefully before calling any other method in
* this class.
*
* @return
*/
int HWAbstraction::openDevice() {
    uint8_t mode = 0;
    uint8_t bits = 8;
    uint32_t speed = 1000000;
    int ret;

    m_fd = open(m_spiDevice.c_str(), O_RDWR);
    if (m_fd < 0) {
        return -1;
    }

    ret = ioctl(m_fd, SPI_IOC_WR_MODE, &mode);
    ret = ioctl(m_fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    ret = ioctl(m_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);

    if (!setupIO()) {
        return -2;
    }


    return 0;
}
예제 #14
0
파일: midi4l.cpp 프로젝트: aumhaa/MIDI4L
    MIDI4L(t_symbol * sym, long ac, t_atom * av) :
        midiin(NULL),
        midiout(NULL),
        numInPorts(-1),
        numOutPorts(-1),
        inPortMap(),
        outPortMap(),
        inPortName(NULL),
        outPortName(NULL),
        message(),
        isSysEx(false)
    {
		setupIO(1, 4); // inlets / outlets
        
        try {
            midiin = new RtMidiIn();
        }
        catch ( RtMidiError &error ) {
            printError("RtMidiIn constructor failure", error);
        }
        
        try {
            midiout = new RtMidiOut();
        }
        catch ( RtMidiError &error ) {
            printError("RtMidiOut consturctor failure", error);
        }
        
        refreshPorts();
        // printPorts();
        
        if(ac > 0) { // first arg is input
            input(0, NULL, ac, av);
        }
        
        if(ac > 1) { // second arg is output
            output(0, NULL, ac-1, av+1);
        }
	}
예제 #15
0
void executeSimpleCommand(command_t c)
{
	pid_t p = fork();
	//if child process is running, wait till finish, store status
	if (p > 0)
	{
		int status;
		waitpid(p, &status, 0);
		if (!WIFEXITED(status))
			error(3, 0, "runtime error: child process returned non-exit status");
		c->status = status;
	}
	else if (p == 0)
	{
		setupIO(c);
		execvp(c->u.word[0], c->u.word);
		// if execvp returns at all, error			
		error (3, 0, "runtime error: %s command failed", c->u.word[0]);
	}
	else
		error(3, 0, "runtime error: forking failed");
}
예제 #16
0
	gmu_bufgranul(t_symbol * sym, long ac, t_atom * av)
	{
		int symcount = 0;
		float f;
		bool gotnum=false;
		t_symbol * bufsym = NULL;
		t_symbol * envsym = NULL;
		t_symbol * spatsym = NULL;
		
		t_atom def_env[5];
		
		// initialisation param 
		nspeakers = 2;
		nvoices_active = 0;
		active_env = 0;
		
		conf.sinterp = 1;
		conf.loop = false;
		conf.sr = sys_getsr();
		
		begin = 0.;
		transp = 1.;
		amp = 1.;
		length = 100.;
		
		position.x = 0.;
		position.y = 0.;
		position.z = 0.;
		
		
		// initialisation interp table
		linear_interp_table = (t_linear_interp *) sysmem_newptr( TABLE_SIZE * sizeof(struct linear_interp) );
		
		for(int i=0; i<TABLE_SIZE ; i++)
		{
			f = (float)(i)/TABLE_SIZE; // va de 0 a 1
			
			linear_interp_table[i].a = 1 - f;
			linear_interp_table[i].b = f;
		}
        
        gmu_bufgrain::interp_table = linear_interp_table;
        
        gmu_env::interp_table = linear_interp_table;
		
		// objects parameters
		for (int j=0; j < ac; j++){
			switch (av[j].a_type){
					
				case A_LONG:		// num speakers
					nspeakers= SAT(av[j].a_w.w_long,1,MAX_NUM_SPEAKERS);
					gotnum = true;
                    post("bufgranul~ : nouts %d",nspeakers);
					break;
					
				case A_SYM:
					if(gotnum)		// spat type
					{
						spatsym = av[j].a_w.w_sym;
                        post("bufgranul~ : spat %s",spatsym->s_name);
					}
					else
					if(symcount==1) //	env buffer // TODO: make possible choice of algos
					{
						envsym = av[j].a_w.w_sym;
						symcount++;
                        post("bufgranul~ : env %s",envsym->s_name);
						
					}else			//	buffer
					{						
						bufsym = av[j].a_w.w_sym;
						symcount++;
                        post("bufgranul~ : sound %s",bufsym->s_name);
					}
                    
					break;
					
				case A_FLOAT:
					post("argument %ld is a float : %lf, not assigned", (long)j,av[j].a_w.w_float);
					break;
			}	
		}
		
        
        // DSP init
		setupIO(&gmu_bufgranul::perform, 0, nspeakers);
        
		// SPAT ASSIGN
		if(spatsym)
		{
			if(!strcmp(spatsym->s_name,"dbap"))
			   spat_class = new gmu_spat_dbap(nspeakers);
			else
			   spat_class = new gmu_spat_dbap(nspeakers);
		}
		else
			spat_class = new gmu_spat_dbap(nspeakers);
			
		// ENV BUFFER MANAGER
		env_shrbuf_manager = new gmu_env_shrbuf_manager();
		// ENV ASSIGN
		int env_p_n;
		if(envsym)
		{
            atom_setsym(def_env, gensym("buffer"));
			atom_setsym(def_env+1, envsym);
			env_p_n = 2;
		}
		else 
		{
			atom_setsym(def_env, gensym("trap"));
			env_p_n = 1;
		}
		
		t_symbol * param;
		param = atom_getsym(def_env);
		
        for(int i = 0; i < MAX_ENV_SLOTS ; i++ )
            env_slots[i] = new gmu_env_slot(env_shrbuf_manager,env_p_n,def_env);
		
		// BUFFER ASSIGN
		
		if(bufsym != NULL)
		{
			default_buffer = new gmu_buffer(&conf,bufsym);
            if(default_buffer->is_valid)
            {
                buffer_slots[0] = default_buffer;
                buffer_pool[string(bufsym->s_name)] = default_buffer;
                gmu_buffer::valid_buffer = default_buffer;
            }
            else
                error("bufgranul~ : default sound buffer is not valid");
		}

        // TEMP BUFFER ALLOC for GRAINS
        gmu_bufgrain::tmp_buffer = (float *) sysmem_newptr(8192 * sizeof(float));
        
        // critical
        //critical_new(critical);
        
	}
예제 #17
0
int main(int argc, char *argv[]) {
    char        *word, *pEnd;
    int         word_count, i, nread;
    uint32_t    cmd_addr, flag;
    char        *gap = " \n";
    char        buff[BUFFSIZE];
    ENTRY       definition, *wp;
    pthread_t   receive_t;

    if (setupIO(argc, argv)) {
         return EXIT_FAILURE;
    }

    // if not given, use default filename
    if (namelen == 0) {
        strcpy(filename, "prufh");
        namelen = 5;
    }
    strcat(filename, ".defs");

    // open list of forth word addresses
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        fprintf(stderr, "Unable to open definitions file, %s\n", filename);
        return EXIT_FAILURE;
    }

    // get number of definitions from begining of file
    fgets (buff, BUFFSIZE, file );
    word_count = atoi(buff);

    // create hash for definition table
    hcreate(word_count);

    // fill hash with name-address pairs
    for (i=0; i<word_count;) {
        fgets(buff, BUFFSIZE, file);

        word = strtok(buff, gap);
        if (word != NULL) {
            definition.key = strdup(word);
            definition.data = (void*)strtol(strtok(NULL, gap), NULL, 0);

            wp = hsearch(definition, ENTER);

            if (wp == NULL) {
                fprintf(stderr, "Dictionary entry failed on \"%s\"\n", word);
                return EXIT_FAILURE;
            } else {
                if (!quiet_mode) 
                    printf("Saved %9.9s  as   %p\n", wp->key, wp->data); 
            }	    
            i++;
        }
    }
    fclose(file);

    if (pruInit(pru_num) == EXIT_SUCCESS) { 

        // start seperate thread to handle forth output
        if (pthread_create(&receive_t, NULL, receive, (void*) &outpipe)) {
        }

        // main loop, relay input to pru
        for(;;) {
            nread = read(0, buff, BUFFSIZE);  // wait here for input on stdin
            if (nread > 1) {
                word = strtok(buff, gap);

                // exit program on "bye" command
                if (strncmp(word, "bye", 3) == 0) break;

                // find address of word corresponding to input
                definition.key = word;
                wp = hsearch(definition, FIND);

                if (wp == NULL) {
                    // if input not defined, see if it is a number
                    cmd_addr = strtoul(word, &pEnd, 0);
                    if (pEnd == word) {
                        fprintf(stderr, "Unknown word, \"%s\"\n", word);
                        continue;
                    } else {
                        // if a number was input, signal forth to push it
                        flag = LIT_FLAG;
                        if (!quiet_mode) 
                            printf("Pushing %d\n", cmd_addr);
                    }
                } else {
                    // signal that a command address is being sent
                    flag = CMD_FLAG;
                    // retrieve the address
                    cmd_addr = (uint16_t)(intptr_t)(wp->data);
                    if (!quiet_mode) 
                        printf("Executing %9.9s %x\n", word, cmd_addr);
                }

                // send message to pruss
                if (exec(cmd_addr, flag)) {
                    fprintf(stderr, "Unable to issue command, \"%s\"\n", word);
                }
            }
        }
    }
    hdestroy();

    pthread_cancel(receive_t);
    pthread_join(receive_t, NULL);

    /* shutdown pru */
    prussdrv_pru_disable(pru_num);
    prussdrv_exit();

    if (outpipe != 1) {
        close(outpipe);
    }
    if (inpipe != 0) {
        close(inpipe);
    }

    return EXIT_SUCCESS;
}
예제 #18
0
int main(void)
{

	/* Disable watchdog: not required for this application */

	MCUSR &= ~(1 << WDRF);
	wdt_disable();

	setupStateMachine();

	setupTimer();

	setupIO();

	initialiseMap();

	UART_Init(UART0, 9600, 32, 32, false);

	I2C_SetPrescaler(64);
	DS3231_Init();

	UC_BTN_Init(APP_TICK_MS);

	TLC5916_Init(&tlc, SR_ShiftOut, tlcLatchFn, tlcOEFn);

	TLC5916_OutputEnable(&tlc, true);

	uint8_t displayBytes[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	TLC5916_ClockOut(displayBytes, 10, &tlc);

	/* All processing interrupt based from here */
	
	sei();

	/* First get the time from the DS3231.
	 * Don't worry about the state machine or any events, just get the time
	 * and see if it's greater than the compile time
	 */

	DS3231_ReadDeviceDateTime(NULL);

	while ( !DS3231_IsIdle() ) { I2C_Task(); }
	DS3231_GetDateTime(&tm);

	DS3231_SetRate(DS3231_RATE_1HZ);
	DS3231_SQWINTControl(DS3231_SQW);
	DS3231_UpdateControl();

	while ( !DS3231_IsIdle() ) { I2C_Task(); }

	s_unixtime = time_to_unix_seconds(&tm);

	if (s_unixtime < COMPILE_TIME_INT)
	{
		TM compile_time = COMPILE_TIME_STRUCT;
		DS3231_SetDeviceDateTime(&compile_time, false, NULL);

		while ( !DS3231_IsIdle() ) { I2C_Task(); }

		s_unixtime = COMPILE_TIME_INT;
	}
	
	updateUnixTimeDigits();
	
	//putTimeToUART();
	
	s_displayDirty = true;
	
	while (true)
	{
		
		if (TMR8_Tick_TestAndClear(&appTick))
		{
			applicationTick();
		}

		if (TMR8_Tick_TestAndClear(&heartbeatTick))
		{
			s_BlinkState = !s_BlinkState;
			s_displayDirty |= true;
		}

		if (PCINT_TestAndClear(secondTickVector))
		{
			s_bTick = !s_bTick;
			if (s_bTick && (SM_GetState(&sm) == (SM_STATEID)DISPLAY))
			{
				s_unixtime++;
				updateUnixTimeDigits();
				s_displayDirty |= true;
			}
			
			for(uint8_t i = 0; i < (uint8_t)SM_GetState(&sm); ++i)
			{
				//IO_Control(HB_PORT, HB_PIN, IO_OFF);
				//IO_Control(HB_PORT, HB_PIN, IO_ON);
			}
		}
		
		if (s_displayDirty)
		{
			updateDisplay();
			s_displayDirty |= false;
		}

		I2C_Task();
	}
}
예제 #19
0
void executeSubshellCommand(command_t c)
{
	setupIO(c);
	callCommand(c->u.subshell_command);
	c->status = command_status(c->u.subshell_command);
}
예제 #20
0
파일: commands.c 프로젝트: AndTH/GCA
unsigned char parseCmd(CANMsg *cmsg) {
    unsigned char txed = 0;
    //mode_word.s_full = 0;
    switch (cmsg->b[d0]) {

        case OPC_ASRQ:
        {
            int addr = cmsg->b[d3] * 256 + cmsg->b[d4];
            if (SOD == addr && doSOD == 0) {
                ioIdx = 0;
                doSOD = 1;
            }
            break;
        }

        case OPC_ACON:
        case OPC_ASON:
        {
            ushort nn = cmsg->b[d1] * 256 + cmsg->b[d2];
            ushort addr = cmsg->b[d3] * 256 + cmsg->b[d4];
            setOutput(nn, addr, 1);
            break;
        }

        case OPC_ACOF:
        case OPC_ASOF:
        {
            ushort nn = cmsg->b[d1] * 256 + cmsg->b[d2];
            ushort addr = cmsg->b[d3] * 256 + cmsg->b[d4];
            setOutput(nn, addr, 0);
            break;
        }

        case OPC_RQNPN:
            // Request to read a parameter
            if (thisNN(cmsg) == 1) {
                doRqnpn((unsigned int) cmsg->b[d3]);
            }
            break;

        case OPC_SNN:
        {
            if (Wait4NN) {
                unsigned char nnH = cmsg->b[d1];
                unsigned char nnL = cmsg->b[d2];
                NN_temp = nnH * 256 + nnL;
                eeWrite(EE_NN, nnH);
                eeWrite(EE_NN + 1, nnL);
                Wait4NN = 0;
                LED2 = 0;
            }
            break;
        }

        case OPC_RQNP:
            if (Wait4NN) {
                CANMsg canmsg;
                canmsg.b[d0] = OPC_PARAMS;
                canmsg.b[d1] = params[0];
                canmsg.b[d2] = params[1];
                canmsg.b[d3] = params[2];
                canmsg.b[d4] = params[3];
                canmsg.b[d5] = params[4];
                canmsg.b[d6] = params[5];
                canmsg.b[d7] = params[6];
                canmsg.b[dlc] = 8;
                canbusSend(&canmsg);
                txed = 1;
            }
            break;

        case OPC_BOOT:
            // Enter bootloader mode if NN matches
            if (thisNN(cmsg) == 1) {
                eeWrite((unsigned char) (&bootflag), 0xFF);
                Reset();
            }
            break;

        case OPC_RTOF:
            if (NV1 & CFG_SAVEOUTPUT) {
                saveOutputStates();
            }
            break;

        case OPC_NNCLR:
            if (thisNN(cmsg) && isLearning) {
                setupIO(TRUE);
            }
            break;

        case OPC_QNN:
        {
            CANMsg canmsg;
            canmsg.b[d0] = OPC_PNN;
            canmsg.b[d1] = (NN_temp / 256) & 0xFF;
            canmsg.b[d2] = (NN_temp % 256) & 0xFF;
            canmsg.b[d3] = params[0];
            canmsg.b[d4] = params[2];
            canmsg.b[d5] = NV1;
            canmsg.b[dlc] = 6;
            canbusSend(&canmsg);
        }
            //LED2 = 1;
            txed = 1;
            break;

        case OPC_RTON:
            pnnCount = 0;
            /*
            setOutput(0,  9, (pnnCount & 0x01) ? 1:0);
            setOutput(0, 10, (pnnCount & 0x02) ? 1:0);
            setOutput(0, 11, (pnnCount & 0x04) ? 1:0);
            setOutput(0, 12, (pnnCount & 0x08) ? 1:0);
            setOutput(0, 13, (pnnCount & 0x10) ? 1:0);
            setOutput(0, 14, (pnnCount & 0x20) ? 1:0);
            setOutput(0, 15, (pnnCount & 0x40) ? 1:0);
            setOutput(0, 16, (pnnCount & 0x80) ? 1:0);
             */
            break;

        case OPC_PNN:
            pnnCount++;
            /*
            setOutput(0,  9, (pnnCount & 0x01) ? 1:0);
            setOutput(0, 10, (pnnCount & 0x02) ? 1:0);
            setOutput(0, 11, (pnnCount & 0x04) ? 1:0);
            setOutput(0, 12, (pnnCount & 0x08) ? 1:0);
            setOutput(0, 13, (pnnCount & 0x10) ? 1:0);
            setOutput(0, 14, (pnnCount & 0x20) ? 1:0);
            setOutput(0, 15, (pnnCount & 0x40) ? 1:0);
            setOutput(0, 16, (pnnCount & 0x80) ? 1:0);
             */
            break;

        case OPC_NVRD:
            if (thisNN(cmsg)) {
                CANMsg canmsg;
                byte nvnr = cmsg->b[d3];
                if (nvnr == 1) {
                    canmsg.b[d0] = OPC_NVANS;
                    canmsg.b[d1] = (NN_temp / 256) & 0xFF;
                    canmsg.b[d2] = (NN_temp % 256) & 0xFF;
                    canmsg.b[d3] = nvnr;
                    canmsg.b[d4] = NV1;
                    canmsg.b[dlc] = 5;
                    canbusSend(&canmsg);
                    txed = 1;
                } else if (nvnr < 18) {
                    canmsg.b[d0] = OPC_NVANS;
                    canmsg.b[d1] = (NN_temp / 256) & 0xFF;
                    canmsg.b[d2] = (NN_temp % 256) & 0xFF;
                    canmsg.b[d3] = nvnr;
                    canmsg.b[d4] = Ports[nvnr - 2].cfg;
                    canmsg.b[dlc] = 5;
                    canbusSend(&canmsg);
                    txed = 1;
                } else if (nvnr == 18) {
                    canmsg.b[d0] = OPC_NVANS;
                    canmsg.b[d1] = (NN_temp / 256) & 0xFF;
                    canmsg.b[d2] = (NN_temp % 256) & 0xFF;
                    canmsg.b[d3] = nvnr;
                    canmsg.b[d4] = getPortStates(0); // port status 1-8
                    canmsg.b[dlc] = 5;
                    canbusSend(&canmsg);
                    txed = 1;
                } else if (nvnr == 19) {
                    canmsg.b[d0] = OPC_NVANS;
                    canmsg.b[d1] = (NN_temp / 256) & 0xFF;
                    canmsg.b[d2] = (NN_temp % 256) & 0xFF;
                    canmsg.b[d3] = nvnr;
                    canmsg.b[d4] = getPortStates(1); // port status 9-16
                    canmsg.b[dlc] = 5;
                    canbusSend(&canmsg);
                    txed = 1;
                } else if (nvnr == 20) {
                    canmsg.b[d0] = OPC_NVANS;
                    canmsg.b[d1] = (NN_temp / 256) & 0xFF;
                    canmsg.b[d2] = (NN_temp % 256) & 0xFF;
                    canmsg.b[d3] = nvnr;
                    canmsg.b[d4] = CANID;
                    canmsg.b[dlc] = 5;
                    canbusSend(&canmsg);
                    txed = 1;
                }
            }
            break;

        case OPC_NVSET:
            if (thisNN(cmsg)) {
                byte nvnr = cmsg->b[d3];
                if (nvnr == 1) {
                    NV1 = cmsg->b[d4];
                    eeWrite(EE_NV, NV1);
                } else if (nvnr < 18) {
                    Ports[nvnr - 2].cfg = cmsg->b[d4];
                    eeWrite(EE_PORTCFG + (nvnr - 2), Ports[nvnr - 2].cfg);
                    configPort(nvnr - 2);
                } else if (nvnr == 20) {
                    CANID = cmsg->b[d4];
                    eeWrite(EE_CANID, CANID);
                }

            }
            break;

        case OPC_NNLRN:
            if (thisNN(cmsg)) {
                isLearning = TRUE;
            }
            break;

        case OPC_NNULN:
            if (thisNN(cmsg)) {
                isLearning = FALSE;
                LED2 = PORT_OFF;
            }
            break;

        case OPC_EVLRN:
            if (isLearning) {
                ushort evtnn = cmsg->b[d1] * 256 + cmsg->b[d2];
                ushort addr = cmsg->b[d3] * 256 + cmsg->b[d4];
                byte idx = cmsg->b[d5];
                byte val = cmsg->b[d6];
                if (idx < 16) {
                    Ports[idx].evtnn = evtnn;
                    Ports[idx].addr = addr;
                    eeWriteShort(EE_PORTNN + (2 * idx), evtnn);
                    eeWriteShort(EE_PORTADDR + (2 * idx), addr);
                }
                if (idx == 16) {
                    SOD = addr;
                    eeWrite(EE_SOD, addr / 256);
                    eeWrite(EE_SOD + 1, addr % 256);
                }
            }
            break;

        case OPC_NERD:
            if (thisNN(cmsg)) {
                doEV = 1;
                evIdx = 0;
                // start of day event
                {
                    CANMsg canmsg;
                    canmsg.b[d0] = OPC_ENRSP;
                    canmsg.b[d1] = (NN_temp / 256) & 0xFF;
                    canmsg.b[d2] = (NN_temp % 256) & 0xFF;
                    canmsg.b[d3] = 0;
                    canmsg.b[d4] = 0;
                    canmsg.b[d5] = SOD / 256;
                    canmsg.b[d6] = SOD % 256;
                    canmsg.b[d7] = 16;
                    canmsg.b[dlc] = 8;
                    canbusSend(&canmsg);
                }
                txed = 1;
            }
            break;


        default: break;
    }
    return txed;
}