Test

Dependencies:   BSP_DISCO_F429ZI LCD_DISCO_F429ZI mbed TS_DISCO_F429ZI

main.cpp

Committer:
jimk3038
Date:
2017-07-24
Revision:
1:39992c325c58
Parent:
0:a564383a9b15

File content as of revision 1:39992c325c58:

//
//  Powerhouse Electronics - Fluid Dispense System
//      By: Jim Kemp June 6th, 2017
//
//  Notes: Screen Size: 240x320

#include "TS_DISCO_F429ZI.h"
#include "LCD_DISCO_F429ZI.h"
#include "mbed.h"

#define FLASH_USER_START_ADDR   FLASH_SECTOR_10   	/* Start @ of user Flash area */
#define FLASH_USER_END_ADDR     FLASH_SECTOR_11     /* End @ of user Flash area */

#define TS_IDLE     		15  // Reset for touch screen idle. On idle, save values.
//#define BUFFER_SIZE         ((uint32_t)0x0100)
//#define WRITE_READ_ADDR     ((uint32_t)0x0800)
#define WRITE_READ_ADDR     ((uint32_t)0x0000)

LCD_DISCO_F429ZI lcd;
TS_DISCO_F429ZI ts;
Timer tsTimer;

DigitalOut led1(LED1);
bool tsPress( uint16_t *x, uint16_t *y );

// Used to define a bounding box by x,y and width, height.
typedef struct {
	uint16_t x, y;
	uint16_t width, height;
} box;

// Used to define a point.
typedef struct {
	uint16_t x, y;
} pt;

typedef enum { P0, P1, P2, P3, INC, DEC, NONE } winLocs_t;

const box butLeft =  { 0,   270,  110, 50 };
const box butRight = { 130, 270,  110, 50 };
const box parm0Win = { 0,0,   239, 55 };
const box parm1Win = { 0,60,  239, 55 };
const box parm2Win = { 0,120, 239, 55 };
const box parm3Win = { 0,180, 239, 55 };

static void SystemClock_Config();
bool testTouch( uint16_t x, uint16_t y, box b );
void myFillRect( LCD_DISCO_F429ZI lcd, box b );
void myDrawRect( LCD_DISCO_F429ZI lcd, box b, uint32_t color );
void dispParm( LCD_DISCO_F429ZI lcd, uint8_t parmNum, char *s, char *units, float val );
winLocs_t locateTouch( uint16_t x, uint16_t y );

uint32_t FirstSector = 0, NbOfSectors = 0, Address = 0;
uint32_t SectorError = 0;
__IO uint32_t data32 = 0 , MemoryProgramStatus = 0;

int main() {      
	led1 = 1;
	//char s[20];
	float cnt=20.0f, cnt2=12.0f, chg=0.1f;
	uint8_t status;
	uint16_t x=0, y=0;	// Touch Screen X/Y coord.
	uint8_t tsFast=0;	// Switch to fast change after a long touch.
	uint8_t tsIdle=0;	// After changes are made, on idle save values.
	winLocs_t activeWin = NONE;
	uint32_t vals[10];

	FLASH_EraseInitTypeDef EraseInitStruct;
	
    HAL_Init();
    SystemClock_Config();
	//wait( 1 );

	//vals[0] = (uint32_t)0;
	//vals[1] = (uint32_t)0;
	vals[0] = (uint32_t)222;
	vals[1] = (uint32_t)111;
	wait_ms( 50 );

	FirstSector = FLASH_USER_START_ADDR;
	/* Get the number of sector to erase from 1st sector*/
	NbOfSectors = FLASH_USER_END_ADDR - FirstSector + 1;
	
	/* Fill EraseInit structure*/
	EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
	EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3;
	EraseInitStruct.Sector = FirstSector;
	EraseInitStruct.NbSectors = NbOfSectors;

    HAL_FLASH_Unlock();
	__HAL_FLASH_CLEAR_FLAG( FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR 
		| FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR );
	//FLASH_Erase_Sector( FLASH_USER_START_ADDR, VOLTAGE_RANGE_3 );
	HAL_FLASHEx_Erase( &EraseInitStruct, &SectorError );

    Address = FLASH_USER_START_ADDR;
    HAL_FLASH_Program( TYPEPROGRAM_WORD, Address, vals[0]);
    HAL_FLASH_Program( TYPEPROGRAM_WORD, Address+4, vals[1]);
    HAL_FLASH_Lock();

	lcd.Clear( LCD_COLOR_BLACK );
	lcd.SetBackColor( LCD_COLOR_BLACK );
	lcd.SetTextColor( LCD_COLOR_WHITE );
	BSP_LCD_SetFont( &Font20 );
	lcd.DisplayStringAt( 0, LINE(4), (uint8_t *)"Powerhouse-", LEFT_MODE );
	lcd.DisplayStringAt( 0, LINE(5), (uint8_t *)"Electronics", CENTER_MODE );
	BSP_LCD_SetFont( &Font24 );
	lcd.DisplayStringAt( 0, LINE(8), (uint8_t *)"Ph-Elec.com", CENTER_MODE );
	printf( "\nPowerhouse Electronics\n" );
	printf( "Dispencer System\n" );

	Address = FLASH_USER_START_ADDR;
	vals[0] = *(__IO uint32_t*)Address;
	vals[1] = *(__IO uint32_t*)(Address+4);
	
	printf( "Read Data Done: %d %d\n", (int16_t)vals[0], (int16_t)vals[1] );

	wait( 1 );

	lcd.Clear(LCD_COLOR_BLACK);
	status = ts.Init( lcd.GetXSize(), lcd.GetYSize() );
	if ( status != TS_OK ) {
		lcd.Clear(LCD_COLOR_RED);
		lcd.SetBackColor(LCD_COLOR_RED);
		lcd.SetTextColor(LCD_COLOR_WHITE);
		lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN", CENTER_MODE);
		lcd.DisplayStringAt(0, LINE(6), (uint8_t *)"INIT FAIL", CENTER_MODE);
		while ( 1 );
	}

	printf( "Screen Size: %d / %d\n", lcd.GetXSize(), lcd.GetYSize() );

	lcd.SetTextColor(LCD_COLOR_BLUE);
	myFillRect( lcd, butLeft );
	myFillRect( lcd, butRight );
	lcd.SetBackColor(LCD_COLOR_BLUE);
	lcd.SetTextColor(LCD_COLOR_WHITE);
	BSP_LCD_SetFont(&Font24);
	lcd.DisplayStringAt( 20, LINE(12), (uint8_t *)"Inc.", LEFT_MODE);
	lcd.DisplayStringAt( 160, LINE(12), (uint8_t *)"Dec.", LEFT_MODE);
	lcd.SetBackColor(LCD_COLOR_BLACK);
	
	while ( 1 ) {
		
		if ( tsPress( &x, &y ) ) {
			if ( activeWin == P0 ) {
				if ( testTouch( x,y, butLeft ) ) {
					cnt += chg;
					if ( cnt >= 1000.0f ) cnt = 999.9f;
				}
				if ( testTouch( x,y, butRight ) ) {
					cnt -= chg;
					if ( cnt < 0.0f ) cnt = 0.0f;
				}
			}
			
			if ( activeWin == P1 ) {
				if ( testTouch( x,y, butLeft ) ) {
					cnt2 += chg;
					if ( cnt2 >= 1000.0f ) cnt2 = 999.9f;
				}
				if ( testTouch( x,y, butRight ) ) {
					cnt2 -= chg;
					if ( cnt2 < 0.0f ) cnt2 = 0.0f;
				}
			}

			tsFast += 1;
			if ( tsFast >  5 ) chg = 1.0;
			if ( tsFast > 25 ) chg = 10.0;
			if ( tsFast > 50 ) chg = 100.0;
			tsIdle = TS_IDLE;
		}
		else {
			tsFast = 0;
			chg = 0.1f;
			if ( tsIdle == 1 ) printf( "Save Values...\n" );
			if ( tsIdle ) --tsIdle;
		}

		// Update faster and faster when the ts is held down long.
		if ( tsFast < 5 ) wait( 0.3 );
		else if ( tsFast < 20 )	wait( 0.2 );
		else wait( 0.1 );

		dispParm( lcd, 0, "Dispense Speed:", "mm/min", cnt );
		dispParm( lcd, 1, "PreFill Dist:", "mm", cnt2 );
		dispParm( lcd, 2, "PostRetact Dist:", "mm", 12.0f );
		dispParm( lcd, 3, "Pre/Post Speed:", "mm/min", 100.0f );
		
		if( tsIdle == TS_IDLE ) {
			if( (locateTouch( x,y ) == P0) && (activeWin != P0) ) {
				printf( "P0 Selected.\n" );
				activeWin = P0;
				myDrawRect( lcd, parm0Win, LCD_COLOR_RED );
				myDrawRect( lcd, parm1Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm2Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm3Win, LCD_COLOR_BLACK );
			}

			if( (locateTouch( x,y ) == P1) && (activeWin != P1) ) {
				printf( "P1 Selected.\n" );
				activeWin = P1;
				myDrawRect( lcd, parm0Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm1Win, LCD_COLOR_RED );
				myDrawRect( lcd, parm2Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm3Win, LCD_COLOR_BLACK );
			}

			if( (locateTouch( x,y ) == P2) && (activeWin != P2) ) {
				printf( "P2 Selected.\n" );
				activeWin = P2;
				myDrawRect( lcd, parm0Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm1Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm2Win, LCD_COLOR_RED );
				myDrawRect( lcd, parm3Win, LCD_COLOR_BLACK );
			}

			if( (locateTouch( x,y ) == P3) && (activeWin != P3) ) {
				printf( "P3 Selected.\n" );
				activeWin = P3;
				myDrawRect( lcd, parm0Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm1Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm2Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm3Win, LCD_COLOR_RED );
			}
		}
		if ( tsIdle == 1 ) {
			if( activeWin != NONE ) {
				myDrawRect( lcd, parm0Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm1Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm2Win, LCD_COLOR_BLACK );
				myDrawRect( lcd, parm3Win, LCD_COLOR_BLACK );
				activeWin = NONE;
			}		
		}

		led1 = !led1;
	}
}

// ============================================================================
winLocs_t locateTouch( uint16_t x, uint16_t y ) {
	if( testTouch( x,y, parm0Win ) ) return P0; 
	if( testTouch( x,y, parm1Win ) ) return P1; 
	if( testTouch( x,y, parm2Win ) ) return P2; 
	if( testTouch( x,y, parm3Win ) ) return P3; 
	return NONE;
}

// Paint a parameter on the screen. 
// ============================================================================
void dispParm( LCD_DISCO_F429ZI lcd, uint8_t parmNum, char *s, char *units, float val ) {
	char str[20];
	uint16_t y = parmNum * 60;
	//box p;
	
	BSP_LCD_SetFont( &Font20 );
	lcd.DisplayStringAt(4, y+6, (uint8_t *)s, LEFT_MODE );
	BSP_LCD_SetFont( &Font24 );
	sprintf( str, "%5.1f%s ", val, units );
	lcd.DisplayStringAt( 0, y+30, (uint8_t *)str, RIGHT_MODE );
	
	//p.x=0; p.y=y;
	//p.width=239; p.height=55;
	//myDrawRect( lcd, p, LCD_COLOR_WHITE );
}

// Helper fuction to fill a rect given a lcd handle and a box struct.
// ============================================================================
void myFillRect( LCD_DISCO_F429ZI lcd, box b ) {
	lcd.FillRect( b.x, b.y,  b.width, b.height );
}

// ============================================================================
void myDrawRect( LCD_DISCO_F429ZI lcd, box b, uint32_t color ) {
	uint32_t tmpColor = lcd.GetTextColor();		// Save current color.
	
	lcd.SetTextColor( color );
	lcd.DrawRect( b.x, b.y,  b.width, b.height );
	// Draw an inner box to make the line 2 pixels wide.
	lcd.DrawRect( b.x+1, b.y+1,  b.width-2, b.height-2 );
	
	lcd.SetTextColor( tmpColor );				// Restore original color.
}


// Return true if x,y is within bounding box struct.
// ============================================================================
bool testTouch( uint16_t x, uint16_t y, box b ) {

	if ( (x <= b.x) || (x >= (b.x+b.width)) )		return false;
	if ( (y <= b.y) || (y >= (b.y+b.height)) )	return false;
	return true;
}

// Update the param X/Y values and return true if new touch values.
// ============================================================================
bool tsPress( uint16_t* xx, uint16_t* yy  ) {
	TS_StateTypeDef TS_State;
	static bool flgTouch=true;
	static uint16_t x=0, y=0;

	tsTimer.start();

	ts.GetState(&TS_State);      
	if ( TS_State.TouchDetected ) {
		x = TS_State.X;
		y = TS_State.Y;
		printf("* x=%d y=%d\n", x, y);
		tsTimer.reset();	// Reset on new touch.
		flgTouch = true;	// Set flag on new touch.
	}
	if ( flgTouch && (tsTimer.read_ms() > 250) ) {
		printf("  x=%d y=%d\n", x, y);
		flgTouch = false;
	}

	*xx = x; *yy = y;
	return flgTouch;	// Return true on touch.
}

static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  /* Enable Power Control clock */
  __PWR_CLK_ENABLE();
  
  /* The voltage scaling allows optimizing the power consumption when the device is 
     clocked below the maximum system frequency, to update the voltage scaling value 
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  
  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;  
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}