📄 pwmc.lst
字号:
\ ??PWMC_ConfigureChannel_2:
\ 0000004C 80CFD3E3 BICS R12,R3,#0x200
\ 00000050 0600000A BEQ ??PWMC_ConfigureChannel_4
\ 00000054 ........ LDR R0,??DataTable23 ;; `?<Constant "-F- ASSERT: ">`
\ 00000058 ........ BL printf
\ 0000005C 6820A0E3 MOV R2,#+104
\ 00000060 ........ LDR R1,??DataTable24 ;; `?<Constant "F:\\\\Diplomovka\\\\IARproj...">`
\ 00000064 ........ LDR R0,??DataTable25 ;; `?<Constant "Sanity check failed a...">`
\ 00000068 ........ BL printf
\ ??PWMC_ConfigureChannel_5:
\ 0000006C FEFFFFEA B ??PWMC_ConfigureChannel_5
105
106 // Disable channel (effective at the end of the current period)
107 if ((AT91C_BASE_PWMC->PWMC_SR & (1 << channel)) != 0) {
\ ??PWMC_ConfigureChannel_4:
\ 00000070 ........ LDR R12,??DataTable18 ;; 0xfffcc00c
\ 00000074 00C09CE5 LDR R12,[R12, #+0]
\ 00000078 01E0A0E3 MOV LR,#+1
\ 0000007C 1E001CE1 TST R12,LR, LSL R0
\ 00000080 0800000A BEQ ??PWMC_ConfigureChannel_6
108 AT91C_BASE_PWMC->PWMC_DIS = 1 << channel;
\ 00000084 01C0A0E3 MOV R12,#+1
\ 00000088 1CC0A0E1 LSL R12,R12,R0
\ 0000008C ........ LDR LR,??DataTable29 ;; 0xfffcc008
\ 00000090 00C08EE5 STR R12,[LR, #+0]
109 while ((AT91C_BASE_PWMC->PWMC_SR & (1 << channel)) != 0);
\ ??PWMC_ConfigureChannel_7:
\ 00000094 ........ LDR R12,??DataTable18 ;; 0xfffcc00c
\ 00000098 00C09CE5 LDR R12,[R12, #+0]
\ 0000009C 01E0A0E3 MOV LR,#+1
\ 000000A0 1E001CE1 TST R12,LR, LSL R0
\ 000000A4 FAFFFF1A BNE ??PWMC_ConfigureChannel_7
110 }
111
112 // Configure channel
113 AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CMR = prescaler | alignment | polarity;
\ ??PWMC_ConfigureChannel_6:
\ 000000A8 011082E1 ORR R1,R2,R1
\ 000000AC 011083E1 ORR R1,R3,R1
\ 000000B0 ........ LDR R2,??DataTable28 ;; 0xfffcc200
\ 000000B4 801282E7 STR R1,[R2, +R0, LSL #+5]
114 }
\ 000000B8 0140BDE8 POP {R0,LR}
\ 000000BC 1EFF2FE1 BX LR ;; return
115
116 //------------------------------------------------------------------------------
117 /// Configures PWM clocks A & B to run at the given frequencies. This function
118 /// finds the best MCK divisor and prescaler values automatically.
119 /// \param clka Desired clock A frequency (0 if not used).
120 /// \param clkb Desired clock B frequency (0 if not used).
121 /// \param mck Master clock frequency.
122 //------------------------------------------------------------------------------
\ In section .text, align 4, keep-with-next
123 void PWMC_ConfigureClocks(unsigned int clka, unsigned int clkb, unsigned int mck)
124 {
\ PWMC_ConfigureClocks:
\ 00000000 F8402DE9 PUSH {R3-R7,LR}
\ 00000004 0050A0E1 MOV R5,R0
\ 00000008 0160A0E1 MOV R6,R1
\ 0000000C 0240A0E1 MOV R4,R2
125 unsigned int mode = 0;
\ 00000010 0070A0E3 MOV R7,#+0
126 unsigned int result;
127
128 // Clock A
129 if (clka != 0) {
\ 00000014 000055E3 CMP R5,#+0
\ 00000018 0A00000A BEQ ??PWMC_ConfigureClocks_0
130
131 result = FindClockConfiguration(clka, mck);
\ 0000001C 0410A0E1 MOV R1,R4
\ 00000020 ........ BL FindClockConfiguration
132 ASSERT(result != 0, "-F- Could not generate the desired PWM frequency (%uHz)\n\r", clka);
\ 00000024 000050E3 CMP R0,#+0
\ 00000028 0500001A BNE ??PWMC_ConfigureClocks_1
\ 0000002C ........ LDR R0,??DataTable23 ;; `?<Constant "-F- ASSERT: ">`
\ 00000030 ........ BL printf
\ 00000034 0510A0E1 MOV R1,R5
\ 00000038 50009FE5 LDR R0,??PWMC_ConfigureClocks_2 ;; `?<Constant "-F- Could not generat...">`
\ 0000003C ........ BL printf
\ ??PWMC_ConfigureClocks_3:
\ 00000040 FEFFFFEA B ??PWMC_ConfigureClocks_3
133 mode |= result;
\ ??PWMC_ConfigureClocks_1:
\ 00000044 0070A0E1 MOV R7,R0
134 }
135
136 // Clock B
137 if (clkb != 0) {
\ ??PWMC_ConfigureClocks_0:
\ 00000048 000056E3 CMP R6,#+0
\ 0000004C 0B00000A BEQ ??PWMC_ConfigureClocks_4
138
139 result = FindClockConfiguration(clkb, mck);
\ 00000050 0410A0E1 MOV R1,R4
\ 00000054 0600A0E1 MOV R0,R6
\ 00000058 ........ BL FindClockConfiguration
140 ASSERT(result != 0, "-F- Could not generate the desired PWM frequency (%uHz)\n\r", clkb);
\ 0000005C 000050E3 CMP R0,#+0
\ 00000060 0500001A BNE ??PWMC_ConfigureClocks_5
\ 00000064 ........ LDR R0,??DataTable23 ;; `?<Constant "-F- ASSERT: ">`
\ 00000068 ........ BL printf
\ 0000006C 0610A0E1 MOV R1,R6
\ 00000070 18009FE5 LDR R0,??PWMC_ConfigureClocks_2 ;; `?<Constant "-F- Could not generat...">`
\ 00000074 ........ BL printf
\ ??PWMC_ConfigureClocks_6:
\ 00000078 FEFFFFEA B ??PWMC_ConfigureClocks_6
141 mode |= (result << 16);
\ ??PWMC_ConfigureClocks_5:
\ 0000007C 007887E1 ORR R7,R7,R0, LSL #+16
142 }
143
144 // Configure clocks
145 TRACE_DEBUG("Setting PWMC_MR = 0x%08X\n\r", mode);
146 AT91C_BASE_PWMC->PWMC_MR = mode;
\ ??PWMC_ConfigureClocks_4:
\ 00000080 0C009FE5 LDR R0,??PWMC_ConfigureClocks_2+0x4 ;; 0xfffcc000
\ 00000084 007080E5 STR R7,[R0, #+0]
147 }
\ 00000088 F140BDE8 POP {R0,R4-R7,LR}
\ 0000008C 1EFF2FE1 BX LR ;; return
\ ??PWMC_ConfigureClocks_2:
\ 00000090 ........ DC32 `?<Constant "-F- Could not generat...">`
\ 00000094 00C0FCFF DC32 0xfffcc000
148
149 //------------------------------------------------------------------------------
150 /// Sets the period value used by a PWM channel. This function writes directly
151 /// to the CPRD register if the channel is disabled; otherwise, it uses the
152 /// update register CUPD.
153 /// \param channel Channel number.
154 /// \param period Period value.
155 //------------------------------------------------------------------------------
\ In section .text, align 4, keep-with-next
156 void PWMC_SetPeriod(unsigned char channel, unsigned short period)
157 {
158 // If channel is disabled, write to CPRD
159 if ((AT91C_BASE_PWMC->PWMC_SR & (1 << channel)) == 0) {
\ PWMC_SetPeriod:
\ 00000000 ........ LDR R2,??DataTable18 ;; 0xfffcc00c
\ 00000004 002092E5 LDR R2,[R2, #+0]
\ 00000008 0130A0E3 MOV R3,#+1
\ 0000000C 130012E1 TST R2,R3, LSL R0
160
161 AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CPRDR = period;
\ 00000010 ........ LDREQ R2,??DataTable28 ;; 0xfffcc200
\ 00000014 80028200 ADDEQ R0,R2,R0, LSL #+5
\ 00000018 08108005 STREQ R1,[R0, #+8]
\ 0000001C 0800000A BEQ ??PWMC_SetPeriod_0
162 }
163 // Otherwise use update register
164 else {
165
166 AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CMR |= AT91C_PWMC_CPD;
\ 00000020 0020A0E1 MOV R2,R0
\ 00000024 ........ LDR R3,??DataTable28 ;; 0xfffcc200
\ 00000028 822293E7 LDR R2,[R3, +R2, LSL #+5]
\ 0000002C 402E82E3 ORR R2,R2,#0x400
\ 00000030 0030A0E1 MOV R3,R0
\ 00000034 ........ LDR R12,??DataTable28 ;; 0xfffcc200
\ 00000038 83228CE7 STR R2,[R12, +R3, LSL #+5]
167 AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CUPDR = period;
\ 0000003C 80028CE0 ADD R0,R12,R0, LSL #+5
\ 00000040 101080E5 STR R1,[R0, #+16]
168 }
169 }
\ ??PWMC_SetPeriod_0:
\ 00000044 1EFF2FE1 BX LR ;; return
170
171 //------------------------------------------------------------------------------
172 /// Sets the duty cycle used by a PWM channel. This function writes directly to
173 /// the CDTY register if the channel is disabled; otherwise it uses the
174 /// update register CUPD.
175 /// Note that the duty cycle must always be inferior or equal to the channel
176 /// period.
177 /// \param channel Channel number.
178 /// \param duty Duty cycle value.
179 //------------------------------------------------------------------------------
\ In section .text, align 4, keep-with-next
180 void PWMC_SetDutyCycle(unsigned char channel, unsigned short duty)
181 {
\ PWMC_SetDutyCycle:
\ 00000000 00502DE9 PUSH {R12,LR}
182 SANITY_CHECK(duty <= AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CPRDR);
\ 00000004 ........ LDR R3,??DataTable28 ;; 0xfffcc200
\ 00000008 802283E0 ADD R2,R3,R0, LSL #+5
\ 0000000C 082092E5 LDR R2,[R2, #+8]
\ 00000010 010052E1 CMP R2,R1
\ 00000014 0600002A BCS ??PWMC_SetDutyCycle_0
\ 00000018 ........ LDR R0,??DataTable23 ;; `?<Constant "-F- ASSERT: ">`
\ 0000001C ........ BL printf
\ 00000020 B620A0E3 MOV R2,#+182
\ 00000024 ........ LDR R1,??DataTable24 ;; `?<Constant "F:\\\\Diplomovka\\\\IARproj...">`
\ 00000028 ........ LDR R0,??DataTable25 ;; `?<Constant "Sanity check failed a...">`
\ 0000002C ........ BL printf
\ ??PWMC_SetDutyCycle_1:
\ 00000030 FEFFFFEA B ??PWMC_SetDutyCycle_1
183
184 // SAM7S errata
185 #if defined(at91sam7s16) || defined(at91sam7s161) || defined(at91sam7s32) \
186 || defined(at91sam7s321) || defined(at91sam7s64) || defined(at91sam7s128) \
187 || defined(at91sam7s256) || defined(at91sam7s512)
188 ASSERT(duty > 0, "-F- Duty cycle value 0 is not permitted on SAM7S chips.\n\r");
189 ASSERT((duty > 1) || (AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CMR & AT91C_PWMC_CALG),
190 "-F- Duty cycle value 1 is not permitted in left-aligned mode on SAM7S chips.\n\r");
191 #endif
192
193 // If channel is disabled, write to CDTY
194 if ((AT91C_BASE_PWMC->PWMC_SR & (1 << channel)) == 0) {
\ ??PWMC_SetDutyCycle_0:
\ 00000034 7D2F43E2 SUB R2,R3,#+500
\ 00000038 002092E5 LDR R2,[R2, #+0]
\ 0000003C 0130A0E3 MOV R3,#+1
\ 00000040 130012E1 TST R2,R3, LSL R0
195
196 AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CDTYR = duty;
\ 00000044 ........ LDREQ R2,??DataTable28 ;; 0xfffcc200
\ 00000048 80028200 ADDEQ R0,R2,R0, LSL #+5
\ 0000004C 04108005 STREQ R1,[R0, #+4]
\ 00000050 0800000A BEQ ??PWMC_SetDutyCycle_2
197 }
198 // Otherwise use update register
199 else {
200
201 AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CMR &= ~AT91C_PWMC_CPD;
\ 00000054 0020A0E1 MOV R2,R0
\ 00000058 ........ LDR R3,??DataTable28 ;; 0xfffcc200
\ 0000005C 822293E7 LDR R2,[R3, +R2, LSL #+5]
\ 00000060 402EC2E3 BIC R2,R2,#0x400
\ 00000064 0030A0E1 MOV R3,R0
\ 00000068 ........ LDR R12,??DataTable28 ;; 0xfffcc200
\ 0000006C 83228CE7 STR R2,[R12, +R3, LSL #+5]
202 AT91C_BASE_PWMC->PWMC_CH[channel].PWMC_CUPDR = duty;
\ 00000070 80028CE0 ADD R0,R12,R0, LSL #+5
\ 00000074 101080E5 STR R1,[R0, #+16]
203 }
204 }
\ ??PWMC_SetDutyCycle_2:
\ 00000078 0140BDE8 POP {R0,LR}
\ 0000007C 1EFF2FE1 BX LR ;; return
205
206 //------------------------------------------------------------------------------
207 /// Enables the given PWM channel. This does NOT enable the corresponding pin;
208 /// this must be done in the user code.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -