power_sample.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 523 行 · 第 1/2 页

C
523
字号
/**********************************************************************************/
/*                                                                                */
/*    Copyright (C) 2005 Oki Electric Industry Co., LTD.                          */
/*                                                                                */
/*    System Name    :  ML67Q4051/ML67Q4061					                      */
/*    Module Name    :  Power control sample program                              */
/*    File   Name    :  power_sample.c                                            */
/*    Revision       :  01.00                                                     */
/*    Date           :  2005/02/16 initial version                                */
/*                                                                                */
/**********************************************************************************/
#include "ML674061.h"
#include "common.h"
#include "irq.h"
#include "pm674061_lib.h"

#ifdef __IAR__
#include "intrinsics.h"
#endif

/* Constants */
#define MHz      (1000000L)
#define TMRCYC   (30)           /* interval of timer interrupt (ms) */
#define SYSCLK	 (33)	        /* SYSCLK (MHz)*/
#define VALUE_OF_TMRLR          /* reload value of timer */\
                 (65536 - (TMRCYC * SYSCLK * 1000) / 16)

#if ((VALUE_OF_TMRLR) < 0 || 0x10000 <= (VALUE_OF_TMRLR))
#error "Invalid value : VALUE_OF_TMRLR"
#endif

/* constants */
#define    TRIGGER_LEVEL        14
#define    BUFF_SIZE            256
#define    FIFO_SIZE            16

/* please note, the test at slower rate here is due to the
fact that, in the APB clock test, if the APBCLK is down
to 8Mhz, UART may not work at baudrate 115,200. See User's Manual
17.4.10. The deviation will be too big to compensate.
The test conducted below is, 32Mhz, 16Mhz, 8Mhz at the same
baudrate 57,600. When the APB clock is divided by half, to keep
the same baudrate, the divisor latch value needs to be divided too. */

#define    DLM_BAUD             0x00  /* baud = 9,600 */
#define    DLL_BAUD             0xD7  /* baud = 9,600 */

/* === setting baud rate value === */
/*     baud  | DLM_BAUD | DLL_BAUD */
/*     1,200 |   0x06   |   0xB7   */
/*     2,400 |   0x03   |   0x5B   */
/*     4,800 |   0x01   |   0xAE   */
/*     9,600 |   0x00   |   0xD7   */
/*    19,200 |   0x00   |   0x6B   */
/*    38,400 |   0x00   |   0x36   */
/*    57,600 |   0x00   |   0x24   */
/*   115,200 |   0x00   |   0x12   */

#define LED_H   0x0076
#define LED_S   0x006D

/* Functions */
int main(void);                     /* Main routine */
static void setup_exint(void);     /* setup exint */
static void set_timer(void);        /* setup of timer */
static void Blink_LED( int blink_count ); /* Blink LED */
static void reg_irq_handler(void);  /* registration of IRQ handler */
static void timer_handler(void);    /* timer handler */
void    init_uart(void);        /* initialize UART */
void    uart_handler(void);     /* UART interrupt handler */
void    reg_uart_irq_handler(void);  /* registration of IRQ handler */

/* LED lighting pattern table */
UHWORD LED_TABLE [18] = {LED_0,LED_1,LED_2,LED_3,   /* "0","1","2","3" */
                         LED_4,LED_5,LED_6,LED_7,   /* "4","5","6","7" */
                         LED_8,LED_9,LED_A,LED_b,   /* "8","9","A","b" */
                         LED_C,LED_d,LED_E,LED_F,   /* "C","d","E","F" */
                         LED_all,LED_off};          /* all on ,all off */

/* global variables */
volatile  unsigned  char  rw_buff[BUFF_SIZE];  /* ring buffer */
int  write_pointer = 0;   /* the current char point from UART to execute the command */
volatile  int  cmd_flag = 0;
volatile  int  rec_data_counter = 0;
volatile  int  error_flag = 0;  /* 0:no error, 1:overrun error, 2:parity error,
                               3:framing error, 4:overflow error */
static volatile int counter;
static volatile int led_count;

/****************************************************************************/
/*  Entry point                                                             */
/*  Function : main                                                         */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   0                                                   */
/****************************************************************************/
int main(void)
{
    UBYTE input;
    UBYTE diva_clk_gear = 0;
    UBYTE apb_clk_gear = 0;
    UHWORD diva_clk_led_pattern[5] = {0x0020,0x0001,0x0021,0x0002,0x0022};
    UHWORD apb_clk_led_pattern[3] = {0x0010,0x0008,0x0018};

    /* Initialization of IRQ */
    init_irq();

    /* initialize clock gear for both CCLK and APB CLK */
    pm_diva_clkgear(0, 1);
    pm_apb_clkgear(0, 0);

    /* registration of IRQ handler */
    reg_irq_handler();
	
    /* setting of timer */
    set_timer() ;

    /* setup UART 0 instead of SIO as for the OKI-J board */
    init_uart();

    /* register of UART IRQ handler */
    reg_uart_irq_handler();

    /* setup of extint1*/
    setup_exint();

    /* initialize led */
    init_led();
	
    led_on(LED_START_PATTERN);

    /* IRQ enable */
#ifdef __IAR__
      __enable_interrupt();
#else
    irq_en();
#endif

	for(;;)
	{
          /* receive ready? */
          /* cmd_flag 1 is received on the UART, 0 is processed or not received. */
          if ( write_pointer != 0 && error_flag == 0 && cmd_flag != 0 )
          {
            /* Get UART data from buffer */
            /* get previous data */
            input = rw_buff[write_pointer-1];
            switch(input)
            {
            case 'h':
            case 'H':
                led_on(LED_H);
                put_wvalue(TMEN, 0x01); /* timer start */

                /* HALT mode */
                cmd_flag = 0;
                pm_halt(0x00000001,0x00000004);   /* external INT and timer */

                /* even in the HALT mode, the SIO and SYSCLK interrupt can be used to
                set the CPU to RUN mode, that's why, after calling pm_halt() to
                HALT the MCU, the enabling of the timer will wake the CPU right after.
                SIO can not be used for wakeup as it's not connected on AME_51 board. */

                Blink_LED( 5 );
                put_wvalue(TMEN, 0x00); /* timer stop */
                led_on(LED_START_PATTERN);
		/* change to SYSCLK */
                put_wvalue(CLKCNT, (get_wvalue(CLKCNT)&0xFFFFFCFF)) ;
                break;

            case 's':
            case 'S':
                led_on(LED_S);
                cmd_flag = 0;
                /* change to ringosc */
                put_wvalue(CLKCNT, (get_wvalue(CLKCNT)&0xFFFFFCFF) | 0x00000100) ;
                /* STOP mode */
                pm_stop(0x00000000,0x00000004);

                /* At this point, the CPU is stopped, an external interrupt EXTINT1
                can be used to wake up the CPU. So, once LED display is S, it stops,
                press the EXTINT1 button, will wake up CPU, in turn, the LED will
                blink 5 times, then back to START_PATTERN. */

                /* change to SYSCLK */
                put_wvalue(CLKCNT, (get_wvalue(CLKCNT)&0xFFFFFCFF));
                put_wvalue(TMEN, 0x01); /* timer start */

                Blink_LED( 5 );
                put_wvalue(TMEN, 0x00); /* timer stop */
                led_on(LED_START_PATTERN);
                break;

            case 'o':
            case 'O':
                if(diva_clk_gear > 0)
                {
                    diva_clk_gear--;
                    set_bit(UARTLCR0,UARTLCR_DLAB);
                    if ( diva_clk_gear == 0 )
                        put_value(UARTDLL0, DLL_BAUD);   /* DLL of divider latch register */
                    else
                        put_value(UARTDLL0, DLL_BAUD / (0x01 << diva_clk_gear));
                    put_value(UARTDLM0, DLM_BAUD);   /* DLM of divider latch register */
                    clr_bit(UARTLCR0,UARTLCR_DLAB);
                }
                /* DIVA_CLK gear */
                pm_diva_clkgear(diva_clk_gear, 0);
                led_on((UBYTE)(diva_clk_led_pattern[diva_clk_gear]));
                break;

            case 'p':
            case 'P':
                /* skip 1/32 divider on the SYSCLK because of the baurate deviation problem */
                if(diva_clk_gear < 4)     /* diva_clk_gear is 0~4 */
                {
                    diva_clk_gear++;
                    set_bit(UARTLCR0,UARTLCR_DLAB);
                    put_value(UARTDLL0, DLL_BAUD / (0x01 << diva_clk_gear)); /* DLL of divider latch register */
                    put_value(UARTDLM0, DLM_BAUD);   /* DLM of divider latch register */
                    clr_bit(UARTLCR0,UARTLCR_DLAB);
                }
                /* DIVA_CLK gear */
                pm_diva_clkgear(diva_clk_gear, 1);
                led_on((UBYTE)(diva_clk_led_pattern[diva_clk_gear]));
                break;

            case '[':
                if(apb_clk_gear > 0)
                {
                        apb_clk_gear--;
                        set_bit(UARTLCR0,UARTLCR_DLAB);
                        if ( apb_clk_gear == 0 )
                            put_value(UARTDLL0, DLL_BAUD);   /* DLL of divider latch register */
                        else
                            put_value(UARTDLL0, DLL_BAUD / (0x01 << apb_clk_gear));
                        put_value(UARTDLM0, DLM_BAUD);   /* DLM of divider latch register */
                        clr_bit(UARTLCR0,UARTLCR_DLAB);
                }
                /* APB_CLK gear */
                pm_apb_clkgear(apb_clk_gear, 0);
                led_on(LED_off);
                led_on((UBYTE)(apb_clk_led_pattern[apb_clk_gear]));
                break;

            case ']':
                if(apb_clk_gear < 2)
                {
                        apb_clk_gear++;
                        set_bit(UARTLCR0,UARTLCR_DLAB);
                        put_value(UARTDLL0, DLL_BAUD / (0x01 << apb_clk_gear));   /* DLL of divider latch register */
                        put_value(UARTDLM0, DLM_BAUD);   /* DLM of divider latch register */
                        clr_bit(UARTLCR0,UARTLCR_DLAB);
                }
                /* APB_CLK gear */
                pm_apb_clkgear(apb_clk_gear, 1);
                led_on((UBYTE)(apb_clk_led_pattern[apb_clk_gear]));
                break;

            default:
                continue;
            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?