도와주세요!!
http://forum.falinux.com/zbxe/?document_srl=401796 를 참고로 기초 소스는 작성하여
Timer 1에서 TOUT1로 Clock를 나오게 하는것은 성공하였으나 TCNTB와 TCMPB 및 TCON-Auto Reload를 이용하여
테스트를 하지 못하여 질문을 드리게 되었습니다.
제가 작성한 소스 개요
1. 초기 설정
// GPIO B1 Pin을 출력으로 설정
GPIO_CFG(S3C2410_GPB1, S3C2410_GPB1_OUTP);
// configure clock tick
tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK;
tcfg1 |= S3C2410_TCFG1_MUX0_DIV4;
tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
tcfg0 |= S3C2410_TCFG_PRESCALER0_MASK;
__raw_writel(tcfg1, S3C2410_TCFG1);
__raw_writel(tcfg0, S3C2410_TCFG0);
__raw_writel(tcnt, S3C2410_TCMPB(1));
__raw_writel((tcnt/2), S3C2410_TCNTB(1));
// ensure timer is stoped...
tcon &= ~(0xF<<8);
tcon |= S3C2410_TCON_T1MANUALUPD;
__raw_writel(tcon, S3C2410_TCON);
tcon &= ~(0xf<<8); // One-shot, Inverter off, No operation, Stop
__raw_writel(tcon, S3C2410_TCON);
2. 프로그램 동작 설명
Command 값 입력 후 해당 입력값을 전역변수 test_CLK로 지정
Timer Interrupt가 걸릴때마다 Timer를 멈춘 후 강제로 해당 GPIO Pin에 High / Low 를 지정 출력
static irqreturn_t lcdadj_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long tcon;
// timer stop
tcon = __raw_readl(S3C2410_TCON);
tcon &= ~(S3C2410_TCON_T1START) | ~(S3C2410_TCON_T1RELOAD);
__raw_writel(tcon, S3C2410_TCON);
if(test_high == 0) {
GPIO_SET(S3C2410_GPB1, 1);
test_high = 1;
}
else if(lcdadj_high == 0) {
GPIO_SET(S3C2410_GPB1, 0);
lcdadj_clk = 0;
}
lcdadj_reload( test_CLK / 10) );
}
3. Reload 함수 - Manual값 입력
static void test_reload( unsigned long tick )
{
unsigned long tcon;
// timer stop
tcon = __raw_readl(S3C2410_TCON);
tcon &= ~(0xF<<8); // Timer 1 = 8
__raw_writel(tcon, S3C2410_TCON);
// Timer 1 Count Buffer Register
__raw_writel(tick, S3C2410_TCMPB(1));
__raw_writel(tick, S3C2410_TCNTB(1));
// timer start
tcon |= S3C2410_TCON_T1MANUALUPD;
__raw_writel(tcon, S3C2410_TCON);
tcon &= ~(0xF<<8);
tcon |= S3C2410_TCON_T1START;
__raw_writel(tcon, S3C2410_TCON);
}
===============================================================================================
이제 질문입니다.
위 소스에서 GPIO-B1에 값을 입력하는 부분
if(test_high == 0) {
GPIO_SET(S3C2410_GPB1, 1);
test_high = 1;
}
else if(lcdadj_high == 0) {
GPIO_SET(S3C2410_GPB1, 0);
lcdadj_clk = 0;
}
을 제외하고, 단순히 S3C2440 User Manual에 있듯 TCNTB와 TCMPB를 입력해서 AUTO RELOAD를 시켜
자동으로 TOUT에 클럭을 나오게 하는게 목적입니다.
단순하게 생각해서 reload 함수에서 다시 timer start될 때 auto reload값을 넣어주거나,
초기 실행시 one shot이 아닌 auto reload를 set 해주는 방법등을 해보았으나 잘되질 않네요..;;
제 생각에는 따로 특정 레지스터나 값을 바꿔줘야 될꺼라곤 생각이 안됩니다.
이거 해볼려고 이틀째 꼬박 소스 이리저리 돌려보고 있네요.. ㅎ;;
PWM Timer를 Auto Reload를 이용하여 제작해보신분 좀 도와주세요..
도움이 될만한 소스가 있는곳이라도 알려주세요..;;
구글, 네이버, 켈프 등 몇몇 사이트를 확인해봤는데 찾기가 힘드네요..
부탁드립니다~(__)
ps. 저도 계속 해볼테니 되면 바로 답글 올리겠습니다.(__)
2440 pwm timer 를 이용해서 인터럽트 마다 led 구동을 해본 사람입니다.
저도 초보라서 자세한것은 말씀드리기 힘들지만 제가 만들면서 알게된 동작 순서를 말씀드리겠습니다.
1. tcfg0 과 tcfg1은 시간 간격을 얼마로 놓을꺼냐의 문제이므로 굳이 언급 하지 않겠습니다.
2. 저는 timer 2 를 이용하였구요. timer0 과 4는 건들지 않았습니다. 커널 소스 보시면 아시겠지만 이미 사용중입니다.
3. auto relord 를 해주면 auto relord 사용중에 설정한 tcnt 값으로 주기적으로 변경해줍니다. autoreload 사용 해줍니다.
4. tcnt, tcmp 값을 본인이 원하는값으로 맞추어 줍니다. 저의 경우 최대한 긴 간격의 인터럽트를 원해서 tcnt = 65535, tcmp = 0
(tcnt 값이 다운카운트 하다가 tcmp 값과 일치해야 (0일때) 인터럽트가 발생. auto realord 때문에 다시 tcnt가 65535로 변경)
5. manual update를 1로 설정하여 tcnt 와 tcmp 값을 셋팅합니다.
6. manualupdate 값을 0으로 변경합니다. (한번 설정한 tcnt 값을 계속 사용했습니다 저는)
7. timer 를 start 합니다.
도움이 되셧으면 좋겠네요~