2014/11/21

STM32에 MCX314AL을 붙여보자 -- 2. 드라이버를 만들자

노바 일렉트로닉스 홈페이지에 가면 MCX314AML.C 파일을 다운받을 수 있다.

MCX302/304/312/314/501을 사용하기 위한 샘플 프로그램 모음 파일인데 이중 MCX314AML.C 파일을 변경해서 모션 컨트롤 드라이버로 사용하자.

MCX314AL.C와 MCX314AL.H 파일을 만들어 봤다.

#define  adr 0x60000000 // Basic address

#define wr0 0x0 //Command register
#define wr1 0x2 //Mode register 1
#define wr2 0x4 //Mode register 2
#define wr3 0x6 //Mode register 3
#define wr4 0x8 //Output register
#define wr5 0xa //Interpolation mode register
#define wr6 0xc //Low word bits data writing register
#define wr7 0xe //High word bits data writing register

#define rr0 0x0 //Main status register
#define rr1 0x2 //Status register 1
#define rr2 0x4 //Status register 2
#define rr3 0x6 //Status register 3
#define rr4 0x8 //Input register 1
#define rr5 0xa //Input register 2
#define rr6 0xc //Low word bits data reading register
#define rr7 0xe //High word bits data reading register

#define bp1p 0x4 //BP + direction data register for the first axis control
#define bp1m 0x6 //BP ? direction data register for the first axis control
#define bp2p 0x8 //BP + direction data register for the second axis control
#define bp2m 0xa //BP ? direction data register for the second axis control
#define bp3p 0xc //BP + direction data register for the third axis control
#define bp3m 0xe //BP ? direction data register for the third axis control

void wreg1(int axis,int wdata);
void wreg2(int axis,int wdata);
void wreg3(int axis,int wdata);
void command(int axis,int cmd);
void range(int axis,long wdata);
void acac(int axis,int wdata);
void dcac(int axis,int wdata);
void acc(int axis,int wdata);
void dec(int axis,int wdata);
void startv(int axis,int wdata);
void speed(int axis,int wdata);
void pulse(int axis,long wdata);
void decp(int axis,long wdata);
void center(int axis,long wdata);
void lp(int axis,long wdata);
void ep(int axis,long wdata);
void compp(int axis,long wdata);
void compm(int axis,long wdata);
void accofst(int axis,long wdata);
void hsspeed(int axis,int wdata);
void expmode(int axis,int em6data,int em7data);
void syncmode(int axis,int sm6data,int sm7data);
long readlp(int axis);
long readep(int axis);
void wait(int axis);
void next_wait(void);
void bp_wait(void);
void homesrch(void);



#include "stm32f4xx_hal.h"
#include
#include "MCX314AL.h"

#define outpw(a, b) *(__IO uint16_t*) (a) = b
#define inpw(a) *(__IO uint16_t*) (a)

// wreg 1 (axis assignment, data) ----Write register 1 setting
void wreg1(int axis,int wdata)
{
outpw(adr+wr0, (axis << 8) + 0xf); //axis assignment
outpw(adr+wr1, wdata);
}

// wreg 2 (axis assignment, data) ----Write register 2 setting
void wreg2(int axis,int wdata)
{
outpw(adr+wr0, (axis << 8) + 0xf); //axis assignment
outpw(adr+wr2, wdata);
}

// wreg 3 (axis assignment, data) -----Write register 3 setting
void wreg3(int axis,int wdata)
{
outpw(adr+wr0, (axis << 8) + 0xf); //axis assignment
outpw(adr+wr3, wdata);
}

// command (axis assignment, data) -----For writing commands
void command(int axis,int cmd)
{
outpw(adr+wr0, (axis << 8) + cmd);
}

// range(axis assignment, data) -----For range (R) setting
void range(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x00);
}

// acac(axis assignment, data) -----For S-curve Deceleration increasing rate (L) setting
void acac(int axis,int wdata)
{
outpw(adr+wr6, wdata);
outpw(adr+wr0, (axis << 8) + 0x01);
}


// dcac(axis assignment, data) ----- For jerk (L) setting
void dcac(int axis,int wdata)
{
outpw(adr+wr6, wdata);
outpw(adr+wr0, (axis << 8) + 0x0e);
}

// acc(axis assignment, data) -----For acceleration/deceleration (A) setting

void acc(int axis,int wdata)
{
outpw(adr+wr6, wdata);
outpw(adr+wr0, (axis << 8) + 0x02);
}

// dec( axis assignment, data) -----For deceleration (D) setting
void dec(int axis,int wdata)
{
outpw(adr+wr6, wdata);
outpw(adr+wr0, (axis << 8) + 0x03);
}

// startv(axis assignment, data) -----For initial speed (SV) setting
void startv(int axis,int wdata)
{
outpw(adr+wr6, wdata);
outpw(adr+wr0, (axis << 8) + 0x04);
}

// speed(axis assignment, data) -----For drive speed (V) setting
void speed(int axis,int wdata)
{
outpw(adr+wr6, wdata);
outpw(adr+wr0, (axis << 8) + 0x05);
}

// pulse( axis assignment, data) -----For output pulse output/finish point (P) setting
void pulse(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x06);
}

// decp(axis assignment, data) -----For manual deceleration (DP) setting
void decp(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x07);
}

// center(axis assignment, data) -----For circular center point (C) setting
void center(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x08);
}

// lp(axis assignment, data) -----For logical position counter (LP ) setting
void lp(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x09);
}

// ep(axis assignment, data) -----For real position counter (EP) setting
void ep(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x0a);
}


// compp(axis assignment, data) -----For COMP+ (CP) setting
void compp(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x0b);
}

// compm(axis assignment, data) -----For COMP ? (CM) setting
void compm(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x0c);
}

// accofst(axis assignment, data) ----For acceleration counter shift (AO) setting
void accofst(int axis,long wdata)
{
outpw(adr+wr7, (wdata >> 16) & 0xffff);
outpw(adr+wr6, wdata & 0xffff);
outpw(adr+wr0, (axis << 8) + 0x0d);
}

// hsspeed(axis assignment, data) ------------------- Home Search Speed (HV) setting
void hsspeed(int axis,int wdata)
{
outpw(adr+wr6, wdata);
outpw(adr+wr0, (axis << 8) + 0x61);
}

// expmode(axis assignment, data) ------------------- Expansion Mode (EM) setting
void expmode(int axis,int em6data,int em7data)
{
outpw(adr+wr6, em6data);
outpw(adr+wr7, em7data);
outpw(adr+wr0, (axis << 8) + 0x60);
}

// syncmode(axis assignment, data) ------------------ Synchronous Mode (SM) setting
void syncmode(int axis,int sm6data,int sm7data)
{
outpw(adr+wr6, sm6data);
outpw(adr+wr7, sm7data);
outpw(adr+wr0, (axis << 8) + 0x64);
}

// readlp(axis assignment) -----For logical position counter (LP) reading
long readlp(int axis)
{
long a;long d6;long d7;
outpw(adr+wr0, (axis << 8) + 0x10);
d6 = inpw(adr+rr6);d7 = inpw(adr+rr7);
a = d6 + (d7 << 16);
return(a);
}

// readep(axis assignment) -----For real position counter (EP) reading
long readep(int axis)
{
long a;long d6;long d7;
outpw(adr+wr0, (axis << 8) + 0x11);
d6 = inpw(adr+rr6);d7 = inpw(adr+rr7);
a = d6 + (d7 << 16);
return(a);
}

// wait(axis assignment) -----For waiting for drive stop
void wait(int axis)
{
while(inpw(adr+rr0) & axis);
}

// next_wait() -----Next data setting of waiting for continuous interpolation
void next_wait(void)
{
while((inpw(adr+rr0) & 0x0200) == 0x0);
}


// bp_wait() ----- Next data setting of waiting for BP interpolation
void bp_wait(void)
{
while((inpw(adr+rr0) & 0x6000) == 0x6000);
}

// home search() ------------------------------- All axes home search
//
// ------ X axis home search ---------------------------------
// Step1 Near home (IN0) signal high-speed search in the ? direction at 20,000pps
// Step2 Home (IN1) signal low-speed search in the ? direction at 500pps
// Step3 Z-phase (IN2) signal low-speed search in the ? direction at 500pps
// Deviation counter clear output at Z-phase search
// Step4 3500 pulse offset high-speed drive in the + direction at 20,000pps
//
// ------ Y axis home search ---------------------------------
// Step1 Near home (IN0) signal high-speed search in the ? direction at 20,000pps
// Step2 Home (IN1) signal low-speed search in the ? direction at 500pps
// Step3 Z-phase (IN2) signal low-speed search in the ? direction at 500pps
// Deviation counter clear output at Z-phase search
// Step4 700 pulse offset high-speed drive in the + direction at 20,000pps
//
// ------ Z axis home search ---------------------------------
// Step1 High-speed search: None
// Step2 Home (IN1) signal low-speed search in the + direction at 400pps
// Step3 Z-phase search: None
// Step4 20 pulse offset drive in the ? direction at 400pps
//
// ------ U axis home search ---------------------------------
// Step1 High-speed search: None
// Step2 Home (IN1) signal low-speed search in the ? direction at 300pps
// Step3 Z-phase search: None
// Step4 Offset drive: None
//

void homesrch(void)
{
// X and Y axes home search parameter setting
// (See the initial setting of main for mode setting)
speed(0x3,2000); // Step1 and 4 High speed: 20000pps
hsspeed(0x3,50); // Step2 and 3 Low speed: 500pps
pulse(0x1,3500); // X axis offset: 3500 pulse
pulse(0x2,700); // Y axis offset: 700 pulse

// Z axis home search parameter setting
speed(0x4,40); // Step4 drive speed: 400pps
hsspeed(0x4,40); // Step2 search speed: 400pps
pulse(0x4,20); // Offset:20 pulses

// U axis home search parameter setting
hsspeed(0x8,30); // Step2 search speed: 300pps

command(0xf,0x62); // Execution of automatic home search for all the axes
wait(0xf); // Waits for termination of all the axes

if(inpw(adr+rr0) & 0x0010) // Error display
{
printf("X-axis Home Search Error \n");
}
if(inpw(adr+rr0) & 0x0020)
{
printf("Y-axis Home Search Error \n");
}
if(inpw(adr+rr0) & 0x0040)
{
printf("Z-axis Home Search Error \n");
}
if(inpw(adr+rr0) & 0x0080)
{
printf("U-axis Home Search Error \n");
}
}


adr을 메모리 맵에 맞게 수정해주고, outpw와 inpw만 재정의 해주면 끝인거 같다.

근데 HardFault 뜬다. 끄으

댓글 없음:

댓글 쓰기