📄 at45.lst
字号:
104
105 //------------------------------------------------------------------------------
106 /// This function returns 1 if the At45 driver is not executing any command;
107 /// otherwise it returns 0.
108 /// \param pAt45 Pointer to an At45 instance.
109 //------------------------------------------------------------------------------
\ In section .text, align 4, keep-with-next
110 unsigned char AT45_IsBusy(At45 *pAt45)
111 {
\ AT45_IsBusy:
\ 00000000 01402DE9 PUSH {R0,LR}
112 return SPID_IsBusy(pAt45->pSpid);
\ 00000004 000090E5 LDR R0,[R0, #+0]
\ 00000008 0050BDE8 POP {R12,LR}
\ 0000000C ........ B SPID_IsBusy ;; tailcall
113 }
114
115 //------------------------------------------------------------------------------
116 /// Sends a command to the dataflash through the SPI. The command is identified
117 /// by its command code and the number of bytes to transfer (1 + number of
118 /// address bytes + number of dummy bytes). If data needs to be received, then
119 /// a data buffer must be provided.
120 /// This function does not block; its optional callback will be invoked when
121 /// the transfer completes.
122 /// \param pAt45 Pointer to an At45 driver instance.
123 /// \param cmd Command code.
124 /// \param cmdSize Size of command code + address bytes + dummy bytes.
125 /// \param pData Data buffer.
126 /// \param dataSize Number of data bytes to send/receive.
127 /// \param address Address at which the command is performed if meaningful.
128 /// \param callback Optional callback to invoke at end of transfer.
129 /// \param pArgument Optional parameter to the callback function.
130 //------------------------------------------------------------------------------
\ In section .text, align 4, keep-with-next
131 unsigned char AT45_SendCommand(
132 At45 *pAt45,
133 unsigned char cmd,
134 unsigned char cmdSize,
135 unsigned char *pData,
136 unsigned int dataSize,
137 unsigned int address,
138 SpidCallback callback,
139 void *pArgument)
140 {
\ AT45_SendCommand:
\ 00000000 F84F2DE9 PUSH {R3-R11,LR}
\ 00000004 0040A0E1 MOV R4,R0
\ 00000008 0150A0E1 MOV R5,R1
\ 0000000C 0260A0E1 MOV R6,R2
\ 00000010 28709DE5 LDR R7,[SP, #+40]
\ 00000014 2C809DE5 LDR R8,[SP, #+44]
\ 00000018 30909DE5 LDR R9,[SP, #+48]
\ 0000001C 34A09DE5 LDR R10,[SP, #+52]
141 SpidCmd *pCommand;
142 const At45Desc *pDesc = pAt45->pDesc;
\ 00000020 1CB094E5 LDR R11,[R4, #+28]
143 unsigned int dfAddress = 0;
144
145 // Sanity checks
146 ASSERT(pAt45, "AT45_Command: pAt45 is 0.\n\r");
\ 00000024 000054E3 CMP R4,#+0
\ 00000028 0400001A BNE ??AT45_SendCommand_0
\ 0000002C ........ LDR R0,??DataTable4 ;; `?<Constant "-F- ASSERT: ">`
\ 00000030 ........ BL printf
\ 00000034 28019FE5 LDR R0,??AT45_SendCommand_1 ;; `?<Constant "AT45_Command: pAt45 i...">`
\ 00000038 ........ BL printf
\ ??AT45_SendCommand_2:
\ 0000003C FEFFFFEA B ??AT45_SendCommand_2
147 ASSERT(pDesc || (cmd == AT45_STATUS_READ),
148 "AT45_Command: Device has no descriptor, only STATUS_READ command allowed\n\r");
\ ??AT45_SendCommand_0:
\ 00000040 00005BE3 CMP R11,#+0
\ 00000044 0600001A BNE ??AT45_SendCommand_3
\ 00000048 D70055E3 CMP R5,#+215
\ 0000004C 0400000A BEQ ??AT45_SendCommand_3
\ 00000050 ........ LDR R0,??DataTable4 ;; `?<Constant "-F- ASSERT: ">`
\ 00000054 ........ BL printf
\ 00000058 08019FE5 LDR R0,??AT45_SendCommand_1+0x4 ;; `?<Constant "AT45_Command: Device ...">`
\ 0000005C ........ BL printf
\ ??AT45_SendCommand_4:
\ 00000060 FEFFFFEA B ??AT45_SendCommand_4
149
150 // Check if the SPI driver is available
151 if (AT45_IsBusy(pAt45)) {
\ ??AT45_SendCommand_3:
\ 00000064 ........ BL AT45_IsBusy
\ 00000068 000050E3 CMP R0,#+0
152
153 return AT45_ERROR_LOCK;
\ 0000006C 0100A013 MOVNE R0,#+1
\ 00000070 3900001A BNE ??AT45_SendCommand_5
154 }
155
156 // Compute command pattern
157 pAt45->pCmdBuffer[0] = cmd;
\ 00000074 2050C4E5 STRB R5,[R4, #+32]
158
159 // Add address bytes if necessary
160 if (cmdSize > 1) {
\ 00000078 020056E3 CMP R6,#+2
\ 0000007C 2B00003A BCC ??AT45_SendCommand_6
161
162 ASSERT(pDesc, "AT45_Command: No descriptor for dataflash.\n\r");
\ 00000080 00005BE3 CMP R11,#+0
\ 00000084 0400001A BNE ??AT45_SendCommand_7
\ 00000088 ........ LDR R0,??DataTable4 ;; `?<Constant "-F- ASSERT: ">`
\ 0000008C ........ BL printf
\ 00000090 D4009FE5 LDR R0,??AT45_SendCommand_1+0x8 ;; `?<Constant "AT45_Command: No desc...">`
\ 00000094 ........ BL printf
\ ??AT45_SendCommand_8:
\ 00000098 FEFFFFEA B ??AT45_SendCommand_8
163 if (!configuredBinaryPage) {
\ ??AT45_SendCommand_7:
\ 0000009C ........ LDR R0,??DataTable7 ;; configuredBinaryPage
\ 000000A0 0000D0E5 LDRB R0,[R0, #+0]
\ 000000A4 000050E3 CMP R0,#+0
\ 000000A8 0B00001A BNE ??AT45_SendCommand_9
164 dfAddress =
165 ((address / (pDesc->pageSize)) << pDesc->pageOffset)
166 + (address % (pDesc->pageSize));
\ 000000AC 0800A0E1 MOV R0,R8
\ 000000B0 08109BE5 LDR R1,[R11, #+8]
\ 000000B4 ........ BL __aeabi_uidivmod
\ 000000B8 0C109BE5 LDR R1,[R11, #+12]
\ 000000BC 08102DE5 STR R1,[SP, #-8]!
\ 000000C0 04008DE5 STR R0,[SP, #+4]
\ 000000C4 0800A0E1 MOV R0,R8
\ 000000C8 08109BE5 LDR R1,[R11, #+8]
\ 000000CC ........ BL __aeabi_uidivmod
\ 000000D0 04009DE5 LDR R0,[SP, #+4]
\ 000000D4 08209DE4 LDR R2,[SP], #+8
\ 000000D8 108281E0 ADD R8,R1,R0, LSL R2
167 }
168 else {
169 dfAddress = address;
170 }
171 // Write address bytes
172 if (pDesc->pageNumber >= 16384) {
\ ??AT45_SendCommand_9:
\ 000000DC 00009BE5 LDR R0,[R11, #+0]
\ 000000E0 400C50E3 CMP R0,#+16384
\ 000000E4 0C00003A BCC ??AT45_SendCommand_10
173
174 pAt45->pCmdBuffer[1] = ((dfAddress & 0x0F000000) >> 24);
\ 000000E8 F00608E2 AND R0,R8,#0xF000000
\ 000000EC 200CA0E1 LSR R0,R0,#+24
\ 000000F0 2100C4E5 STRB R0,[R4, #+33]
175 pAt45->pCmdBuffer[2] = ((dfAddress & 0x00FF0000) >> 16);
\ 000000F4 2808A0E1 LSR R0,R8,#+16
\ 000000F8 2200C4E5 STRB R0,[R4, #+34]
176 pAt45->pCmdBuffer[3] = ((dfAddress & 0x0000FF00) >> 8);
\ 000000FC 2804A0E1 LSR R0,R8,#+8
\ 00000100 2300C4E5 STRB R0,[R4, #+35]
177 pAt45->pCmdBuffer[4] = ((dfAddress & 0x000000FF) >> 0);
\ 00000104 2480C4E5 STRB R8,[R4, #+36]
178
179 if ((cmd != AT45_CONTINUOUS_READ) && (cmd != AT45_PAGE_READ)) {
\ 00000108 0B0055E3 CMP R5,#+11
\ 0000010C D2005513 CMPNE R5,#+210
\ 00000110 0600000A BEQ ??AT45_SendCommand_6
180
181 cmdSize++;
\ 00000114 016086E2 ADD R6,R6,#+1
\ 00000118 040000EA B ??AT45_SendCommand_6
182 }
183 }
184 else {
185
186 pAt45->pCmdBuffer[1] = ((dfAddress & 0x00FF0000) >> 16);
\ ??AT45_SendCommand_10:
\ 0000011C 2808A0E1 LSR R0,R8,#+16
\ 00000120 2100C4E5 STRB R0,[R4, #+33]
187 pAt45->pCmdBuffer[2] = ((dfAddress & 0x0000FF00) >> 8);
\ 00000124 2804A0E1 LSR R0,R8,#+8
\ 00000128 2200C4E5 STRB R0,[R4, #+34]
188 pAt45->pCmdBuffer[3] = ((dfAddress & 0x000000FF) >> 0);
\ 0000012C 2380C4E5 STRB R8,[R4, #+35]
189 }
190 }
191
192 // Update the SPI Transfer descriptors
193 pCommand = &(pAt45->command);
\ ??AT45_SendCommand_6:
\ 00000130 041084E2 ADD R1,R4,#+4
194 pCommand->cmdSize = cmdSize;
\ 00000134 0460C1E5 STRB R6,[R1, #+4]
195 pCommand->pData = pData;
\ 00000138 00009DE5 LDR R0,[SP, #+0]
\ 0000013C 080081E5 STR R0,[R1, #+8]
196 pCommand->dataSize = dataSize;
\ 00000140 BC70C1E1 STRH R7,[R1, #+12]
197 pCommand->callback = callback;
\ 00000144 109081E5 STR R9,[R1, #+16]
198 pCommand->pArgument = pArgument;
\ 00000148 14A081E5 STR R10,[R1, #+20]
199
200 // Send Command and data through the SPI
201 if (SPID_SendCommand(pAt45->pSpid, pCommand)) {
\ 0000014C 000094E5 LDR R0,[R4, #+0]
\ 00000150 ........ BL SPID_SendCommand
\ 00000154 000050E3 CMP R0,#+0
202
203 return AT45_ERROR_SPI;
\ 00000158 0200A013 MOVNE R0,#+2
204 }
205
206 return 0;
\ ??AT45_SendCommand_5:
\ 0000015C F84FBDE8 POP {R3-R11,LR}
\ 00000160 1EFF2FE1 BX LR ;; return
\ ??AT45_SendCommand_1:
\ 00000164 ........ DC32 `?<Constant "AT45_Command: pAt45 i...">`
\ 00000168 ........ DC32 `?<Constant "AT45_Command: Device ...">`
\ 0000016C ........ DC32 `?<Constant "AT45_Command: No desc...">`
207 }
208
209 //------------------------------------------------------------------------------
210 /// This function returns the At45Desc structure corresponding to the device
211 /// connected
212 /// It automatically initializes pAt45->pDesc field structure.
213 /// This function shall be called by the application before AT45_SendCommand.
214 /// Returns 0 if successful; Otherwise, returns AT45_ERROR_LOCK if the At45
215 /// driver is in use or AT45_ERROR_SPI if there was an error with the SPI driver.
216 /// \param pAt45 Pointer to an AT45 driver instance.
217 /// \param status Device status register value.
218 //------------------------------------------------------------------------------
\ In section .text, align 4, keep-with-next
219 const At45Desc * AT45_FindDevice(At45 *pAt45, unsigned char status)
220 {
\ AT45_FindDevice:
\ 00000000 01402DE9 PUSH {R0,LR}
221 unsigned int i;
222 unsigned char id = AT45_STATUS_ID(status);
\ 00000004 3C2001E2 AND R2,R1,#0x3C
223
224 // Check if status is all one; in which case, it is assumed that no device
225 // is connected
226 if (status == 0xFF) {
\ 00000008 FF0051E3 CMP R1,#+255
227
228 return 0;
\ 0000000C 0000A003 MOVEQ R0,#+0
\ 00000010 1500000A BEQ ??AT45_FindDevice_0
229 }
230
231 // Look in device array
232 i = 0;
\ 00000014 0030A0E3 MOV R3,#+0
233 pAt45->pDesc = 0;
\ 00000018 00C0A0E3 MOV R12,#+0
\ 0000001C 1CC080E5 STR R12,[R0, #+28]
234 while ((i < NUMDATAFLASH) && !(pAt45->pDesc)) {
235
236 if (at45Devices[i].id == id) {
\ ??AT45_FindDevice_1:
\ 00000020 18C0A0E3 MOV R12,#+24
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -