fix for mbed lib issue 3 (i2c problem) see also https://mbed.org/users/mbed_official/code/mbed/issues/3 affected implementations: LPC812, LPC11U24, LPC1768, LPC2368, LPC4088

Fork of mbed-src by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers startup_lpc407x_8x.cpp Source File

startup_lpc407x_8x.cpp

00001 //*****************************************************************************
00002 //   +--+       
00003 //   | ++----+   
00004 //   +-++    |  
00005 //     |     |  
00006 //   +-+--+  |   
00007 //   | +--+--+  
00008 //   +----+    Copyright (c) 2012 Code Red Technologies Ltd.
00009 //
00010 // LPC407x_8x Microcontroller Startup code for use with Red Suite
00011 //
00012 // Version : 120624
00013 //
00014 // Software License Agreement
00015 // 
00016 // The software is owned by Code Red Technologies and/or its suppliers, and is 
00017 // protected under applicable copyright laws.  All rights are reserved.  Any 
00018 // use in violation of the foregoing restrictions may subject the user to criminal 
00019 // sanctions under applicable laws, as well as to civil liability for the breach
00020 // of the terms and conditions of this license.
00021 // 
00022 // THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
00023 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
00024 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
00025 // USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
00026 // TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
00027 // CODE RED TECHNOLOGIES LTD. 
00028 //
00029 //*****************************************************************************
00030 #if defined (__cplusplus)
00031 #ifdef __REDLIB__
00032 #error Redlib does not support C++
00033 #else
00034 //*****************************************************************************
00035 //
00036 // The entry point for the C++ library startup
00037 //
00038 //*****************************************************************************
00039 extern "C" {
00040     extern void __libc_init_array(void);
00041 }
00042 #endif
00043 #endif
00044 
00045 #define WEAK __attribute__ ((weak))
00046 #define ALIAS(f) __attribute__ ((weak, alias (#f)))
00047 
00048 //#if defined (__USE_CMSIS)
00049 #include "LPC407x_8x_177x_8x.h"
00050 //#endif
00051 
00052 //*****************************************************************************
00053 #if defined (__cplusplus)
00054 extern "C" {
00055 #endif
00056 
00057 //*****************************************************************************
00058 //
00059 // Forward declaration of the default handlers. These are aliased.
00060 // When the application defines a handler (with the same name), this will 
00061 // automatically take precedence over these weak definitions
00062 //
00063 //*****************************************************************************
00064      void ResetISR(void);
00065 WEAK void NMI_Handler(void);
00066 WEAK void HardFault_Handler(void);
00067 WEAK void MemManage_Handler(void);
00068 WEAK void BusFault_Handler(void);
00069 WEAK void UsageFault_Handler(void);
00070 WEAK void SVC_Handler(void);
00071 WEAK void DebugMon_Handler(void);
00072 WEAK void PendSV_Handler(void);
00073 WEAK void SysTick_Handler(void);
00074 WEAK void IntDefaultHandler(void);
00075 
00076 //*****************************************************************************
00077 //
00078 // Forward declaration of the specific IRQ handlers. These are aliased
00079 // to the IntDefaultHandler, which is a 'forever' loop. When the application
00080 // defines a handler (with the same name), this will automatically take 
00081 // precedence over these weak definitions
00082 //
00083 //*****************************************************************************
00084 void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
00085 void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);
00086 void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);
00087 void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);
00088 void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);
00089 void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);
00090 void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);
00091 void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);
00092 void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);
00093 void PWM1_IRQHandler(void) ALIAS(IntDefaultHandler);
00094 void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);
00095 void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);
00096 void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler);
00097 void SPI_IRQHandler(void) ALIAS(IntDefaultHandler);
00098 void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);
00099 void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);
00100 void PLL0_IRQHandler(void) ALIAS(IntDefaultHandler);
00101 void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);
00102 void EINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
00103 void EINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
00104 void EINT2_IRQHandler(void) ALIAS(IntDefaultHandler);
00105 void EINT3_IRQHandler(void) ALIAS(IntDefaultHandler);
00106 void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);
00107 void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
00108 void USB_IRQHandler(void) ALIAS(IntDefaultHandler);
00109 void CAN_IRQHandler(void) ALIAS(IntDefaultHandler);
00110 void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);
00111 void I2S_IRQHandler(void) ALIAS(IntDefaultHandler);
00112 void ENET_IRQHandler(void) ALIAS(IntDefaultHandler);
00113 void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);
00114 void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);
00115 void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);
00116 void PLL1_IRQHandler(void) ALIAS(IntDefaultHandler);
00117 void USBActivity_IRQHandler(void) ALIAS(IntDefaultHandler);
00118 void CANActivity_IRQHandler(void) ALIAS(IntDefaultHandler);
00119 void MCI_IRQHandler(void) ALIAS(IntDefaultHandler);
00120 void UART4_IRQHandler(void) ALIAS(IntDefaultHandler);
00121 void SSP2_IRQHandler(void) ALIAS(IntDefaultHandler);
00122 void LCD_IRQHandler(void) ALIAS(IntDefaultHandler);
00123 void GPIO_IRQHandler(void) ALIAS(IntDefaultHandler);
00124 void PWM0_IRQHandler(void) ALIAS(IntDefaultHandler);
00125 void EEPROM_IRQHandler(void) ALIAS(IntDefaultHandler);
00126 
00127 //*****************************************************************************
00128 //
00129 // The entry point for the application.
00130 // __main() is the entry point for Redlib based applications
00131 // main() is the entry point for Newlib based applications
00132 //
00133 //*****************************************************************************
00134 #if defined (__REDLIB__)
00135 extern void __main(void);
00136 #endif
00137 extern int main(void);
00138 //*****************************************************************************
00139 //
00140 // External declaration for the pointer to the stack top from the Linker Script
00141 //
00142 //*****************************************************************************
00143 extern void _vStackTop(void);
00144 
00145 //*****************************************************************************
00146 #if defined (__cplusplus)
00147 } // extern "C"
00148 #endif
00149 //*****************************************************************************
00150 //
00151 // The vector table.
00152 // This relies on the linker script to place at correct location in memory.
00153 //
00154 //*****************************************************************************
00155 extern void (* const g_pfnVectors[])(void);
00156 __attribute__ ((section(".isr_vector")))
00157 void (* const g_pfnVectors[])(void) = {
00158     // Core Level - CM3
00159     &_vStackTop, // The initial stack pointer
00160     ResetISR,                           // The reset handler
00161     NMI_Handler,                            // The NMI handler
00162     HardFault_Handler,                      // The hard fault handler
00163     MemManage_Handler,                      // The MPU fault handler
00164     BusFault_Handler,                       // The bus fault handler
00165     UsageFault_Handler,                     // The usage fault handler
00166     0,                              // Reserved
00167     0,                              // Reserved
00168     0,                              // Reserved
00169     0,                              // Reserved
00170     SVC_Handler,                            // SVCall handler
00171     DebugMon_Handler,                       // Debug monitor handler
00172     0,                              // Reserved
00173     PendSV_Handler,                         // The PendSV handler
00174     SysTick_Handler,                        // The SysTick handler
00175 
00176     // Chip Level - LPC17
00177     WDT_IRQHandler,                         // 16, 0x40 - WDT
00178     TIMER0_IRQHandler,                      // 17, 0x44 - TIMER0
00179     TIMER1_IRQHandler,                      // 18, 0x48 - TIMER1
00180     TIMER2_IRQHandler,                      // 19, 0x4c - TIMER2
00181     TIMER3_IRQHandler,                      // 20, 0x50 - TIMER3
00182     UART0_IRQHandler,                       // 21, 0x54 - UART0
00183     UART1_IRQHandler,                       // 22, 0x58 - UART1
00184     UART2_IRQHandler,                       // 23, 0x5c - UART2
00185     UART3_IRQHandler,                       // 24, 0x60 - UART3
00186     PWM1_IRQHandler,                        // 25, 0x64 - PWM1
00187     I2C0_IRQHandler,                        // 26, 0x68 - I2C0
00188     I2C1_IRQHandler,                        // 27, 0x6c - I2C1
00189     I2C2_IRQHandler,                        // 28, 0x70 - I2C2
00190     IntDefaultHandler,                      // 29, Not used
00191     SSP0_IRQHandler,                        // 30, 0x78 - SSP0
00192     SSP1_IRQHandler,                        // 31, 0x7c - SSP1
00193     PLL0_IRQHandler,                        // 32, 0x80 - PLL0 (Main PLL)
00194     RTC_IRQHandler,                         // 33, 0x84 - RTC
00195     EINT0_IRQHandler,                       // 34, 0x88 - EINT0
00196     EINT1_IRQHandler,                       // 35, 0x8c - EINT1
00197     EINT2_IRQHandler,                       // 36, 0x90 - EINT2
00198     EINT3_IRQHandler,                       // 37, 0x94 - EINT3
00199     ADC_IRQHandler,                         // 38, 0x98 - ADC
00200     BOD_IRQHandler,                         // 39, 0x9c - BOD
00201     USB_IRQHandler,                         // 40, 0xA0 - USB
00202     CAN_IRQHandler,                         // 41, 0xa4 - CAN
00203     DMA_IRQHandler,                         // 42, 0xa8 - GP DMA
00204     I2S_IRQHandler,                         // 43, 0xac - I2S
00205     ENET_IRQHandler,                        // 44, 0xb0 - Ethernet
00206     MCI_IRQHandler,                         // 45, 0xb4 - SD/MMC card I/F
00207     MCPWM_IRQHandler,                       // 46, 0xb8 - Motor Control PWM
00208     QEI_IRQHandler,                         // 47, 0xbc - Quadrature Encoder
00209     PLL1_IRQHandler,                        // 48, 0xc0 - PLL1 (USB PLL)
00210     USBActivity_IRQHandler,                     // 49, 0xc4 - USB Activity interrupt to wakeup
00211     CANActivity_IRQHandler,                     // 50, 0xc8 - CAN Activity interrupt to wakeup
00212     UART4_IRQHandler,                       // 51, 0xcc - UART4
00213 
00214     SSP2_IRQHandler,                        // 52, 0xd0 - SSP2
00215     LCD_IRQHandler,                         // 53, 0xd4 - LCD
00216     GPIO_IRQHandler,                        // 54, 0xd8 - GPIO
00217     PWM0_IRQHandler,                        // 55, 0xdc - PWM0
00218     EEPROM_IRQHandler,                      // 56, 0xe0 - EEPROM
00219 
00220 };
00221 
00222 //*****************************************************************************
00223 // Functions to carry out the initialization of RW and BSS data sections. These
00224 // are written as separate functions rather than being inlined within the
00225 // ResetISR() function in order to cope with MCUs with multiple banks of
00226 // memory.
00227 //*****************************************************************************
00228 __attribute__ ((section(".after_vectors")))
00229 void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
00230     unsigned int *pulDest = (unsigned int*) start;
00231     unsigned int *pulSrc = (unsigned int*) romstart;
00232     unsigned int loop;
00233     for (loop = 0; loop < len; loop = loop + 4)
00234         *pulDest++ = *pulSrc++;
00235 }
00236 
00237 __attribute__ ((section(".after_vectors")))
00238 void bss_init(unsigned int start, unsigned int len) {
00239     unsigned int *pulDest = (unsigned int*) start;
00240     unsigned int loop;
00241     for (loop = 0; loop < len; loop = loop + 4)
00242         *pulDest++ = 0;
00243 }
00244 
00245 //*****************************************************************************
00246 // The following symbols are constructs generated by the linker, indicating
00247 // the location of various points in the "Global Section Table". This table is
00248 // created by the linker via the Code Red managed linker script mechanism. It
00249 // contains the load address, execution address and length of each RW data
00250 // section and the execution and length of each BSS (zero initialized) section.
00251 //*****************************************************************************
00252 extern unsigned int __data_section_table;
00253 extern unsigned int __data_section_table_end;
00254 extern unsigned int __bss_section_table;
00255 extern unsigned int __bss_section_table_end;
00256 
00257 //*****************************************************************************
00258 // Reset entry point for your code.
00259 // Sets up a simple runtime environment and initializes the C/C++
00260 // library.
00261 //*****************************************************************************
00262 __attribute__ ((section(".after_vectors")))
00263 void
00264 ResetISR(void) {
00265 
00266     //
00267     // Copy the data sections from flash to SRAM.
00268     //
00269     unsigned int LoadAddr, ExeAddr, SectionLen;
00270     unsigned int *SectionTableAddr;
00271 
00272     // Load base address of Global Section Table
00273     SectionTableAddr = &__data_section_table;
00274 
00275     // Copy the data sections from flash to SRAM.
00276     while (SectionTableAddr < &__data_section_table_end) {
00277         LoadAddr = *SectionTableAddr++;
00278         ExeAddr = *SectionTableAddr++;
00279         SectionLen = *SectionTableAddr++;
00280         data_init(LoadAddr, ExeAddr, SectionLen);
00281     }
00282     // At this point, SectionTableAddr = &__bss_section_table;
00283     // Zero fill the bss segment
00284     while (SectionTableAddr < &__bss_section_table_end) {
00285         ExeAddr = *SectionTableAddr++;
00286         SectionLen = *SectionTableAddr++;
00287         bss_init(ExeAddr, SectionLen);
00288     }
00289 
00290 #if defined (__VFP_FP__) && !defined (__SOFTFP__)
00291 /*
00292  * Code to enable the Cortex-M4 FPU only included
00293  * if appropriate build options have been selected.
00294  * Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C)
00295  */  
00296     // Read CPACR (located at address 0xE000ED88)
00297     // Set bits 20-23 to enable CP10 and CP11 coprocessors
00298     // Write back the modified value to the CPACR
00299     asm volatile ("LDR.W R0, =0xE000ED88\n\t"
00300                   "LDR R1, [R0]\n\t"
00301                   "ORR R1, R1, #(0xF << 20)\n\t"
00302                   "STR R1, [R0]");  
00303 #endif // (__VFP_FP__) && !(__SOFTFP__)
00304 
00305     // Check to see if we are running the code from a non-zero
00306     // address (eg RAM, external flash), in which case we need
00307     // to modify the VTOR register to tell the CPU that the
00308     // vector table is located at a non-0x0 address.
00309 
00310     // Note that we do not use the CMSIS register access mechanism,
00311     // as there is no guarantee that the project has been configured
00312     // to use CMSIS.
00313     unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;
00314     if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) {
00315         // CMSIS : SCB->VTOR = <address of vector table>
00316         *pSCB_VTOR = (unsigned int)g_pfnVectors;
00317     }
00318 
00319 //#ifdef __USE_CMSIS
00320     SystemInit();
00321 //#endif
00322 
00323 #if defined (__cplusplus)
00324     //
00325     // Call C++ library initialisation
00326     //
00327     __libc_init_array();
00328 #endif
00329 
00330 #if defined (__REDLIB__)
00331     // Call the Redlib library, which in turn calls main()
00332     __main() ;
00333 #else
00334     main();
00335 #endif
00336 
00337     //
00338     // main() shouldn't return, but if it does, we'll just enter an infinite loop 
00339     //
00340     while (1) {
00341         ;
00342     }
00343 }
00344 
00345 //*****************************************************************************
00346 // Default exception handlers. Override the ones here by defining your own
00347 // handler routines in your application code.
00348 //*****************************************************************************
00349 __attribute__ ((section(".after_vectors")))
00350 void NMI_Handler(void)
00351 {
00352     while(1)
00353     {
00354     }
00355 }
00356 __attribute__ ((section(".after_vectors")))
00357 void HardFault_Handler(void)
00358 {
00359     while(1)
00360     {
00361     }
00362 }
00363 __attribute__ ((section(".after_vectors")))
00364 void MemManage_Handler(void)
00365 {
00366     while(1)
00367     {
00368     }
00369 }
00370 __attribute__ ((section(".after_vectors")))
00371 void BusFault_Handler(void)
00372 {
00373     while(1)
00374     {
00375     }
00376 }
00377 __attribute__ ((section(".after_vectors")))
00378 void UsageFault_Handler(void)
00379 {
00380     while(1)
00381     {
00382     }
00383 }
00384 __attribute__ ((section(".after_vectors")))
00385 void SVC_Handler(void)
00386 {
00387     while(1)
00388     {
00389     }
00390 }
00391 __attribute__ ((section(".after_vectors")))
00392 void DebugMon_Handler(void)
00393 {
00394     while(1)
00395     {
00396     }
00397 }
00398 __attribute__ ((section(".after_vectors")))
00399 void PendSV_Handler(void)
00400 {
00401     while(1)
00402     {
00403     }
00404 }
00405 __attribute__ ((section(".after_vectors")))
00406 void SysTick_Handler(void)
00407 {
00408     while(1)
00409     {
00410     }
00411 }
00412 
00413 //*****************************************************************************
00414 //
00415 // Processor ends up here if an unexpected interrupt occurs or a specific
00416 // handler is not present in the application code.
00417 //
00418 //*****************************************************************************
00419 __attribute__ ((section(".after_vectors")))
00420 void IntDefaultHandler(void)
00421 {
00422     while(1)
00423     {
00424     }
00425 }
00426 
00427 #include <stdlib.h>
00428 
00429 void *operator new(size_t size)  {return malloc(size);}
00430 void *operator new[](size_t size){return malloc(size);}
00431 
00432 void operator delete(void *p)   {free(p);}
00433 void operator delete[](void *p) {free(p);}