コード例 #1
0
ファイル: app.c プロジェクト: gillspice/mios32
/////////////////////////////////////////////////////////////////////////////
// Installed via MIOS32_MIDI_DirectRxCallback_Init
/////////////////////////////////////////////////////////////////////////////
static s32 NOTIFY_MIDI_Rx(mios32_midi_port_t port, u8 midi_byte)
{
  // check for MIDI clock
  if( midi_byte == 0xf8 ) {
    mios32_sys_time_t t = MIOS32_SYS_TimeGet();
    u32 timestamp = 1000*t.seconds + t.fraction_ms;

    DelayUpdate(&d_tick, timestamp);

    if( (midi_clock_ctr % 24) == 0 )
      DelayUpdate(&d_beat, timestamp);

    if( (midi_clock_ctr % 96) == 0 ) {
      DelayUpdate(&d_measure, timestamp);

      // force print message with each measure
      print_message = 1;
    }

    ++midi_clock_ctr;
    total_delay += d_tick.delay_last;

    return 0; // no error, no filtering
  }

  // check for MIDI start or continue
  if( midi_byte == 0xfa || midi_byte == 0xfb ) {
    mios32_sys_time_t t = MIOS32_SYS_TimeGet();
    u32 timestamp = 1000*t.seconds + t.fraction_ms;

    timestamp_midi_start = timestamp;

    u8 including_min_max = 0;
    DelayInit(&d_tick, including_min_max);
    DelayInit(&d_measure, including_min_max);
    DelayInit(&d_beat, including_min_max);

    midi_clock_ctr = 0;
    total_delay = 0;

    return 0; // no error, no filtering
  }

  // check for MIDI stop
  if( midi_byte == 0xfc ) {
    // invalidate measured delays
    u8 including_min_max = 0;
    DelayInit(&d_tick, including_min_max);
    DelayInit(&d_measure, including_min_max);
    DelayInit(&d_beat, including_min_max);

    return 0; // no error, no filtering
  }

  return 0; // no error, no filtering
}
コード例 #2
0
ファイル: app.c プロジェクト: JKcompute/395_midi_controller
/////////////////////////////////////////////////////////////////////////////
// This task is running endless in background
/////////////////////////////////////////////////////////////////////////////
void APP_Background(void)
{
  int i;
  struct ntp_tm tm;
  const char *month_names[] = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
	  
  const char *weekday_names[] = {
    "Sun", "Mon", "Tue", "Wed", 
    "Thu", "Fri", "Sat" };
  mios32_sys_time_t t;
  char timestring[64];
  // clear LCD screen
  MIOS32_LCD_Clear();

  // endless loop: print status information on LCD
  while( 1 ) {
    // new message requested?
    // TODO: add FreeRTOS specific queue handling!
    u8 new_msg = PRINT_MSG_NONE;
    portENTER_CRITICAL(); // port specific FreeRTOS function to disable tasks (nested)
    if( print_msg ) {
      new_msg = print_msg;
      print_msg = PRINT_MSG_NONE; // clear request
    }
    portEXIT_CRITICAL(); // port specific FreeRTOS function to enable tasks (nested)

    switch( new_msg ) {
      case PRINT_MSG_INIT:
		MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL);
        MIOS32_LCD_CursorSet(0, 0);
        MIOS32_LCD_PrintString("see README.txt   ");
        MIOS32_LCD_CursorSet(0, 1);
        MIOS32_LCD_PrintString("for details     ");
	break;

      case PRINT_MSG_STATUS:
      {
	    MIOS32_LCD_CursorSet(0, 0);
		// request status screen again (will stop once a new screen is requested by another task)
		print_msg = PRINT_MSG_STATUS;
      }
      break;
    }
	  

	t = MIOS32_SYS_TimeGet();
	// convert ntp seconds since 1900 into useful time structure
	ntp_tmtime(t.seconds, &tm);
 	// honour dailight savings
 	ntp_dst(&tm);
	MIOS32_LCD_FontInit((u8 *)GLCD_FONT_SMALL);
    MIOS32_LCD_CursorSet(15, 12);
	MIOS32_LCD_PrintFormattedString("%s %02d %s %04d %02d:%02d:%02d", weekday_names[tm.weekday], tm.day, month_names[tm.month-1], tm.year,tm.hour, tm.minute, tm.second);
  
	  
  }
}
コード例 #3
0
// returns current timestamp
static u32 tapTempoTimestamp(void)
{
#if 0
  // Problem: LPC17 doesn't deliver a timestamp which is accurate enough... (only second resolution)
  mios32_sys_time_t t = MIOS32_SYS_TimeGet();
  return 1000*t.seconds + t.fraction_ms;
#else
  return seq_core_timestamp_ms;
#endif
}
コード例 #4
0
ファイル: seq_terminal.c プロジェクト: gillspice/mios32
s32 SEQ_TERMINAL_PrintSystem(void *_output_function)
{
  void (*out)(char *format, ...) = _output_function;
  char str_buffer[128];

  MUTEX_MIDIOUT_TAKE;

  out("System Informations:\n");
  out("====================\n");
  out(MIOS32_LCD_BOOT_MSG_LINE1 " " MIOS32_LCD_BOOT_MSG_LINE2 "\n");

  mios32_sys_time_t t = MIOS32_SYS_TimeGet();
  int hours = (t.seconds / 3600) % 24;
  int minutes = (t.seconds % 3600) / 60;
  int seconds = (t.seconds % 3600) % 60;

  out("Operating System: MIOS32\n");
  out("Board: " MIOS32_BOARD_STR "\n");
  out("Chip Family: " MIOS32_FAMILY_STR "\n");
  if( MIOS32_SYS_SerialNumberGet((char *)str_buffer) >= 0 )
    out("Serial Number: %s\n", str_buffer);
  else
    out("Serial Number: ?\n");
  out("Flash Memory Size: %d bytes\n", MIOS32_SYS_FlashSizeGet());
  out("RAM Size: %d bytes\n", MIOS32_SYS_RAMSizeGet());

  out("Systime: %02d:%02d:%02d\n", hours, minutes, seconds);
  out("CPU Load: %02d%%\n", SEQ_STATISTICS_CurrentCPULoad());
  out("MIDI Scheduler: Alloc %3d/%3d Drops: %3d",
	    seq_midi_out_allocated, seq_midi_out_max_allocated, seq_midi_out_dropouts);

  u32 stopwatch_value_max = SEQ_STATISTICS_StopwatchGetValueMax();
  u32 stopwatch_value = SEQ_STATISTICS_StopwatchGetValue();
  if( stopwatch_value_max == 0xffffffff ) {
    out("Stopwatch: Overrun!\n");
  } else if( !stopwatch_value_max ) {
    out("Stopwatch: no result yet\n");
  } else {
    out("Stopwatch: %d/%d uS\n", stopwatch_value, stopwatch_value_max);
  }

#if !defined(MIOS32_FAMILY_EMULATION) && configGENERATE_RUN_TIME_STATS
  // send Run Time Stats to MIOS terminal
  out("FreeRTOS Task RunTime Stats:\n");
  FREERTOS_UTILS_RunTimeStats();
#endif

  out("done.\n");
  MUTEX_MIDIOUT_GIVE;

  return 0; // no error
}
コード例 #5
0
/////////////////////////////////////////////////////////////////////////////
// Hack: reinitializes the screens after some time, to clean up 
//       potentially garbled screens
//
/////////////////////////////////////////////////////////////////////////////
void reinit()
{
   mios32_sys_time_t t = MIOS32_SYS_TimeGet();
   charcount++;
   if (t.seconds > last_reinit_seconds || charcount > 500)
   {
      charcount = 0;
      last_reinit_seconds = t.seconds;
      
      MIOS32_BOARD_J15_RS_Set(0);
      MIOS32_BOARD_J15_RW_Set(0);
      APP_LCD_Cmd(0b00110011);
      APP_LCD_Cmd(0b00110010);

      APP_LCD_Cmd(0b00101000); // 4bit, 2 lines
      APP_LCD_Cmd(0b00001100); // display on, cursor off, char blinking off
      APP_LCD_Cmd(0b00000110); // entry mode
   }
}
コード例 #6
0
/////////////////////////////////////////////////////////////////////////////
// Handles Idle Counter (frequently called from Background task)
/////////////////////////////////////////////////////////////////////////////
s32 SEQ_STATISTICS_Idle(void)
{
  static u32 idle_ctr = 0;
  static u32 last_seconds = 0;

  // determine the CPU load
  ++idle_ctr;
  mios32_sys_time_t t = MIOS32_SYS_TimeGet();
  if( t.seconds != last_seconds ) {
    last_seconds = t.seconds;

    // MAX_IDLE_CTR defined in mios32_config.h
    // CPU Load is printed in main menu screen
    cpu_load_in_percent = 100 - ((100 * idle_ctr) / MAX_IDLE_CTR);

#if 0
    DEBUG_MSG("Load: %d%% (Ctr: %d)\n", cpu_load_in_percent, idle_ctr);
#endif
    
    idle_ctr = 0;
  }

  return 0; // no error
}
コード例 #7
0
/////////////////////////////////////////////////////////////////////////////
// Local button callback function
// Should return:
//   1 if value has been changed
//   0 if value hasn't been changed
//  -1 if invalid or unsupported button
/////////////////////////////////////////////////////////////////////////////
static s32 Button_Handler(seq_ui_button_t button, s32 depressed)
{

  if( SEQ_FILE_FormattingRequired() )
    return 0; // no button action as long as files not available
	
	u8 group;
	s32 status;
	
  switch( button ) {
		
		case SEQ_UI_BUTTON_Edit: {
			
			
			if ( depressed && (selected_page == PAGE_REMIX) ) {
					
				// we want to show vertical VU meters normal mode
				SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
				
				selected_page = PAGE_MAIN;		
				
				//
				// here we run the commands for remix states
				//
				u16 remix_map_tmp;
				
				// if we are in no preview_mode them call the demix procedment in case we got some request
				if ( (seq_pattern_remix_map != seq_pattern_demix_map) && ( remix_mode ) ) {
					remix_map_tmp = seq_pattern_remix_map;
					seq_pattern_remix_map = ~(seq_pattern_remix_map ^ seq_pattern_demix_map);
					
          if (ableton_api) {
						
            // TODO: implements a ableton remotescript to the clip control functionality
						
						u8 track;
						for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
						 
						 // if we got the track bit setup inside our remix_map, them do not send mixer data for that track channel, let it be mixed down
						 if ( ((1 << track) | seq_pattern_remix_map) == seq_pattern_remix_map ) {
							 // do nothing...
						 } else {
							 // delay our task for ableton get a breath before change the pattern line
							 vTaskDelay(50);
							 // send slot play envet to ableton: cc (111 + track) with value 127 to channel 16
							 MIOS32_MIDI_SendCC(ableton_port, 15, (111 + track), 127);
						 }
						 
						}           
						
          }
					
					// if we are in remix mode lets start the process
					if (remix_map_tmp == 0) {
												
						//pattern_name = pattern_name_remix;
						preview_mode = 0;
						remix_mode = 0;
						// set the pattern_remix_timer reference
						pattern_remix_timer = MIOS32_SYS_TimeGet();
						
					}
					
					// Change Pattern
					u8 group;
					for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
						// change pattern
						SEQ_PATTERN_Change(group, seq_pattern[group], 0);
					}
					
					// copy the pattern name for future reference
					sprintf(pattern_name, seq_pattern_name[0]);
					
					// getting back
					seq_pattern_remix_map = remix_map_tmp;
					seq_pattern_demix_map = seq_pattern_remix_map;
					
				}
				
			} else if ( !depressed ) {		
				
				// we want to show horizontal VU meters in remix mode
				SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_HBars);
				
				selected_page = PAGE_REMIX;
			}
				
			return 1;	
				
		} break;				
			
    case SEQ_UI_BUTTON_Select: {
			
      if(!depressed) {
        selected_page = PAGE_OPTION;
        return 1;
      }
			
      if( (depressed) && (selected_page == PAGE_OPTION) ) {
        selected_page = PAGE_MAIN;
      }
			
		} break;
			
		default:
			break;
			
			
  }

  if( depressed ) return 0; // ignore when button depressed if its not SEQ_UI_BUTTON_Select or SEQ_UI_BUTTON_Edit
	
  switch( selected_page ) {

    ///////////////////////////////////////////////////////////////////////////
    // REMIX PAGE
    case PAGE_REMIX: {

      if( button <= SEQ_UI_BUTTON_GP16 ) {
        // re-using encoder routine
        return Encoder_Handler(button, 0);
      }			
			
    } break;

    ///////////////////////////////////////////////////////////////////////////
    // OPTION PAGE
    case PAGE_OPTION: {

      switch( button ) {

        case SEQ_UI_BUTTON_GP1:
          // Save Pattern(all 4 groups at once)
          for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
						
            if( (status=SEQ_PATTERN_Save(group, seq_pattern[group])) < 0 ) {
              SEQ_UI_SDCardErrMsg(2000, status);
              return 0;
            }
						
          }
					
          // Save the pattern mixer
          SEQ_MIXER_Save(SEQ_MIXER_NumGet());
					
          break;

        case SEQ_UI_BUTTON_GP2:
          // Edit Pattern Name
					//SEQ_LCD_Clear();
          selected_page = PAGE_NAME_EDIT;
          break;

        case SEQ_UI_BUTTON_GP3:
          // Copy Pattern
					// We are going to use the multicopy procedure
					SEQ_UI_PATTERN_Copy();

					// coping mixer
					SEQ_UI_MIXER_Copy();

          break;

        case SEQ_UI_BUTTON_GP4:
          // Paste Pattern
					// We are going to use the multicopy procedure
					SEQ_UI_PATTERN_Paste();

					// paste mixer
					SEQ_UI_MIXER_Paste();
			
          break;

        case SEQ_UI_BUTTON_GP5:
        case SEQ_UI_BUTTON_GP6:
          return -1; // not mapped

        case SEQ_UI_BUTTON_GP7:
        case SEQ_UI_BUTTON_GP8:
          // Track Delay Page
					//SEQ_LCD_Clear();
          //selected_page = PAGE_TRK_DELAY;
          //break;
					return -1; // not mapped

        case SEQ_UI_BUTTON_GP9:
        case SEQ_UI_BUTTON_GP10:
					return -1; // not mapped

        case SEQ_UI_BUTTON_GP11:
        case SEQ_UI_BUTTON_GP12:
					return -1; // not mapped

        case SEQ_UI_BUTTON_GP13:
        case SEQ_UI_BUTTON_GP14:
          // Auto Save switch
          auto_save ^= 1;
          break;
          break;

        case SEQ_UI_BUTTON_GP15:
        case SEQ_UI_BUTTON_GP16:
					// Ableton API switch
          ableton_api ^= 1;
          return -1; // not mapped
      }

      return 0;

    } break;

    ///////////////////////////////////////////////////////////////////////////
    // PATTERN NAME EDIT PAGE
    case PAGE_NAME_EDIT: {

      return Encoder_Handler((seq_ui_encoder_t)button, 0);

    } break;

    ///////////////////////////////////////////////////////////////////////////
    // TRACK DELAY PAGE
    case PAGE_TRK_DELAY: {

    } break;

    ///////////////////////////////////////////////////////////////////////////
    // MAIN PAGE
    case PAGE_MAIN: {

      // Pattern Change Group Requests
      if( button <= SEQ_UI_BUTTON_GP8 ) {

        u8 group;
				
        for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
          if( selected_pattern[group].group == button ) {
            if( SEQ_FILE_B_NumPatterns(selected_pattern[group].bank) > 64 ) {
              selected_pattern[group].lower ^= 1;
            } else {
              selected_pattern[group].lower = 0; // toggling not required
            }
          } else {
            selected_pattern[group].group = button;
            preview_bank = button;
            //preview_mode = 0;
          }
        }
				
				SEQ_PATTERN_PeekName(selected_pattern[0], preview_name);
				preview_mode = 1;
				
        return 1; // value always changed
      }

      // Pattern Change Request
      if( button >= SEQ_UI_BUTTON_GP9 && button <= SEQ_UI_BUTTON_GP16 ) {

        //u8 group;

        s32 status = 0;

        // setting save patterns for later autosave procedure
        //for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group)
        //  save_pattern[group] = seq_pattern[group];
				
        // change preview pattern
        selected_pattern[0].num = button-8;
        selected_pattern[1].num = button-8;
        selected_pattern[2].num = button-8;
        selected_pattern[3].num = button-8;

        if ( !preview_mode )
        {
          preview_num = button-8;
          SEQ_PATTERN_PeekName(selected_pattern[0], preview_name);
          preview_mode = 1;
					
					// for security reasons in live environment, we can not accept rapid 2x press of pattern button.
					// if the buttons are not good quality they can send a 2x rapid signal os pressing in just one physical pressing
					// the time we need is bassicly the human time to read the name of patterns requested
			    // start time in count
			    pc_time_control = seq_core_timestamp_ms + 200;
					// vTaksDelay(200);
        } else {

					// 
					if ( remix_mode == 0 ) {
					
						//char str[30];
						//sprintf(str, "%d = %d %d = %d", selected_pattern[0].num, preview_num, selected_pattern[0].group, preview_bank);
						//SEQ_UI_Msg(SEQ_UI_MSG_USER, 2000, str, "debug");
						
						// Check for remix state
						if ( (selected_pattern[0].num == preview_num) &&  (selected_pattern[0].group == preview_bank) ) {
						
							//if ( pc_time_control >= seq_core_timestamp_ms )
							//	return 0; // do nothing, just to be shure we are not handle acidental double clicks, it happens!					
							
							// if we got some remix bit setup, enter in remix mode
							if (seq_pattern_remix_map != 0) {
								// set the remix mode
								remix_mode = 1;
							}
						
						}
						
					}
					
          // Change Pattern
          if ( (selected_pattern[0].num == preview_num) &&  (selected_pattern[0].group == preview_bank) ) {

  	        if ( pc_time_control >= seq_core_timestamp_ms )
	            return 0; // do nothing, just to be shure we are not handle acidental double clicks

						if (ableton_api) {
							
							u8 ableton_pattern_number = 0;
							
							//
							// ABLETON API PATTERN CHANGE HANDLE
							//
							// send ableton event to change the line clips
							if (selected_pattern[0].lower) {
						  	ableton_pattern_number = ((selected_pattern[0].group - 1) * 8) + button;
							} else {
						  	ableton_pattern_number = (((selected_pattern[0].group - 1) + 8) * 8) + button;
							}
							
							// midi_cc to send = 110
							// midi_chn = 16
							// midi_port = ableton_port
							// here we need to send a clip line change request
							MIOS32_MIDI_SendCC(ableton_port, 15, 110, ableton_pattern_number);
						
							// delay our task for ableton get a breath before change the pattern line
							vTaskDelay(50);

							// clip triggering
							u8 track;
            	for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
              
              	// if we got the track bit setup inside our remix_map, them do not send mixer data for that track channel, let it be mixed down
              	if ( ((1 << track) | seq_pattern_remix_map) == seq_pattern_remix_map ) {
                	// do nothing...
              	} else {
									// delay our task for ableton get a breath before change the pattern line
									vTaskDelay(50);									
									// send clip slot play envet to ableton cc (111 + track) with value 127 to channel 16
                	MIOS32_MIDI_SendCC(ableton_port, 15, (111 + track), 127);
              	}
              
            	}           

							// send a global clip change(all clips in the clip line)	
							// send play envet to ableton cc 20 with value 127 to channel 16
							//MIOS32_MIDI_SendCC(ableton_port, 15, 20, 127);

						}
						
						//
						// Autosave Pattern
						//
						if (auto_save) {
							
							// Autosave all 4 group of patterns
							for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
								
								// Save to SD Card
								if( (status=SEQ_PATTERN_Save(group, seq_pattern[group])) < 0 ) {
									SEQ_UI_SDCardErrMsg(2000, status);
								}
								
							}
							
							// Autosave Mixer Map
							SEQ_MIXER_Save(SEQ_MIXER_NumGet());
							
						}							
						
						// if we are not in remix mode 
						if (seq_pattern_remix_map == 0) {
							
							// keep the name of old pattern(because we still got 1 or more tracks belongs to this pattern)
							//pattern_name = seq_pattern_name;
							// set timer for mixed pattern
							pattern_remix_timer = MIOS32_SYS_TimeGet();
						}								
						
						//
						// Pattern change request
						//
            for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {

              // change pattern
              //selected_pattern[group].num = button-8;
              SEQ_PATTERN_Change(group, selected_pattern[group], 0);

							//if ( remix_mode ) {
								// keep the pattern name...
								//sprintf(seq_pattern_name[group], pattern_name);
							//}
							
            }
						
						if ( !remix_mode ) {
							// copy the pattern name for future reference
							//sprintf(pattern_name, seq_pattern_name[0]);	
							SEQ_PATTERN_PeekName(selected_pattern[0], pattern_name);
							// TODO: sync this with the pattern change handled by SEQ_PATTERN_Handler()
							//pattern_timer.seconds = 0;		
							preview_mode = 0;
						}
						
						// support for demix
            seq_pattern_demix_map = seq_pattern_remix_map;

            //preview_mode = 0;
						
          // Request a Pattern Preview
          } else {
            preview_num = button-8;
            SEQ_PATTERN_PeekName(selected_pattern[0], preview_name);

        	  // for security reasons in live environment, we can not accept 2x rapid press of pattern button.
      	    // if the buttons are not good quality they can send a 2x rapid signal os pressing in just one physical pressing
    	      // the time we need is bassicly the human time to read the name of patterns requested
  	        // start time in count
	          pc_time_control = seq_core_timestamp_ms + 200;

          }

        }			
				
        return 1; // value always changed
      }

      u8 visible_track = SEQ_UI_VisibleTrackGet();

      switch( button ) {

        case SEQ_UI_BUTTON_Right:
          // switch to next track
          if( visible_track < (SEQ_CORE_NUM_TRACKS - 1) )
            visible_track++;
					
          ui_selected_tracks = (1 << visible_track);
          ui_selected_group = visible_track / 4;

          return 1; // value always changed

        case SEQ_UI_BUTTON_Left:
          // switch to previous track
          if( visible_track >= 1 )
            visible_track--;
					
          ui_selected_tracks = (1 << visible_track);
          ui_selected_group = visible_track / 4;

          return 1; // value always changed

        case SEQ_UI_BUTTON_Up:
          return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);

        case SEQ_UI_BUTTON_Down:
          return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
      }

      return -1; // invalid or unsupported button

    } break;

    ///////////////////////////////////////////////////////////////////////////
    // Page do not exist
    default:
      break;

  }
	
	return 0;

}
コード例 #8
0
ファイル: seq_ui_info.c プロジェクト: glocklueng/MIOS32
/////////////////////////////////////////////////////////////////////////////
// Local Display Handler function
// IN: <high_prio>: if set, a high-priority LCD update is requested
/////////////////////////////////////////////////////////////////////////////
static s32 LCD_Handler(u8 high_prio)
{
  if( high_prio ) {
    SEQ_LCD_CursorSet(32, 0);
    mios32_sys_time_t t = MIOS32_SYS_TimeGet();
    int hours = (t.seconds / 3600) % 24;
    int minutes = (t.seconds % 3600) / 60;
    int seconds = (t.seconds % 3600) % 60;
    SEQ_LCD_PrintFormattedString("%02d:%02d:%02d", hours, minutes, seconds);
    return 0;
  }


  // layout:
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
  // <--------------------------------------><-------------------------------------->
  // About this MIDIbox:             00:00:00Stopwatch:   100/  300 uS  CPU Load: 40%
  //   System   Globals    Tracks  TrackInfo>MIDI Scheduler: Alloc   0/  0 Drops:   0


  // Select MIDI Device with GP Button:      10 Devices found under /sysex           
  //  xxxxxxxx  xxxxxxxx  xxxxxxxx  xxxxxxxx  xxxxxxxx  xxxxxxxx  xxxxxxxx  xxxxxxxx>



  ///////////////////////////////////////////////////////////////////////////
  SEQ_LCD_CursorSet(0, 0);
  SEQ_LCD_PrintString("About this MIDIbox:             ");

  ///////////////////////////////////////////////////////////////////////////
  SEQ_LCD_CursorSet(0, 1);

  SEQ_LCD_PrintList((char *)ui_global_dir_list, LIST_ENTRY_WIDTH, NUM_LIST_ITEMS, NUM_LIST_DISPLAYED_ITEMS, ui_selected_item, list_view_offset);

  ///////////////////////////////////////////////////////////////////////////
  switch( ui_selected_item + list_view_offset ) {
    case LIST_ITEM_SYSTEM: {
      u32 stopwatch_value_max = SEQ_STATISTICS_StopwatchGetValueMax();
      u32 stopwatch_value = SEQ_STATISTICS_StopwatchGetValue();

      SEQ_LCD_CursorSet(40, 0);
      if( stopwatch_value_max == 0xffffffff ) {
	SEQ_LCD_PrintFormattedString("Stopwatch: Overrun!     ");
      } else if( !stopwatch_value_max ) {
	SEQ_LCD_PrintFormattedString("Stopwatch: no result yet");
      } else {
	SEQ_LCD_PrintFormattedString("Stopwatch: %4d/%4d uS ", stopwatch_value, stopwatch_value_max);
      }
      SEQ_LCD_PrintSpaces(3);
      SEQ_LCD_PrintFormattedString("CPU Load: %02d%%", SEQ_STATISTICS_CurrentCPULoad());

      SEQ_LCD_CursorSet(40, 1);
      if( seq_midi_out_allocated > 1000 || seq_midi_out_max_allocated > 1000 || seq_midi_out_dropouts > 1000 ) {
	SEQ_LCD_PrintFormattedString("MIDI Scheduler: Alloc %4d/%4d Dr: %4d",
				     seq_midi_out_allocated, seq_midi_out_max_allocated, seq_midi_out_dropouts);
      } else {
	SEQ_LCD_PrintFormattedString("MIDI Scheduler: Alloc %3d/%3d Drops: %3d",
				     seq_midi_out_allocated, seq_midi_out_max_allocated, seq_midi_out_dropouts);
      }
    } break;

    default:
      SEQ_LCD_CursorSet(40, 0);
      //                  <---------------------------------------->
      SEQ_LCD_PrintString("Press SELECT to send Informations       ");
      SEQ_LCD_CursorSet(40, 1);
      SEQ_LCD_PrintString("to MIOS Terminal                        ");
  }

  return 0; // no error
}
コード例 #9
0
ファイル: app.c プロジェクト: JKcompute/395_midi_controller
static void TASK_MatrixScan(void *pvParameters)
{
  while( 1 ) {
    // wait for next timesplice (1 mS)
    vTaskDelay(1 / portTICK_RATE_MS);

    // determine timestamp (we need it for delay measurements)
    mios32_sys_time_t t = MIOS32_SYS_TimeGet();
    u32 timestamp = 1000*t.seconds + t.fraction_ms;

    // loop:
    //   - latch DIN/DOUT values
    //   - shift selection pattern for *next* row to DOUT registers
    //   - read DIN values of previously selected row
    // since we need to select the first row before the first DIN values are latched, we loop from -1
    // to handle the initial state
    int row;
    for(row=-1; row<MATRIX_NUM_ROWS; ++row) {
      if( row >= 0 ) { // not required for initial scan
	// latch DIN values
	MIOS32_SPI_RC_PinSet(MIOS32_SRIO_SPI, MIOS32_SRIO_SPI_RC_PIN, 0); // spi, rc_pin, pin_value
	MIOS32_DELAY_Wait_uS(1);
	MIOS32_SPI_RC_PinSet(MIOS32_SRIO_SPI, MIOS32_SRIO_SPI_RC_PIN, 1); // spi, rc_pin, pin_value
      }

      // determine selection mask for next row (written into DOUT registers while reading DIN registers)
      u16 select_row_pattern = ~(1 << (row+1));
#if MATRIX_DOUT_HAS_SINK_DRIVERS
      select_row_pattern ^= 0xffff; // invert selection pattern if sink drivers are connected to DOUT pins
#endif

      // read DIN, write DOUT
      u8 din0 = MIOS32_SPI_TransferByte(MIOS32_SRIO_SPI, (select_row_pattern >> 8) & 0xff);
      u8 din1 = MIOS32_SPI_TransferByte(MIOS32_SRIO_SPI, (select_row_pattern >> 0) & 0xff);

      // latch new DOUT value
      MIOS32_SPI_RC_PinSet(MIOS32_SRIO_SPI, MIOS32_SRIO_SPI_RC_PIN, 0); // spi, rc_pin, pin_value
      MIOS32_DELAY_Wait_uS(1);
      MIOS32_SPI_RC_PinSet(MIOS32_SRIO_SPI, MIOS32_SRIO_SPI_RC_PIN, 1); // spi, rc_pin, pin_value

      if( row >= 0 ) {
	// combine read DIN bytes to 16bit value
	u16 din_pattern = (din1 << 8) | din0;

	// check if values have been changed via XOR combination with previously scanned value
	u16 changed = din_pattern ^ din_value[row];
	if( changed ) {
	  // store changed value
	  din_value[row] = din_pattern;

	  // notify changed value
	  int column;
	  for(column=0; column<16; ++column) {
	    u16 mask = 1 << column;
	    if( changed & mask )
	      BUTTON_NotifyToggle(row, column, (din_pattern & mask) ? 1 : 0, timestamp);
	  }
	}
      }
    }
  }
}