⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iar_pm674061_lib.s

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 S
📖 第 1 页 / 共 3 页
字号:
;* output               0        : normal end                           *
;*                      except 0 : input parameter error                *
;*                                                                      *
;*----------------------------------------------------------------------*
;*                                                                      *
;* using registers      r0,r1,r2,r3,r4,r5,r6,r7                         *
;*              (include registers used in STOP,HALT common routine)    *
;*                                                                      *
;************************************************************************

        EXPORT  pm_halt
pm_halt           ; unsigned long pm_halt(unsigned long Irq_enable)

;*** save registers ***
        STMFD   SP!,{r2-r7,lr}  ; save r2-r7,lr register

;*** set input parameter of STOP,HALT common routine
        LDR     r2,=HALT_CHECK1
        LDR     r3,=HALT_CHECK2
        LDR     r7,=HALTMODE_BIT

        B       pm_stop_halt      ; blanch to STOP,HALT common routine



;************************************************************************
;*                                                                      *
;* stop clock of ML674051/ML674061 series                               *
;*                         (STOP,HALT common routine)                   *
;*                                                                      *
;* pm_stop_halt                                                         *
;*                                                                      *
;* input                                                                *
;*      r0,r1:IRQ number to awake                                       *
;*           ML674051/ML674061 series from STOP/HALT mode               *
;*         r0:  bit0  : IRQ number 0                                    *
;*                :         :                                           *
;*              bit31 : IRQ number 31                                   *
;*         r1:  bit0  : IRQ number 32                                   *
;*                :         :                                           *
;*              bit31 : IRQ number 63                                   *
;*              *each bit is    0 = IRQ masked                          *
;*                              1 = IRQ allowed                         *
;*----------------------------------------------------------------------*
;*                                                                      *
;* using registers      r0,r1,r2,r3,r4,r5                               *
;*                                                                      *
;************************************************************************

pm_stop_halt
;*** check input parameter ***
        TEQ     r0,#0x00000000  ; input parameter != 0 ?
        TEQ     r1,#0x00000000  ; input parameter != 0 ?
        MOVEQ   r0,#0x00000001  ; set input parameter error return value(except 0)
        BEQ     pm_stop_halt_end  ; error end
        TST     r0,r2           ; non-awakable IRQ number is set ?
        BNE     pm_stop_halt_end  ; error end
        TST     r1,r3           ; non-awakable IRQ number is set ?
        BNE     pm_stop_halt_end  ; error end

;*** mask IRQ and FIQ. and get pre-masked CPSR ***
        MOV     r4,r0           ; save r0->r4
        SWI     SWI_PM_IF_DIS   ; mask IRQ and FIQ, return value:r0 = pre-masked CPSR

;*** save pre-masked CPSR ***
        LDR     r2,=SAVE_CPSR           ; save CPSR -> SAVE_CPSR
        STR     r0,[r2]
        MOV     r0,r4                   ; restore r4->r0

;*** WAIT ***
        nop                             ; NOP * 1

;*** save FIQ and IRQ mask information ***
        LDR     r2,=FIQEN               ; get FIQEN register
        LDR     r3,[r2]
        LDR     r4,=SAVE_FIQEN          ; save FIQEN -> SAVE_FIQEN
        STR     r3,[r4]
        LDR     r2,=ILC0                ; get ILC0 register
        LDR     r3,[r2]
        LDR     r4,=SAVE_ILC0           ; save ILC0 -> SAVE_ILC0
        STR     r3,[r4]
        LDR     r2,=ILC1                ; get ILC1 register
        LDR     r3,[r2]
        LDR     r4,=SAVE_ILC1           ; save ILC1 -> SAVE_ILC1
        STR     r3,[r4]
        LDR     r2,=EXILCA              ; get EXILCA register
        LDR     r3,[r2]
        LDR     r4,=SAVE_EXILCA         ; save EXILCA -> SAVE_EXILCA
        STR     r3,[r4]
        LDR     r2,=EXILCB              ; get EXILCB register
        LDR     r3,[r2]
        LDR     r4,=SAVE_EXILCB         ; save EXILCB -> SAVE_EXILCB
        STR     r3,[r4]
        LDR     r2,=EXILCC              ; get EXILCC register
        LDR     r3,[r2]
        LDR     r4,=SAVE_EXILCC         ; save EXILCC -> SAVE_EXILCC
        STR     r3,[r4]

;*** set IRQ awaking STOP/HALT mode. and mask FIQ and IRQ except that ***
        MOV     r2,#0
        LDR     r3,=FIQEN               ; mask FIQ
        STR     r2,[r3]
        LDR     r3,=ILC0                ; mask IRQ0,1,4,6
        STR     r2,[r3]
        LDR     r3,=ILC1                ; mask IRQ8-15
        STR     r2,[r3]
        LDR     r3,=EXILCA              ; mask IRQ16-31
        STR     r2,[r3]
        LDR     r3,=EXILCB              ; mask IRQ32-47
        STR     r2,[r3]
        LDR     r3,=EXILCC              ; mask IRQ48-63
        STR     r2,[r3]

        MOV     r2,#0
        MOV     r4,#1
pm_stop_halt_10
        TST     r0,r4                   ; IRQx allowed?
        BEQ     pm_stop_halt_20
        BL      iptmask_set1             ; allow IRQx
pm_stop_halt_20
        ADD     r4,r4,r4
        ADD     r2,r2,#1
        CMP     r2,#32
        BLT     pm_stop_halt_10

        MOV     r2,#0
        MOV     r4,#1
pm_stop_halt_100
        TST     r1,r4                   ; IRQx allowed?
        BEQ     pm_stop_halt_200
        BL      iptmask_set2             ; allow IRQx
pm_stop_halt_200
        ADD     r4,r4,r4
        ADD     r2,r2,#1
        CMP     r2,#32
        BLT     pm_stop_halt_100

;*** setting of CLKSTPCNT ***
        LDR     r2,=CLKSTPCNT
        LDR     r3,[r2]
        BIC     r3,r3,#0x00080000
        STR     r3,[r2]

;*** switch to STOP/HALT mode ***
        LDR     r2,=CLKSTP              ; set STOP/HATL mode(CLK stop)
        LDR     r3,[r2]
        ORR     r7,r7,r3
        MOV     r3,#0x3c                ; release CLKSTP write key(0x3c)
        STR     r3,[r2]
        STR     r7,[r2]                 ; write STOP/HALT bit to CLKSTP

;*** dummy read * 4 ***
        LDR     r2,=CLKSTP                 ; CLKSTP read * 4
        LDR     r3,[r2]
        LDR     r3,[r2]
        LDR     r3,[r2]
        LDR     r3,[r2]

;;;
;;;     under STOP/HALT mode
;;;

;*** restore FIQ and IRQ mask information ***
        LDR     r1,=FIQEN               ; restore FIQEN register
        LDR     r2,=SAVE_FIQEN
        LDR     r2,[r2]
        STR     r2,[r1]
        LDR     r1,=ILC0                ; restore ILC0 register
        LDR     r2,=SAVE_ILC0
        LDR     r2,[r2]
        STR     r2,[r1]
        LDR     r1,=ILC1                ; restore ILC1 register
        LDR     r2,=SAVE_ILC1
        LDR     r2,[r2]
        STR     r2,[r1]
        LDR     r1,=EXILCA              ; restore EXILCA register
        LDR     r2,=SAVE_EXILCA
        LDR     r2,[r2]
        STR     r2,[r1]
        LDR     r1,=EXILCB              ; restore EXILCB register
        LDR     r2,=SAVE_EXILCB
        LDR     r2,[r2]
        STR     r2,[r1]
        LDR     r1,=EXILCC              ; restore EXILCC register
        LDR     r2,=SAVE_EXILCC
        LDR     r2,[r2]
        STR     r2,[r1]

;*** restore CPSR ***
        LDR     r1,=SAVE_CPSR   ; get SAVE_CPSR
        LDR     r0,[r1]         ; r0 <- SAVE_CPSR
        SWI     SWI_PM_IF_RECOV ; restore CPSR  input parameter:r0 -> CPSR

;*** set normal end return value(0) ***
        MOV     r0,#0                           ; set narmal end return value

pm_stop_halt_end
;*** restore registers ***
        LDMFD   SP!,{r2-r7,lr}  ; restore r2-r7,lr register
        BX      lr              ; return


;************************************************************************
;*                                                                      *
;* change DIVA_CLK                                                      *
;*   DIVA_CLK speed : 1/1, 1/2, 1/4, 1/8, 1/16, 1/32                    *
;*                                                                      *
;* pm_diva_clkgear                                                      *
;*                                                                      *
;* input                                                                *
;*      r0:dividing ratio   0=1/1, 1=1/2, 2=1/4, 3=1/8, 4=1/16, 5=1/32  *
;*                                                                      *
;*      r1:mode             0 = slow->fast                              *
;*                          1 = fast->slow                              *
;*                                                                      *
;*----------------------------------------------------------------------*
;*                                                                      *
;* C API name   unsigned long pm_diva_clkgear                           *
;*                              (unsigned long Change_diva_clk,         *
;*                               unsigned long Mode_flag)               *
;*                                                                      *
;* input        unsigned long Change_diva_clk                           *
;*                              0 = 1/1                                 *
;*                              1 = 1/2                                 *
;*                              2 = 1/4                                 *
;*                              3 = 1/8                                 *
;*                              4 = 1/16                                *
;*                              5 = 1/32                                *
;*              unsigned long Mode_flag                                 *
;*                              0 = slow->fast                          *
;*                              1 = fast->slow                          *
;*                                                                      *
;* output       0       : normal end                                    *
;*              non 0   : input parameter error                         *
;*                                                                      *
;*----------------------------------------------------------------------*
;*                                                                      *
;* using register       r0,r1,r2,r3                                     *
;*                                                                      *
;************************************************************************

        EXPORT  pm_diva_clkgear
pm_diva_clkgear       ; unsigned long pm_diva_clkgear(unsigned long Change_diva_clk
                      ;                                 unsigned long Mode_flag)

;*** input parameter check ***
        CMP     r0,#0x5
        BHI     pm_diva_clkgear_error_end   ; error end
        CMP     r1,#0x1
        BHI     pm_diva_clkgear_error_end   ; error end

;*** save registers ***
        STMFD   SP!,{r1-r3,lr}  ; save r1-r3,lr register

;*** mask IRQ and FIQ. and get pre-masked CPSR ***
        MOV     r3,r0           ; save r0->r3
        SWI     SWI_PM_IF_DIS   ; mask IRQ and FIQ, return value:r0 = pre-masked CPSR

;*** save pre-masked CPSR ***
        LDR     r2,=SAVE_CPSR   ; save CPSR -> SAVE_CPSR
        STR     r0,[r2]
        MOV     r0,r3           ; restore r3->r0

;*** wait ***
        nop                     ; NOP * 1

;*** branch to each mode ***
        ADR     r2,pm_diva_clkgear_Jump_Table

⌨️ 快捷键说明

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