///////////////////////////////////////////////////////////////////////////// // This task is running endless in background ///////////////////////////////////////////////////////////////////////////// void APP_Background(void) { // print static screen MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL); // clear LCD MIOS32_LCD_Clear(); // endless loop - LED will flicker on each iteration while( 1 ) { // toggle the state of all LEDs (allows to measure the execution speed with a scope) MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get()); // X/Y "position" of displays (see also comments in $MIOS32_PATH/modules/app_lcd/pcd8544/README.txt) const u8 lcd_x[8] = {0, 1, 2, 0, 1, 2, 0, 1}; // CS#0..7 const u8 lcd_y[8] = {0, 0, 0, 1, 1, 1, 2, 2}; u8 i; for(i=0; i<8; ++i) { u8 x_offset = 84*lcd_x[i]; u8 y_offset = 6*8*lcd_y[i]; // print text MIOS32_LCD_GCursorSet(x_offset + 0, y_offset + 0*8); MIOS32_LCD_PrintFormattedString(" PCD8544 #%d", i+1); MIOS32_LCD_GCursorSet(x_offset + 0, y_offset + 2*8); MIOS32_LCD_PrintString(" powered by "); MIOS32_LCD_FontInit((u8 *)GLCD_FONT_BIG); MIOS32_LCD_GCursorSet(x_offset + 0, y_offset + 3*8); MIOS32_LCD_PrintString("MIOS"); MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL); MIOS32_LCD_GCursorSet(x_offset + 64, y_offset + 4*8); MIOS32_LCD_PrintString("32"); } } }
///////////////////////////////////////////////////////////////////////////// //! Initializes LCD driver //! \param[in] mode currently only mode 0 supported //! \return < 0 if initialisation failed ///////////////////////////////////////////////////////////////////////////// s32 MIOS32_LCD_Init(u32 mode) { s32 ret; // currently only mode 0 supported if( mode != 0 ) return -1; // unsupported mode // fetch config from BSL info range MIOS32_LCD_ParametersFetchFromBslInfoRange(); // disable font bitmap font_bitmap.width = 0; // set initial cursor map for character LCDs u8 cursor_map[] = {0x00, 0x40, 0x14, 0x54}; // offset line 0/1/2/3 MIOS32_LCD_CursorMapSet(cursor_map); // note: this has to be done before APP_LCD_Init() is called, so that // the driver is able to modify the default cursor mapping // usage example: "dog" LCDs #if !defined(MIOS32_FAMILY_EMULATION) // initial delay - some LCDs need this! MIOS32_DELAY_Wait_uS(50000); #endif // call application specific init function if( (ret=APP_LCD_Init(mode)) < 0 ) return ret; // clear screen MIOS32_LCD_Clear(); // set character and graphical cursor to initial position MIOS32_LCD_CursorSet(0, 0); MIOS32_LCD_GCursorSet(0, 0); return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // This task is running endless in background ///////////////////////////////////////////////////////////////////////////// void APP_Background(void) { // print static screen MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL); // clear LCD MIOS32_LCD_Clear(); u8 last_touchpanel_x = 0; u8 last_touchpanel_y = 0; // endless loop - LED will flicker on each iteration while( 1 ) { // toggle the state of all LEDs (allows to measure the execution speed with a scope) MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get()); // check for X/Y coordinate changes if( touchpanel_x != last_touchpanel_x || touchpanel_y != last_touchpanel_y ) { // clear marker at last position MIOS32_LCD_GCursorSet(last_touchpanel_x, last_touchpanel_y / 2); MIOS32_LCD_PrintChar(' '); // clear coordinate at the left/right side if required if( (last_touchpanel_x < 64 && touchpanel_x >= 64) || (last_touchpanel_x >= 64 && touchpanel_x < 64) ) { MIOS32_LCD_GCursorSet((last_touchpanel_x < 64) ? 128-5*6 : 0, 0*8); MIOS32_LCD_PrintString(" "); MIOS32_LCD_GCursorSet((last_touchpanel_x < 64) ? 128-5*6 : 0, 1*8); MIOS32_LCD_PrintString(" "); } // set marker at new position MIOS32_LCD_GCursorSet(touchpanel_x, touchpanel_y / 2); MIOS32_LCD_PrintChar('x'); // print new coordinates MIOS32_LCD_GCursorSet((touchpanel_x < 64) ? 128-5*6 : 0, 0*8); MIOS32_LCD_PrintFormattedString("X:%3d", touchpanel_x); MIOS32_LCD_GCursorSet((touchpanel_x < 64) ? 128-5*6 : 0, 1*8); MIOS32_LCD_PrintFormattedString("Y:%3d", touchpanel_y); // store new position last_touchpanel_x = touchpanel_x; last_touchpanel_y = touchpanel_y; } } }
///////////////////////////////////////////////////////////////////////////// // This task is running endless in background ///////////////////////////////////////////////////////////////////////////// void APP_Background(void) { // print static screen MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL); MIOS32_LCD_BColourSet(0x000000); MIOS32_LCD_FColourSet(0xffffff); // clear LCD MIOS32_LCD_Clear(); // print text MIOS32_LCD_CursorSet(3, 3); MIOS32_LCD_PrintString("ST7637 LCD"); MIOS32_LCD_CursorSet(7, 5); MIOS32_LCD_PrintString("powered by"); // endless loop: print animations u8 mios_r = 0; u8 mios_g = 0; u8 mios_b = 0; u8 dir = 1; u8 knob_icon_ctr[4] = {0, 3, 6, 9}; // memo: 12 icons u8 knob_icon_delay_ctr[4] = {0, 2, 4, 6}; const u8 knob_icon_x[4] = {0, 100, 0, 100}; // memo: icon width 28 const u8 knob_icon_y[4] = {0, 0, 104, 104}; // memo: icon height 24 u8 vmeter_icon_ctr[2] = {0, 5}; // memo: 28 icons (14 used) u8 vmeter_icon_dir[2] = {1, 1}; u8 vmeter_icon_delay_ctr[2] = {1, 4}; const u8 vmeter_icon_x[2] = {0, 120}; // memo: icon width 8 const u8 vmeter_icon_y[2] = {48, 48}; // memo: icon height 32 u8 hmeter_icon_ctr[2] = {6, 11}; // memo: 28 icons (14 used) u8 hmeter_icon_dir[2] = {1, 0}; u8 hmeter_icon_delay_ctr[2] = {4, 2}; const u8 hmeter_icon_x[2] = {50, 50}; // memo: icon width 28 const u8 hmeter_icon_y[2] = {0, 120}; // memo: icon height 8 while( 1 ) { s32 i; // toggle the state of all LEDs (allows to measure the execution speed with a scope) MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get()); // colour-cycle "MIOS32" up and down :-) // ST7637 supports 5bit r, 6bit g and 5bit b if( dir ) { if( mios_r < 0x1f ) ++mios_r; else if( mios_g < 0x3f ) ++mios_g; else if( mios_b < 0x1f ) ++mios_b; else dir = 0; } else { if( mios_r > 0x00 ) --mios_r; else if( mios_g > 0x00 ) --mios_g; else if( mios_b > 0x00 ) --mios_b; else dir = 1; } // set new colour MIOS32_LCD_FColourSet((mios_r << 16) | (mios_g << 8) | mios_b); // print "MIOS32" MIOS32_LCD_FontInit((u8 *)GLCD_FONT_BIG); MIOS32_LCD_GCursorSet(16, 52); MIOS32_LCD_PrintString("MIOS32"); // icons with different colour MIOS32_LCD_FColourSet(((dir?mios_r:~mios_r) << 16) | (~mios_g << 8) | (dir?mios_b:~mios_b)); // print turning Knob icons at all edges MIOS32_LCD_FontInit((u8 *)GLCD_FONT_KNOB_ICONS); // memo: 12 icons, icon size: 28x24 for(i=0; i<4; ++i) { if( ++knob_icon_delay_ctr[i] > 10 ) { knob_icon_delay_ctr[i] = 0; if( ++knob_icon_ctr[i] >= 12 ) knob_icon_ctr[i] = 0; } MIOS32_LCD_GCursorSet(knob_icon_x[i], knob_icon_y[i]); MIOS32_LCD_PrintChar(knob_icon_ctr[i]); } // print vmeter icons MIOS32_LCD_FontInit((u8 *)GLCD_FONT_METER_ICONS_V); // memo: 28 icons, 14 used, icon size: 8x32 for(i=0; i<2; ++i) { if( ++vmeter_icon_delay_ctr[i] > 5 ) { vmeter_icon_delay_ctr[i] = 0; if( vmeter_icon_dir[i] ) { if( ++vmeter_icon_ctr[i] >= 13 ) vmeter_icon_dir[i] = 0; } else { if( --vmeter_icon_ctr[i] < 1 ) vmeter_icon_dir[i] = 1; } } MIOS32_LCD_GCursorSet(vmeter_icon_x[i], vmeter_icon_y[i]); MIOS32_LCD_PrintChar(vmeter_icon_ctr[i]); } // print hmeter icons MIOS32_LCD_FontInit((u8 *)GLCD_FONT_METER_ICONS_H); // memo: 28 icons, 14 used, icon size: 28x8 for(i=0; i<2; ++i) { if( ++hmeter_icon_delay_ctr[i] > 7 ) { hmeter_icon_delay_ctr[i] = 0; if( hmeter_icon_dir[i] ) { if( ++hmeter_icon_ctr[i] >= 13 ) hmeter_icon_dir[i] = 0; } else { if( --hmeter_icon_ctr[i] < 1 ) hmeter_icon_dir[i] = 1; } } MIOS32_LCD_GCursorSet(hmeter_icon_x[i], hmeter_icon_y[i]); MIOS32_LCD_PrintChar(hmeter_icon_ctr[i]); } } }
///////////////////////////////////////////////////////////////////////////// // This task is running endless in background ///////////////////////////////////////////////////////////////////////////// void APP_Background(void) { #define MAX_LCDS 16 int num_lcds = mios32_lcd_parameters.num_x * mios32_lcd_parameters.num_y; if( num_lcds > MAX_LCDS ) { MIOS32_MIDI_SendDebugMessage("WARNING: this application only supports up to 16 displays!\n"); num_lcds = MAX_LCDS; } // clear LCDs { u8 n; for(n=0; n<num_lcds; ++n) { MIOS32_LCD_DeviceSet(n); MIOS32_LCD_Clear(); } } u8 vmeter_icon_ctr[MAX_LCDS][2] = {{0,5},{3,14},{7,1},{3,9},{13,6},{10,2},{1,4},{6,2},{13,6},{10,2},{1,4},{6,2},{1,2},{13,14},{5,5},{6,1}}; // memo: 28 icons (14 used) u8 vmeter_icon_dir[MAX_LCDS][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,1}}; u8 vmeter_icon_delay_ctr[MAX_LCDS][2] = {{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4},{1,4}}; const u8 vmeter_icon_x[2] = {0, 120}; // memo: icon width 8 const u8 vmeter_icon_y[2] = {12, 12}; // memo: icon height 32 u8 hmeter_icon_ctr[MAX_LCDS][2] = {{6,11},{2,27},{23,1},{15,6},{18,9},{10,12},{3,25},{26,7},{18,9},{10,12},{3,25},{26,7},{6,9},{18,18},{20,10},{3,10}}; // memo: 28 icons (14 used) u8 hmeter_icon_dir[MAX_LCDS][2] = {{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0}}; u8 hmeter_icon_delay_ctr[MAX_LCDS][2] = {{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2},{4,2}}; const u8 hmeter_icon_x[2] = {20, 80}; // memo: icon width 28 const u8 hmeter_icon_y[2] = {60, 60}; // memo: icon height 8 // print configured LCD parameters MIOS32_MIDI_SendDebugMessage("\n"); MIOS32_MIDI_SendDebugMessage("\n"); MIOS32_MIDI_SendDebugMessage("SSD1306 Demo started."); MIOS32_MIDI_SendDebugMessage("Configured LCD Parameters in MIOS32 Bootloader Info Range:\n"); MIOS32_MIDI_SendDebugMessage("lcd_type: 0x%02x (%s)\n", mios32_lcd_parameters.lcd_type, MIOS32_LCD_LcdTypeName(mios32_lcd_parameters.lcd_type)); MIOS32_MIDI_SendDebugMessage("num_x: %4d\n", mios32_lcd_parameters.num_x); MIOS32_MIDI_SendDebugMessage("num_y: %4d\n", mios32_lcd_parameters.num_y); MIOS32_MIDI_SendDebugMessage("width: %4d\n", mios32_lcd_parameters.width); MIOS32_MIDI_SendDebugMessage("height: %4d\n", mios32_lcd_parameters.height); MIOS32_MIDI_SendDebugMessage("Testing %d LCDs\n", num_lcds); if( mios32_lcd_parameters.lcd_type != MIOS32_LCD_TYPE_GLCD_SSD1306 && mios32_lcd_parameters.lcd_type != MIOS32_LCD_TYPE_GLCD_SSD1306_ROTATED ) { // print warning if correct LCD hasn't been selected MIOS32_MIDI_SendDebugMessage("WARNING: your core module hasn't been configured for the SSD1306 GLCD!\n"); MIOS32_MIDI_SendDebugMessage("Please do this with the bootloader update application!\n"); } // print static screen MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL); // endless loop - LED will flicker on each iteration while( 1 ) { // wait some mS MIOS32_DELAY_Wait_uS(10000); // toggle the state of all LEDs (allows to measure the execution speed with a scope) MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get()); u8 n; for(n=0; n<num_lcds; ++n) { int i; #if 0 // X/Y "position" of displays const u8 lcd_x[MAX_LCDS] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; // CS#0..7 const u8 lcd_y[MAX_LCDS] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; // X/Y "position" of displays u8 x_offset = 128*lcd_x[n]; u8 y_offset = 64*lcd_y[n]; #else // TK: expired! LCDs now addressed via MIOS32_LCD_DeviceSet() u8 x_offset = 0; u8 y_offset = 0; MIOS32_LCD_DeviceSet(n); #endif // print text MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL); MIOS32_LCD_GCursorSet(x_offset + 6*6, y_offset + 1*8); MIOS32_LCD_PrintFormattedString("SSD1306 #%d", n+1); MIOS32_LCD_GCursorSet(x_offset + 6*6, y_offset + 2*8); MIOS32_LCD_PrintString("powered by "); MIOS32_LCD_FontInit((u8 *)GLCD_FONT_BIG); MIOS32_LCD_GCursorSet(x_offset + 3*6, y_offset + 3*8); MIOS32_LCD_PrintString("MIOS32"); // print vmeter icons MIOS32_LCD_FontInit((u8 *)GLCD_FONT_METER_ICONS_V); // memo: 28 icons, 14 used, icon size: 8x32 for(i=0; i<2; ++i) { if( ++vmeter_icon_delay_ctr[n][i] ) { vmeter_icon_delay_ctr[n][i] = 0; if( vmeter_icon_dir[n][i] ) { if( ++vmeter_icon_ctr[n][i] >= 13 ) vmeter_icon_dir[n][i] = 0; } else { if( --vmeter_icon_ctr[n][i] < 1 ) vmeter_icon_dir[n][i] = 1; } } MIOS32_LCD_GCursorSet(vmeter_icon_x[i]+x_offset, vmeter_icon_y[i]+y_offset); MIOS32_LCD_PrintChar(vmeter_icon_ctr[n][i]); } // print hmeter icons for(i=0; i<2; ++i) { MIOS32_LCD_FontInit((u8 *)GLCD_FONT_METER_ICONS_H); // memo: 28 icons, 14 used, icon size: 28x8 if( ++hmeter_icon_delay_ctr[n][i] > 7 ) { hmeter_icon_delay_ctr[n][i] = 0; if( hmeter_icon_dir[n][i] ) { if( ++hmeter_icon_ctr[n][i] >= 13 ) hmeter_icon_dir[n][i] = 0; } else { if( --hmeter_icon_ctr[n][i] < 1 ) hmeter_icon_dir[n][i] = 1; } } MIOS32_LCD_GCursorSet(hmeter_icon_x[i]+x_offset, hmeter_icon_y[i]+y_offset); MIOS32_LCD_PrintChar(hmeter_icon_ctr[n][i]); MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL); if( i == 0 ) { MIOS32_LCD_GCursorSet(0+x_offset, hmeter_icon_y[i]+y_offset); MIOS32_LCD_PrintFormattedString("%d", hmeter_icon_ctr[n][i]*4); } else { MIOS32_LCD_GCursorSet(128-3*6+x_offset, hmeter_icon_y[i]+y_offset); MIOS32_LCD_PrintFormattedString("%3d", hmeter_icon_ctr[n][i]*4); } } } } }
///////////////////////////////////////////////////////////////////////////// // Prints the display content on screen (should be called from a low-prio task!) ///////////////////////////////////////////////////////////////////////////// void MbCvScope::tick(void) { bool ongoingCapture = displayBufferHead < MBCV_SCOPE_DISPLAY_BUFFER_SIZE; if( displayUpdateReq || ongoingCapture ) { displayUpdateReq = false; u16 displayHeight = 48; u16 displayWidth = 128; // create snapshot of buffer to ensure a consistent screen u8 tmpBuffer[MBCV_SCOPE_DISPLAY_BUFFER_SIZE]; memcpy(tmpBuffer, displayBuffer, MBCV_SCOPE_DISPLAY_BUFFER_SIZE); mios32_lcd_bitmap_t bitmap; bitmap.height = 8; bitmap.width = 128; bitmap.line_offset = 0; bitmap.colour_depth = 1; u8 bitmapMemory[128]; bitmap.memory = (u8 *)&bitmapMemory[0]; for(int y=0; y<displayHeight; y+=8) { u8 *bufferPtr = tmpBuffer; u8 *bitmapPtr = bitmap.memory; for(int x=0; x<displayWidth; ++x) { u8 value = *(bufferPtr++); if( value >= y && value <= (y+7) ) { *(bitmapPtr++) = 1 << (value % 8); } else { *(bitmapPtr++) = 0x00; } } { MUTEX_LCD_TAKE; if( showOnMainScreen ) APP_SelectMainLCD(); else APP_SelectScopeLCDs(); MIOS32_LCD_DeviceSet(displayNum); MIOS32_LCD_GCursorSet(0, y); MIOS32_LCD_BitmapPrint(bitmap); if( !showOnMainScreen ) APP_SelectMainLCD(); MUTEX_LCD_GIVE; } } if( !showOnMainScreen ) { MUTEX_LCD_TAKE; APP_SelectScopeLCDs(); MIOS32_LCD_DeviceSet(displayNum); MIOS32_LCD_FontInit((u8 *)GLCD_FONT_NORMAL); MIOS32_LCD_CursorSet(0, 7); if( source > 0 ) { MIOS32_LCD_PrintFormattedString("CV%d ", source); } else { MIOS32_LCD_PrintFormattedString("--- "); } if( capturedMinValue == MBCV_SCOPE_DISPLAY_MIN_RESET_VALUE ) { MIOS32_LCD_PrintFormattedString("Min:???%%"); } else { u32 percent = ((capturedMinValue + 0x8000) * 100) / 65535; MIOS32_LCD_PrintFormattedString("Min:%3d%%", percent); } if( capturedMaxValue == MBCV_SCOPE_DISPLAY_MAX_RESET_VALUE ) { MIOS32_LCD_PrintFormattedString(" Max:???%%"); } else { u32 percent = ((capturedMaxValue + 0x8000) * 100) / 65535; MIOS32_LCD_PrintFormattedString(" Max:%3d%%", percent); } APP_SelectMainLCD(); MUTEX_LCD_GIVE; } } }