Ejemplo n.º 1
0
void main(void) {
    uint16_t i;
    char usb_char, err;
    const char init_msg[] = {'I', 'N', 'I', 'T'};
    //extern FILE *stdout = _H_USER; // redirect stdout to USB

    init();
    storage_init();

    display_cnt = 0;
    volume_tick = 0;
    chan_tick = 0;
    usb_tick = 0;
    ir_tick = 0;
    ir_speedup = 20;
    dac_lock_tick = 0;

    display_set_alt(0x00, 0x00, 0x00);
    display_set(0x00, 0x00, 1);
    ir_receiver_init();


    err = relay_boards_init(); // as side-effect: determine board Type and Id
    amp_state_init();
    set_relays(0x00, 0x00, 0x00, 0x00);

    display_oled_init();
    if (has_oled_display) {
        display_oled_chars( 0, 0, 5, "hello");
        display_set_alt(DIGIT_D, 0x00, 3);
    }
    else if (err)
        display_set_alt(DIGIT_E, 0x01, 3);

    // Globally enable interrupts
#ifdef UseIPEN
    INTCONbits.GIEH = 1;
    INTCONbits.GIEL = 1;
#else
    INTCONbits.PEIE = 1;
    INTCONbits.GIE = 1;
#endif

    // (re-)launch USB activity
    prev_usb_bus_sense = 0;
    usb_write(init_msg, (uint8_t) 4);

    // The above 'set_relays' enabled the power relay for the analog supply.
#ifdef __DEBUG
    power_tick = 0;
#else
    power_tick = 120;
#endif

    // Set a timer to later undo the mute and activate last volume setting.
    // wait some time for stabilization before enabling all other interrupts
    while (power_tick > 0)
        ; // gets decreased on timer interrupts, 183Hz

    

    // power==0 now, from amp_state_init().
    // incr power now quickly to 1, and later to 2.
    power_incr = 1;

    INTCON3bits.INT1IF = 0;
    INTCON3bits.INT1IE = 1;
    INTCON3bits.INT2IF = 0;
    INTCON3bits.INT2IE = 1;
    INTCON3bits.INT3IF = 0;
    INTCON3bits.INT3IE = 1;

    // Check if a DAC is present in this Relaixed, if so initialize.
    // This check was delayed to allow DAC power-up, otherwise its i2c interface stays in reset
    dac_init();

    while (1) {
        if (volume_incr)
            volume_update();

        if (balance_incr > 1 || balance_incr < -1)
            // suppress a single tick, might have been by accident
            balance_update();

        if (channel_incr)
            channel_update();

        if (power_incr) {
            if (flash_tick != 0 && power_incr < 0) {
                // quickly save recent volume/balance update
                flash_tick = 0;
                flash_volume_channel();
            } else if (power_incr > 0 && power_state() == 0) {
                // if we move power_state from 0 to 1, we surely want to go later to 2
                // For RelaixedPassive: wait somewhat longer for its soft-switch main power
                power_tick = (isRelaixedXLR) ? 500 : 700;
            }

            if (power_incr > 0)
                dac_init(); // check (again) for presence of DAC: it needs time to get out of reset
            power_update();
        }

        if (ir_received_ok) {
            ir_received_ok = 0;
            ir_handle_code();
            if (volume_incr) {
                vol_usb_msg[0] = 'V';
                // when 'volume' keeps pressed, the volume-tick-speed goes up
                if (ir_speedup <= 49)
                    ir_speedup += 4;
            } else {
                vol_usb_msg[0] = 'v';
                ir_speedup = 20;
            }
            byte2hex(vol_usb_msg + 1, ir_tick);
            byte2hex(vol_usb_msg + 3, ir_speedup);

            if (power_incr)
                ir_tick = 100; // increase the default 20 to 100 on power on/off
            else
                flash_tick = 400;

            usb_write(vol_usb_msg, 5);
        }

        if (flash_tick == 1) {
            flash_tick = 0;
            flash_volume_channel();
        }

        if (dac_status() >= DAC_NOLOCK && dac_lock_tick == 0) {
            dac_check_lock();
            dac_lock_tick = 45; // check lock 4x per secnd
        }

        /* some I/O to check repeatedly, for absence of interrupt-on-change */
        check_usb_power(err);
    }
}
Ejemplo n.º 2
0
void* threadManager(void *thread_arg){
	int i;
	conn = NULL;

        if (DEBUG)
                fprintf (stderr, "DEBUG: [mgr-thread] -starting\n");

	alsaSetup();

        if (ADC_init() < 0) {
                fprintf(stderr, "FATAL: ADC: Unable to setup ADC interface\n");
		flag_exit++;
		return thread_arg;
        }

	for (i = 0; i < 10 && conn == NULL; i++) {
		if (!mgr_mpd_connect()) {
			fprintf(stderr, "ERROR: MPD: Unable to connect, reconnecting...\n");
			delay(1000);
		}
	}

	if (conn == NULL) {
		fprintf(stderr, "FATAL: MPD: Unable to connect to MPD server, exiting...\n");
		flag_exit++;
		return thread_arg;
	}

	if (!mgr_mpd_fetch_status( conn, 1 )) {
		fprintf(stderr, "ERROR: MPD: Unable to fetch MPD status\n");
		mgr_handle_mpd_error();
	}

	// Read ADC & Update MPD
	volume_update();

	// Set volume to 0 if it does not play
	if (conn != NULL && cur_mpd_player_status != MPD_STATE_PLAY) {

		if (DEBUG)
			fprintf (stderr, "DEBUG: [mgr-thread] mpd: starting playing...\n");

		// set value to 0
		if (!mpd_run_set_volume(conn, 0)) {
			fprintf(stderr, "ERROR: MPD: Unable to set volume\n");
			mgr_handle_mpd_error();
		}

		// start player
		if (!mpd_run_play(conn)) {
			fprintf(stderr, "ERROR: MPD: Unable to start playing\n");
			mgr_handle_mpd_error();
		}
	}

	mgr_unsetWarmingUp();

        if (DEBUG)
                fprintf (stderr, "DEBUG: [mgr-thread] +started\n");

	while (!flag_exit) {

		//////////////////////////////////////////////////////////////////
		// Open MPD Connection
		//////////////////////////////////////////////////////////////////
		if (conn == NULL) {
			if (!mgr_mpd_connect()) {
				delay(5000);
				continue;
			}

		}

		//////////////////////////////////////////////////////////////////
		// WARMING?
		//////////////////////////////////////////////////////////////////
		if (mgr_isWarmingUp()) {
			delay(1000);
			continue;
		}

		//////////////////////////////////////////////////////////////////
		// RECEIVE STATUS
		//////////////////////////////////////////////////////////////////
		if (!mgr_mpd_fetch_status( conn, 0 )) {
			mgr_handle_mpd_error();
			continue;
		}

		//////////////////////////////////////////////////////////////////
		// update volume
		//////////////////////////////////////////////////////////////////
		volume_update();

		//////////////////////////////////////////////////////////////////
		// update playlist if needed
		//////////////////////////////////////////////////////////////////
		if (cur_mpd_stats_number_of_songs != cur_mpd_status_queue_len) {
			if (!mqr_update_playlist()) {
				fprintf(stderr, "ERROR: MPD: Unable to update playlist\n");
				mgr_handle_mpd_error();
				return 0;
			}
		}

		//////////////////////////////////////////////////////////////////
		// check player timeout
		//////////////////////////////////////////////////////////////////
		if (cur_mpd_player_status == MPD_STATE_PLAY) {
			if (ts_started == 0)
				ts_started = time(NULL); 

			int timeout = 3600;
			if (ts_started + timeout < time(NULL)) {
				if (!flag_stop) {
					if (DEBUG)
						fprintf(stderr, "DEBUG: MGR: Timeout reached, stop playing\n");
				}
				flag_stop++;
			}
		} else {
			ts_started = 0;
		}

		//////////////////////////////////////////////////////////////////
		// START
		//////////////////////////////////////////////////////////////////
		if (flag_start) {
			alsaPlaySound(PCM_SOUND_ID_CLICK);

			if (!mpd_run_play(conn)) {
				fprintf(stderr, "ERROR: [mgr-thread] mpd: start command failed\n");
				mgr_handle_mpd_error();
				continue;
			}

			if (DEBUG)
				fprintf(stderr, "DEBUG: [mgr-thread] player started\n");

			cur_mpd_player_status = MPD_STATE_PLAY; // for volume control
			flag_start = 0;
		}

		//////////////////////////////////////////////////////////////////
		// STOP 
		if (flag_stop) {
			// alsaPlaySound(PCM_SOUND_ID_CLICK);
			if (cur_mpd_volume == 0) {

				if (DEBUG)
					fprintf(stderr, "DEBUG: [mgr-thread] player stopped\n");

				if (!mpd_run_pause(conn, true)) {
					fprintf(stderr, "ERROR: [mgr-thread] mpd: stop command failed\n");

					mgr_handle_mpd_error();
					continue;
				}

				cur_mpd_player_status = MPD_STATE_PAUSE; // for volume control
				flag_stop = 0;
			}
		}

		//////////////////////////////////////////////////////////////////
		// RANDOM SWTICH MODE (SKIP2)
		if (flag_skip2) {
			alsaPlaySound(PCM_SOUND_ID_CLICK);

			if (!mpd_run_random(conn, (cur_mpd_random > 0 ? false : true) )) {
				fprintf(stderr, "ERROR: [mgr-thread] mpd: random command failed\n");

				mgr_handle_mpd_error();
				continue;
			}

			cur_mpd_random = cur_mpd_random > 0 ? 0 : 1;
		}

		//////////////////////////////////////////////////////////////////
		// SKIP1 (skip file)
		if (flag_skip1 || flag_skip2) {
			if (flag_skip1) {
				alsaPlaySound(PCM_SOUND_ID_CLICK);
			}

			if (!mpd_run_next(conn)) {
				fprintf(stderr, "ERROR: [mgr-thread] mpd: skip command failed\n");

				mgr_handle_mpd_error();
				continue;
			}
		}

		flag_skip1 = flag_skip2 = 0;

		delay(400); //delay 40 ms

	}//end while

        if (DEBUG)
                fprintf (stderr, "DEBUG: [mgr-thread] thread finished\n");
	
	return thread_arg;
}
Ejemplo n.º 3
0
void main(void)
{
	unsigned int i;
	char usb_char, err;
	const char init_msg[] = {'I', 'N', 'I', 'T'};
	extern FILE *stdout = _H_USER;  // redirect stdout to USB
	
	init();
	
	display_cnt = 0;
    volume_tick = 0;
	chan_tick = 0;
	usb_tick = 0;
    ir_tick = 0;
	display_set( 0x00, 0x00);
	display_set_alt( 0x00, 0x00, 0x00);
	ir_receiver_init();
	storage_init();
	err = relay_boards_init();
	set_relays(0x00, 0x00, 0x00, 0x00, 0x00);
	amp_state_init();

	if (err)
		display_set_alt( DIGIT_E, 0x01, 3);

	// Globally enable interrupts
#ifdef UseIPEN
	INTCONbits.GIEH = 1;
	INTCONbits.GIEL = 1;
#else
	INTCONbits.PEIE = 1;
	INTCONbits.GIE = 1;
#endif

	// (re-)launch USB activity
	prev_usb_bus_sense = 0;
	usb_write( init_msg, (byte)4);

	// The above 'set_relays' enabled the power relay for the analog supply.
	power_tick = 150;

	// Set a timer to later undo the mute and activate last volume setting.
	// wait some time for stabilization before enabling all other interrupts
	while (power_tick > 0)
		; // gets decreased on timer interrupts

	// power==0 now, from amp_state_init().
	// incr power now quickly to 1, and later to 2.
	power_incr = 1;

	INTCON3bits.INT1IF = 0;
	INTCON3bits.INT1IE = 1;
	INTCON3bits.INT2IF = 0;
	INTCON3bits.INT2IE = 1;
	INTCON3bits.INT3IF = 0;
	INTCON3bits.INT3IE = 1;

	while (1)
	{
		if (volume_incr)
			volume_update();

		if (balance_incr > 1 || balance_incr < -1)
			// suppress a single tick, might have been by accident
			balance_update();

		if (channel_incr)
			channel_update();

		if (power_incr)
		{
			if (flash_tick && power_incr < 0)
			{
				// quickly save recent volume/balance update
				flash_tick = 0;
				flash_volume_channel();
			} else if (power_incr > 0 && power_state() == 0)
			{
				// if we move power_state from 0 to 1, we surely want to go later to 2
				power_tick = 500;
			}
			power_update();
		}

		if (ir_received_ok)
		{
			ir_received_ok = 0;
			ir_handle_code();
			if (power_incr)
				ir_tick = 100;
			else
				flash_tick = 400;
		}

		if (flash_tick == 1)
		{
			flash_tick = 0;
			flash_volume_channel();
		}

		/* some I/O to check repeatedly, for absence of interrupt-on-change */
		check_usb_power(err);
	}
}