레이블이 touch인 게시물을 표시합니다. 모든 게시물 표시
레이블이 touch인 게시물을 표시합니다. 모든 게시물 표시

2015년 12월 26일 토요일

Five shades of gpio (Story of the bare matal) / GPIO 의 다섯개의 그레이

This is the short story related GPIO in STM32F4X , Story of the bare metal

요즘 전세계적으로 하드웨어에 대한 관심(Maker Movement)이 다시 일어나고 있는데, 주변에 물어볼 수 있는 사람이 없어서 (제가 질문한게 그게 아닌데, 당최 무신 소린지 다들 자신이 이해한 정도로만 설명해서)  저는 전공이 삽질이라서, 또 뻘짓을 해보았습니다.


개발 시간이 짧은 상업 프로젝트에서는 FPGA가 정답이라고 생각을 하지만, 똑깥은 뻘짓을 호기심에 하는 개발자들이 있을 것 같아서, 글을 남깁니다. 자고 일어나면 세상이 변하기에, 동일한 시행착오를 하지 않았으면 하는 마음에...


CPU           : STM32F405, STM32F415
Test Board  : MINI-M4 for STM32  ( http://www.mikroe.com/mini/stm32/ )
Compiler     : MikroE Pascal 4.7.0  


 
Fig 1. Test Board
        1. Mini-M4 STM32F4 / Ref. http://www.mikroe.com/mini/stm32/
        2. MaxPaper LPix v1.1 /Ref. http://www.maxpaer.com

 
Fig2. Toggling 84Mhz using GPIO Register ( Fully piped line processing )

 
Fig 3. Toggling 83Mhz using BSRR


 
Fig 4. Toggling 21Mhz using Bit-Band

 
Fig 5. Toggling 19Mhz using DMA (M2M, No Burst Mode, 16bit)

  
Fig 6. Toggling 17Mhz using Pascal



2010년 2월 21일 일요일

Maxpaper for Multi touch based on win7





윈도우7의 멀티터치 기능을 활용한 앨범 편집

한손으로 iphone들고 찍으니, 눈의 초점이 어긋나서 제대로 안됨.
쪼그만 삼각대라고 하나 사던지....
멀티터치 제스추어의 가능성을 보여주는 시연으로 ...

- UI 튜닝이 필요한 베타 단계


// ----------------------------------------------------------------------------
//
// Multi touch Implementation
//
// 크레딕스 최원식 (simonsayz@naver.com)
// - www.kredix.com
// - www.maxpaper.com
//
// History ------------------------------------------------------------------
// 2010.02.18 : 개발 시작 ( Based on Delphi7 ) ver 0.1
// 2010.02.18 : Rotate 버그 있음 (WM_touch에서도 동일하게 발생)
// (삼성 매직스테이션 DM-U200 문제로 판단됨)
// ----------------------------------------------------------------------------

Unit VCl_ObjViewer_Base_Touch;

Interface

Uses
Windows,Types,SysUtils;

Const
WM_GESTURENOTIFY = $011A;
WM_GESTURE = $0119;
WM_TOUCH = $0240;
//
WM_TABLET_DEFBASE = $02C0;
WM_TABLET_FLICK = WM_TABLET_DEFBASE + 11;
TOUCHEVENTF_UP = $0004;
//
TWF_FINETOUCH = $00000001;
TWF_WANTPALM = $00000002;

Type
HGESTUREINFO = type LongInt;// LongWord

HTouchInput = THandle;
UInt = DWord;
ULONGLONG = Int64;
ULONG_PTR = LongWord;
//
TGestureType = (gtNone,
gtBegin,
gtEnd,
gtZoom,
gtPan,
gtRotate,
gtTwoFingerTap,
gtPressAndTap);
TGestureState = (gsNone,
gsBegin,
gsWork,
gsEnd);
TGesture = Record
Type_ : TGestureType; // Gesture 형태
State : TGestureState; // Gesture 상태
XY : TPoint; // 위치
Value : Single; // 각도,확대
End;

// For window ----------------------------------------------------------------
TGestureNotifyStruct = Record
cbSize : UINT; // size, in bytes, of this structure
dwFlags : DWORD; // unused
hwndTarget : HWND; // handle to window targeted by the gesture
ptsLocation : TSmallPoint; // starting location
dwInstanceID : DWORD; // internally used
end;
PGestureNotifyStruct = ^TGestureNotifyStruct;
TWMGestureNotify = Packed record
Msg : Cardinal;
Unused : WPARAM;
NotifyStruct : PGestureNotifyStruct;
Result : Integer;
end;
TTouchInput = Record
x : Integer;
y : Integer;
hSource : THandle;
dwID : DWORD;
dwFlags : DWORD;
dwMask : DWORD;
dwTime : DWORD;
dwExtraInfo : ULONG_PTR;
cxContact : DWORD;
cyContact : DWORD;
End;
PTouchInput = ^TTouchInput;

// For Internal Operation & Dbg ----------------------------------------------
TGestureSet = (gsZoom,
gsZoomRotate,
gsAll);
TGestureSav = Record
Cnt : Integer;
State : TGestureState;
ullArguments : ULongLong;
//
ZoomPtPrev : TPoint;
ZoomFac : Single;
//
AngleSnap : Integer; // 화면 Snap Angle 임시저장
AnglePrev : Single; // Touch에서 받은 Angle
//
DbgAngle : Single;
DbgAngleSum : Single;
End;

Var
GestureSav : TGestureSav;

//
Function Gesture_Set (gsHandle : THandle;gsSet : TGestureSet) : Boolean;
Function Gesture_Get (_wParam : wParam; _lParam :lParam) : TGesture;
Function Gesture_Str (Gstr : TGesture) : String;
//
Function RegisterTouchWindow ( Handle : HWND;
ulFlags : Cardinal ): BOOL;
Function UnRegisterTouchWindow( Handle : HWND ): BOOL;
//
Function CloseTouchInputHandle( hTouchInput_ : HTOUCHINPUT ): BOOL;
Function GetTouchInputInfo ( hTouchInput : HTOUCHINPUT;
cInputs : UINT;
pInputs : PTOUCHINPUT;
cbSize : Integer ): BOOL;

Implementation

// http://wiki.helpmvp.com/home/notes/touch
Const
//
GF_Begin = $00000001;
GF_Inertia = $00000002;
GF_End = $00000004;
//
GC_ALLGESTURES = $00000001;
GC_ZOOM = $00000001;
GC_PAN = $00000001;
GC_PAN_WITH_SINGLE_FINGER_VERTICALLY = $00000002;
GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY = $00000004;
GC_PAN_WITH_GUTTER = $00000008;
GC_PAN_WITH_INERTIA = $00000010;
GC_ROTATE = $00000001;
GC_TWOFINGERTAP = $00000001;
GC_PRESSANDTAP = $00000001;
GC_ROLLOVER = GC_PRESSANDTAP;
//
GID_BEGIN = 1; // a generic gesture is beginning.
GID_END = 2; // a generic gesture end.
GID_ZOOM = 3; // zoom start, zoom move, or zoom stop.
GID_PAN = 4; // pan move or pan start.
GID_ROTATE = 5; // rotate move or rotate start.
GID_TWOFINGERTAP = 6; // two-finger tap gesture.
GID_PRESSANDTAP = 7; //
GID_RollOver = GID_PressAndTap;

Type
//
TGestureConfig = Record
dwID : DWORD; // gesture ID
dwWant : DWORD; // settings related to gesture ID that are to be turned on
dwBlock : DWORD; // settings related to gesture ID that are to be turned off
end;
PGestureConfig = ^TGestureConfig;
TConfigs = Array of TGestureConfig;
//
TGestureInfo = Record
cbSize : Longword;
dwFlags : DWord;
dwID : DWord;
hwndTarget : Hwnd;
ptsLocation : TSmallPoint;
dwInstanceID : DWord;
dwSequenceID : DWord;
ullArguments : ULongLong;
cbExtraArgs : UInt;
end;
PGestureInfo = ^TGestureInfo;

Var
_User32Handle : THandle;
_GetGestureInfo : Function ( hGestureInfo : HGESTUREINFO;
Var pGestureInfo : TGestureInfo): BOOL; stdcall;
_CloseGestureInfoHandle : Function ( hGestureInfo : HGESTUREINFO): BOOL; stdcall;
_SetGestureConfig : Function ( hwnd : HWND;
dwReserved : DWORD;
cIDs : UINT;
pGestureConfig: PGESTURECONFIG;
cbSize : UINT ): BOOL; stdcall;
_RegisterTouchWindow : Function ( hwnd : HWND;
ulFlags : Cardinal ): BOOL; stdcall;
_UnRegisterTouchWindow : Function ( hwnd : HWND ): BOOL; stdcall;
_CloseTouchInputHandle : Function ( hTouchInput_ : HTOUCHINPUT ): BOOL; stdcall;
_GetTouchInputInfo : Function ( hTouchInput : HTOUCHINPUT;
cInputs : UINT;
pInputs : PTOUCHINPUT;
cbSize : Integer ): BOOL; stdcall;
//
_GestureSav : TGestureSav;

//
Function GetGestureInfo ( hGestureInfo : HGESTUREINFO;
Var pGestureInfo : TGestureInfo): BOOL;
begin
Case Assigned(_GetGestureInfo) of
True : Result := _GetGestureInfo(hGestureInfo,pGestureInfo);
False : begin
If _User32Handle = 0 then _User32Handle := LoadLibrary('User32.DLL');
Result := False;
If _User32Handle > 0 then
begin
_GetGestureInfo := GetProcAddress(_User32Handle, 'GetGestureInfo');
If Assigned(_GetGestureInfo) then
Result := _GetGestureInfo(hGestureInfo,pGestureInfo);
end;
end;
end;
end;

//
Function CloseGestureInfoHandle (hGestureInfo: HGESTUREINFO): BOOL;
begin
Case Assigned(_CloseGestureInfoHandle) of
True : Result := _CloseGestureInfoHandle(hGestureInfo);
False : begin
If _User32Handle = 0 then _User32Handle := LoadLibrary('User32.DLL');
Result := False;
If _User32Handle > 0 then
begin
_CloseGestureInfoHandle := GetProcAddress(_User32Handle, 'CloseGestureInfoHandle');
If Assigned(_CloseGestureInfoHandle) then
Result := _CloseGestureInfoHandle(hGestureInfo);
end;
end;
end;
end;

//
Function SetGestureConfig ( hwnd : HWND;
dwReserved : DWORD;
cIDs : UINT;
pGestureConfig: PGESTURECONFIG;
cbSize : UINT ): BOOL;
begin
Case Assigned(_SetGestureConfig) of
True : Result := _SetGestureConfig(hwnd,dwReserved,cIDs,pGestureConfig,cbSize);
False : begin
If _User32Handle = 0 then _User32Handle := LoadLibrary('User32.DLL');
Result := False;
If _User32Handle > 0 then
begin
_SetGestureConfig := GetProcAddress(_User32Handle, 'SetGestureConfig');
If Assigned(_SetGestureConfig) then
Result := _SetGestureConfig(hwnd,dwReserved,cIDs,pGestureConfig,cbSize);
end;
end;
end;
end;

//
Function RegisterTouchWindow ( Handle : HWND;
ulFlags : Cardinal ): BOOL;
begin
Case Assigned(_RegisterTouchWindow) of
True : Result := _RegisterTouchWindow(Handle,ulFlags);
False : begin
If _User32Handle = 0 then _User32Handle := LoadLibrary('User32.DLL');
Result := False;
If _User32Handle > 0 then
begin
_RegisterTouchWindow := GetProcAddress(_User32Handle, 'RegisterTouchWindow');
If Assigned(_RegisterTouchWindow) then
Result := _RegisterTouchWindow(Handle,ulFlags);
end;
end;
end;
end;

//
Function UnRegisterTouchWindow ( Handle : HWND ): BOOL;
begin
Case Assigned(_UnRegisterTouchWindow) of
True : Result := _UnRegisterTouchWindow(Handle);
False : begin
If _User32Handle = 0 then _User32Handle := LoadLibrary('User32.DLL');
Result := False;
If _User32Handle > 0 then
begin
_UnRegisterTouchWindow := GetProcAddress(_User32Handle, 'UnregisterTouchWindow');
If Assigned(_UnRegisterTouchWindow) then
Result := _UnRegisterTouchWindow(Handle);
end;
end;
end;
end;

//
Function CloseTouchInputHandle ( hTouchInput_ : HTOUCHINPUT ): BOOL;
begin
Case Assigned(_CloseTouchInputHandle) of
True : Result := _CloseTouchInputHandle(hTouchInput_);
False : begin
If _User32Handle = 0 then _User32Handle := LoadLibrary('User32.DLL');
Result := False;
If _User32Handle > 0 then
begin
_CloseTouchInputHandle := GetProcAddress(_User32Handle, 'CloseTouchInputHandle');
If Assigned(_CloseTouchInputHandle) then
Result := _CloseTouchInputHandle(hTouchInput_);
end;
end;
end;
end;

//
Function GetTouchInputInfo ( hTouchInput : HTOUCHINPUT;
cInputs : UINT;
pInputs : PTOUCHINPUT;
cbSize : Integer ): BOOL;
begin
Case Assigned(_GetTouchInputInfo) of
True : Result := _GetTouchInputInfo(hTouchInput,cInputs,pInputs,cbSize);
False : begin
If _User32Handle = 0 then _User32Handle := LoadLibrary('User32.DLL');
Result := False;
If _User32Handle > 0 then
begin
_GetTouchInputInfo := GetProcAddress(_User32Handle, 'GetTouchInputInfo');
If Assigned(_GetTouchInputInfo) then
Result := _GetTouchInputInfo(hTouchInput,cInputs,pInputs,cbSize);
end;
end;
end;
end;

//
Function GID_ROTATE_ANGLE_FROM_ARGUMENT( Arg: ULONGLONG): Double;
begin
Result := (((Arg / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265);
end;

//
Function GID_GestureType(GID : Cardinal ) : TGestureType;
begin
Case GID of
GID_BEGIN : Result := gtBegin;
GID_END : Result := gtEnd;
GID_ZOOM : Result := gtZoom;
GID_PAN : Result := gtPan;
GID_ROTATE : Result := gtRotate;
GID_TWOFINGERTAP : Result := gtTwoFingerTap;
GID_PRESSANDTAP : Result := gtPressAndTap;
else Result := gtNone;
end;
end;

//
Function Get_Angle(gaArg : ULongLong) : Double;
begin
Result := gID_Rotate_Angle_From_Argument(gaArg) * 180 / pi;
end;

//
Function Flag_Check(fcValue,fcFlag : DWord) : Boolean;
begin
Result := (fcValue and fcFlag) = fcFlag;
end;

//
Function Flag_State(fcValue : DWord) : TGestureState;
begin
// 초기화
Result := gsNone;
//
If Flag_Check(fcValue,GF_Begin ) then Result := gsBegin;
If Flag_Check(fcValue,GF_End ) then Result := gsEnd;
If Result = gsNone then Result := gsWork;
end;

// ----------------------------------------------------------------------------
//
//
//
//
//
// ----------------------------------------------------------------------------

//
Function Gesture_Set (gsHandle : THandle;gsSet : TGestureSet) : Boolean;
Var
GestureConfig : TGestureConfig;
Configs : Array [0..1] of TGestureConfig;
ConfigCnt : Integer;
begin
Case gsSet of
gsAll : // Gesture 전체 사용
begin
FillChar(GestureConfig,SizeOf(GestureConfig),#0);
GestureConfig.dwWant := GC_AllGestures;
Result := Integer(SetGestureConfig(gsHandle,0,1,@GestureConfig,
SizeOf(GestureConfig))) <> 0;
end;
gsZoom,
gsZoomRotate
: //
begin
FillChar(Configs,SizeOf(Configs),#0);
//
Configs[0].dwID := GID_Zoom;
Configs[0].dwWant := GC_Zoom;
Configs[0].dwBlock := 0;

Configs[1].dwID := GID_ROTATE;
Configs[1].dwWant := GC_ROTATE;
Configs[1].dwBlock := 0;
//
Case gsSet of
gsZoom : ConfigCnt := 1;
gsZoomRotate : ConfigCnt := 2;
End;
Result := Integer(SetGestureConfig(gsHandle,0,ConfigCnt,@Configs[0],
Sizeof(TGestureConfig))) <> 0;
end;
end;
end;

// http://msdn.microsoft.com/ko-kr/magazine/ee336016.aspx
Function Gesture_Get(_wParam :wParam; _lParam :lParam) : TGesture;
Var
GI : TGestureInfo;
Str : String;
begin
// Step #1. 초기화 ----------------------------------------------------------
FillChar(Result,SizeOf(TGesture),#0);
FillChar(Gi,SizeOf(Gi),#0);
ZeroMemory(@gi, sizeof(TGestureInfo));
gi.cbSize := Sizeof(gi);

// Step #2. 멀티터치 정보 얻기 ----------------------------------------------
GetGestureInfo(_lParam, gi);
//
Result.Type_ := GID_GestureType(gi.dwID);
Result.XY := Point(gi.ptsLocation.x,gi.ptsLocation.y);

Case gi.dwID of
// Event Style [Simple] ----------------------------------------------------
GID_Pan : Result.State := Flag_State(gi.dwFlags);
GID_TWOFINGERTAP : Result.State := Flag_State(gi.dwFlags);
GID_PRESSANDTAP : Result.State := Flag_State(gi.dwFlags);
// Event Style [Complex] ---------------------------------------------------
GID_Zoom : Begin
Result.State := Flag_State(gi.dwFlags);
// Zoom 계산을 위하여, 초기값 저장
If Result.State = gsBegin then
_GestureSav.ullArguments := gi.ullArguments;
Result.Value := gi.ullArguments / _GestureSav.ullArguments;
End;
GID_Rotate : Begin
Case Flag_State(gi.dwFlags) of
gsNone : Result.State := gsNone;
gsBegin : begin
_GestureSav.Cnt := 0;
_GestureSav.State := gsNone;
Result.State := gsNone;
end;
gsWork,
gsEnd : begin
Inc(_GestureSav.Cnt);
Result.State := gsNone;
If _Gesturesav.Cnt > 2 then
begin
Case _GestureSav.State of
gsNone : begin
Result.State := gsBegin;
_GestureSav.State := gsWork;
_GestureSav.AnglePrev := Get_Angle(gi.ullArguments);
If Flag_State(gi.dwFlags) = gsEnd then
Result.State := gsNone;
end;
gsWork : Case Flag_State(gi.dwFlags) = gsWork of
True : Result.State := gsWork;
False : Result.State := gsEnd;
end;
End;
end;
Result.Value := Get_Angle(gi.ullArguments);

GestureSav.AnglePrev := Result.Value;
{
Case Result.Value > 0 of
True : Result.Value := 2;
False: Result.Value := -2;
End;
}
end;
End;
End;
End;
//
CloseGestureInfoHandle(_lParam);
end;

//
Function Gesture_Str (Gstr : TGesture) : String;

Function State2Str(fsFlag : TGestureState) : String;
begin
Case fsFlag of
gsNone : Result := '... ';
gsBegin : Result := 'Begin ';
gsWork : Result := 'Work ';
gsEnd : Result := 'End ';
End;
end;

Function XY2Str(xy : TPoint) : String;
begin
Result := IntToStr(xy.x)+','+ IntToStr(xy.Y) + ' ';
end;

begin
Case Gstr.Type_ of
gtBegin : Result := 'Begin ';
gtEnd : Result := 'End ';
gtZoom : Result := 'Zoom ' + State2Str(Gstr.State) + XY2Str(Gstr.XY) + Format('%3.1f',[Gstr.Value]);
gtPan : Result := 'Pan ' + State2Str(Gstr.State) + XY2Str(Gstr.XY);
gtRotate : Result := 'Rotate ' + State2Str(Gstr.State) + XY2Str(Gstr.XY) + Format('%3.1f',[Gstr.Value]);
gtTwoFingerTap : Result := '2FngrTap' + State2Str(Gstr.State) + XY2Str(Gstr.XY);
gtPressAndTap : Result := 'Prs &Tap' + State2Str(Gstr.State) + XY2Str(Gstr.XY);
End;
end;

Initialization
//
_User32Handle := 0;
_GetGestureInfo := nil;
_CloseGestureInfoHandle := nil;
_SetGestureConfig := nil;
_RegisterTouchWindow := nil;
_UnRegisterTouchWIndow := nil;
_CloseTouchInputHandle := nil;
//
FillChar(GestureSav,SizeOf(GestureSav),#0);
end.