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); } }
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; }
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); } }