Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers iap.c Source File

iap.c

Go to the documentation of this file.
00001 /**
00002  * @file    iap.c
00003  * @brief
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2017-2017, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #include "iap.h"
00023 #include "cortex_m.h"
00024 #include "LPC11Uxx.h"
00025 
00026 iap_operation_t iap_op;
00027 static cortex_int_state_t state;
00028 static uint32_t lock_count;
00029 
00030 // taken code from the Nxp App Note AN11305
00031 /* This data must be global so it is not read from the stack */
00032 typedef void (*IAP)(uint32_t [], uint32_t []);
00033 static const IAP iap_entry = (IAP)0x1fff1ff1;
00034 #define init_msdstate() *((uint32_t *)(0x10000054)) = 0x0
00035 
00036 /* This function resets some microcontroller peripherals to reset
00037  * hardware configuration to ensure that the USB In-System Programming module
00038  * will work properly. It is normally called from reset and assumes some reset
00039  * configuration settings for the MCU.
00040  * Some of the peripheral configurations may be redundant in your specific
00041  * project.
00042  */
00043 void iap_reinvoke(void)
00044 {
00045     /* make sure USB clock is turned on before calling ISP */
00046     LPC_SYSCON->SYSAHBCLKCTRL |= 0x04000;
00047     /* make sure 32-bit Timer 1 is turned on before calling ISP */
00048     LPC_SYSCON->SYSAHBCLKCTRL |= 0x00400;
00049     /* make sure GPIO clock is turned on before calling ISP */
00050     LPC_SYSCON->SYSAHBCLKCTRL |= 0x00040;
00051     /* make sure IO configuration clock is turned on before calling ISP */
00052     LPC_SYSCON->SYSAHBCLKCTRL |= 0x10000;
00053     /* make sure AHB clock divider is 1:1 */
00054     LPC_SYSCON->SYSAHBCLKDIV = 1;
00055     /* Send Reinvoke ISP command to ISP entry point*/
00056     iap_op.cmd = 57;
00057     init_msdstate();                     /* Initialize Storage state machine */
00058     /* Set stack pointer to ROM value (reset default) This must be the last
00059      * piece of code executed before calling ISP, because most C expressions
00060      * and function returns will fail after the stack pointer is changed.
00061      * In addition ensure the CONTROL register is set to 0 so the MSP is
00062      * used rather than the PSP.
00063      */
00064     __set_MSP(*((volatile uint32_t *)0x00000000));
00065     __set_CONTROL(0);
00066     /* Enter ISP. We call "iap_entry" to enter ISP because the ISP entry is done
00067      * through the same command interface as IAP.
00068      */
00069     iap_entry(&iap_op.cmd, &iap_op.stat);
00070     // Not supposed to come back!
00071 }
00072 
00073 void iap_call(iap_operation_t *operation)
00074 {
00075     iap_entry(&operation->cmd, &operation->stat);
00076 }
00077 
00078 void iap_lock()
00079 {
00080     cortex_int_state_t local_state;
00081     local_state = cortex_int_get_and_disable();
00082     if (lock_count == 0) {
00083         state = local_state;
00084     }
00085     lock_count++;
00086 }
00087 
00088 void iap_unlock()
00089 {
00090     lock_count--;
00091     if (lock_count == 0) {
00092         cortex_int_restore(state);
00093     }
00094     
00095 }