Debug tools / show registers, memory and system clock data
Target mbed board
LPC1768
LPC1114FN28
ST Nucleo L152RE
ST NUcleo F401RE
ST Nucleo F411RE
Command structure
Top
1 - goto step1 -> no connection all pins
2 - goto step2 -> connects pin_x and pin_y (not impliment yet)
t - Check and set RTC
x - Goto HW monitor
q - Return to main
>1
l - Check LED
b - Check button
s - CPU system info & clock
o - CPU clock output (Bug fix, port_mco1_mco2_set() function. Thanks Topi Makinen on April 25th, 2015)
>x(Hardware level monitor)
m - Entry Memory Mode
m>? -> Aditinal functions can see by ?
r - Entry Register Mode
r>? -> Aditinal functions can see by ?
s - System Clock -> sf, System / CPU information -> sc
q - Quit (back to called routine)
p - Entry Port Mode
p>? -> Aditinal functions can see by ?
Usage
Please modify "mon_hw_config.h" file for your purpose.
Especially LPC114FN28 has small memory, you cannot run your own program together with this program.
You don't need any additional HW. Just connect with PC via terminal software.
CAUTION
Due to several CPU's and short development time, I cannot grantee the quality level and several functions are not available yet.
If you found the bug, please let me know. Thanks in advance.
debug_tools/mon_hw_STM32.cpp
- Committer:
- kenjiArai
- Date:
- 2015-04-26
- Revision:
- 4:02980a730cfb
- Parent:
- 3:455df34f7285
File content as of revision 4:02980a730cfb:
/* * mbed Application program for the ST NUCLEO Board * Monitor program Ver.3 for only for STM32F401RE,F411RE & STM32L152RE * * Copyright (c) 2010-2015 Kenji Arai / JH1PJL * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * Started: May 9th, 2010 * Created: May 15th, 2010 * release as "monitor_01" http://mbed.org/users/kenjiArai/code/monitor_01/ * Spareted: June 25th, 2014 mon() & mon_hw() * restart: July 12th, 2014 * Revised: April 25th, 2015 Bug fix ('o' command) pointed out by Topi Makinen * Revised: April 26th, 2015 Change Port output speed (set High speed) * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_L152RE) // Include --------------------------------------------------------------------------------------- #include "mbed.h" #include "mon_hw_config.h" #include "mon_hw_common.h" #include "mon_hw_STM32.h" // Object ---------------------------------------------------------------------------------------- // Definition ------------------------------------------------------------------------------------ // USB Frequency #define USB_FREQ_H 48100000 #define USB_FREQ_L 47900000 // RAM ------------------------------------------------------------------------------------------- uint32_t SystemFrequency; uint8_t quitflag; uint32_t reg_save0, reg_save1, reg_save2, reg_save3, reg_save4, reg_save5, reg_save6; // ROM / Constant data --------------------------------------------------------------------------- #if defined(TARGET_NUCLEO_F401RE) char *const mon_msg = "HW monitor only for mbed Nucleo F401RE created on UTC:"__DATE__"("__TIME__")"; #if USE_MEM const uint32_t mem_range[][2] = { // Memory access range { 0x08000000, 0x0807ffff }, // On-chip Flash memory, 512KB Flash { 0x1fff0000, 0x1fff7a0f }, // System memory { 0x1fffc000, 0x1fffc007 }, // Option bytes { 0x20000000, 0x20017fff }, // Main Embedded SRAM, 96KB SRAM { 0x40000000, 0x5003ffff } // IO area }; #endif // USE_MEM #elif defined(TARGET_NUCLEO_F411RE) char *const mon_msg = "HW monitor only for mbed Nucleo F411RE created on UTC:"__DATE__"("__TIME__")"; #if USE_MEM const uint32_t mem_range[][2] = { // Memory access range { 0x08000000, 0x0807ffff }, // On-chip Flash memory, 512KB Flash { 0x1fff0000, 0x1fff7a0f }, // System memory { 0x1fffc000, 0x1fffc007 }, // Option bytes { 0x20000000, 0x2001ffff }, // Main Embedded SRAM, 128KB SRAM { 0x40000000, 0x5003ffff } // IO area }; #endif // USE_MEM #elif defined(TARGET_NUCLEO_L152RE) char *const mon_msg = "HW monitor only for mbed Nucleo L152RE created on UTC:"__DATE__"("__TIME__")"; #if USE_MEM const uint32_t mem_range[][2] = { // Memory access range { 0x08000000, 0x0807ffff }, // On-chip Flash memory, 512KB Flash { 0x08080000, 0x08083fff }, // EEPROM, 16KB { 0x1ff00000, 0x1ff01fff }, // System memory { 0x1ff80000, 0x1ff8009f }, // Option bytes { 0x20000000, 0x20013fff }, // Main Embedded SRAM, 32KB SRAM { 0x40000000, 0x400267ff } // IO area }; #endif // USE_MEM #endif char *const hmsg0 = "m - Entry Memory Mode"; char *const hmsg1 = "m>? -> Aditinal functions can see by ?"; char *const hmsg2 = "r - Entry Register Mode"; char *const hmsg3 = "r>? -> Aditinal functions can see by ?"; char *const hmsg4 = "s - System Clock -> sf, System / CPU information -> sc"; char *const hmsg5 = "q - Quit (back to called routine)"; char *const hmsg6 = "p - Entry Port Mode"; char *const hmsg7 = "p>? -> Aditinal functions can see by ?"; char *const mrmsg0 = "Enter Register Mode u,i,s,t,a,d,l,w,c & ? for help"; #if (USE_UART==1) || (USE_SPI==1) || (USE_I2C == 1) char *const mrmsg1 = "------"; char *const mrmsg2 = "USART"; // char *const mrmsg4 = "I2C"; // char *const mrmsg6 = "SPI"; // #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) char *const mrmsg3 = "Enter u1,u2,u6 and u* for all"; char *const mrmsg5 = "Enter i1,i2,i3 and i* for all"; char *const mrmsg7 = "Enter s1,s2,s3,s4 and s* for all"; #elif defined(TARGET_NUCLEO_L152RE) char *const mrmsg3 = "Enter u1,u2,u3,u5 and u* for all"; char *const mrmsg5 = "Enter i1,i2 and i* for all"; char *const mrmsg7 = "Enter s1,s2,s3 and s* for all"; #endif #endif // (USE_UART==1) || (USE_SPI==1) || (USE_I2C == 1) char *const mrmsg8 = "Return to All Mode"; //------------------------------------------------------------------------------------------------- // Control Program //------------------------------------------------------------------------------------------------- // No function static void not_yet_impliment( void ) { PRINTF("Not implimented yet"); put_rn(); } // No function #if (USE_MEM==0)||(USE_PORT==0)||(USE_UART==0)||(USE_SPI==0)||(USE_I2C==0)||(USE_SYS==0) static void not_select( void ) { PRINTF("Not select the function (refer mon_hw_config.h)"); put_rn(); } #endif // Help Massage void hw_msg_hlp ( void ) { PRINTF(mon_msg); put_rn(); PRINTF(hmsg0); put_rn(); PRINTF(hmsg1); put_rn(); PRINTF(hmsg6); put_rn(); PRINTF(hmsg7); put_rn(); PRINTF(hmsg2); put_rn(); PRINTF(hmsg3); put_rn(); PRINTF(hmsg4); put_rn(); PRINTF(hmsg5); put_rn(); } #if USE_MEM #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) char *const rmsg0 = "FLASH "; char *const rmsg1 = "SYS-Mem "; char *const rmsg2 = "OPTION "; char *const rmsg3 = "SRAM "; char *const rmsg4 = "IO "; #elif defined(TARGET_NUCLEO_L152RE) char *const rmsg0 = "FLASH "; char *const rmsg1 = "EEPROM "; char *const rmsg2 = "SYS-Mem "; char *const rmsg3 = "OPTION "; char *const rmsg4 = "SRAM "; char *const rmsg5 = "IO "; #endif #include "mon_hw_mem.h" #endif // USE_MEM // Show 16bit register contents void reg_print(uint16_t size, uint16_t reg) { uint16_t i, j, k, n; i = j = k = n = 0; switch (size) { case SIZE8: PRINTF(rgmsg0); put_rn(); i = 8; n = 0x80; break; case SIZE16: PRINTF("%s%s", rgmsg1, rgmsg0); put_rn(); i = 16; n = 0x8000; break; case SIZE32: PRINTF("0x%08x", reg); return; default : ; } PUTC(' '); for (; i>0; i--) { k = n >> (size-i); j = reg & k; if (j) { PUTC('1'); } else { PUTC('0'); } PUTC(' '); PUTC(' '); } PRINTF(" (0x%04x)", reg); } #if USE_I2C void i2c_reg( I2C_TypeDef* I2Cx ) { uint16_t reg; put_rn(); reg = I2Cx->CR1; reg_print( SIZE32, reg ); PRINTF( rnmsg0 ); PRINTF( imsg2 ); put_rn(); reg = I2Cx->CR2; reg_print( SIZE32, reg ); PRINTF( rnmsg1 ); PRINTF( imsg2 ); put_rn(); reg = I2Cx->SR1; reg_print( SIZE32, reg ); PRINTF( rnmsg5 ); PRINTF( imsg3 ); put_rn(); reg = I2Cx->SR2; reg_print( SIZE32, reg ); PRINTF( rnmsg6 ); PRINTF( imsg3 ); put_rn(); reg = I2Cx->DR; reg_print( SIZE32, reg ); PRINTF( rnmsg2 ); PRINTF( imsg4 ); put_rn(); reg = I2Cx->OAR1; reg_print( SIZE32, reg ); PRINTF( rnmsg7 ); PRINTF( imsg6 ); put_rn(); reg = I2Cx->OAR2; reg_print( SIZE32, reg ); PRINTF( rnmsg8 ); PRINTF( imsg6 ); put_rn(); reg = I2Cx->CCR; reg_print( SIZE32, reg ); PRINTF( rnmsg9 ); PRINTF( imsg7 ); put_rn(); reg = I2Cx->TRISE; reg_print( SIZE32, reg ); PRINTF( rnmsg10 ); PRINTF( imsg8 ); put_rn(); } #endif // USE_I2C #if USE_SPI void spi_reg( SPI_TypeDef* SPIx ) { uint16_t reg; put_rn(); reg = SPIx->CR1; reg_print( SIZE32, reg ); PRINTF( rnmsg0 ); PRINTF( imsg2 ); put_rn(); reg = SPIx->CR2; reg_print( SIZE32, reg ); PRINTF( rnmsg1 ); PRINTF( imsg2 ); put_rn(); reg = SPIx->SR; reg_print( SIZE32, reg ); PRINTF( rnmsg3 ); PRINTF( imsg3 ); put_rn(); reg = SPIx->DR; reg_print( SIZE32, reg ); PRINTF( rnmsg2 ); PRINTF( imsg4 ); put_rn(); } #endif // USE_SPI #if USE_UART void usart_reg( USART_TypeDef* USARTx ) { uint16_t reg; put_rn(); reg = USARTx->SR; reg_print( SIZE32, reg ); PRINTF( rnmsg3 ); PRINTF( imsg3 ); put_rn(); reg = USARTx->DR; reg_print( SIZE32, reg ); PRINTF( rnmsg2 ); PRINTF( imsg4 ); put_rn(); reg = USARTx->BRR; reg_print( SIZE32, reg ); PRINTF( rnmsg4 ); PRINTF( imsg5 ); put_rn(); reg = USARTx->CR1; reg_print( SIZE32, reg ); PRINTF( rnmsg0 ); PRINTF( imsg2 ); put_rn(); reg = USARTx->CR2; reg_print( SIZE32, reg ); PRINTF( rnmsg1 ); PRINTF( imsg2 ); put_rn(); } #endif // USE_UART #if USE_PORT void rpt_port_one( GPIO_TypeDef* GPIOx ) { uint32_t i; PRINTF( " " ); i = GPIOx->MODER; PRINTF( "0x%08x",i ); i = GPIOx->OTYPER; PRINTF( " 0x%04x",i ); i = GPIOx->OSPEEDR; PRINTF( " 0x%08x",i ); i = GPIOx->PUPDR; PRINTF( " 0x%08x",i ); i = GPIOx->IDR; PRINTF( " 0x%04x",i ); i = GPIOx->ODR; PRINTF( " 0x%04x",i ); put_rn(); } void rpt_port( void ) { PRINTF( pnmsg0 ); PRINTF( pnmsg1 ); put_rn(); PRINTF( pnmsga ); rpt_port_one( GPIOA ); PRINTF( pnmsgb ); rpt_port_one( GPIOB ); PRINTF( pnmsgc ); rpt_port_one( GPIOC ); PRINTF( pnmsgd ); rpt_port_one( GPIOD ); PRINTF( pnmsge ); rpt_port_one( GPIOE ); PRINTF( pnmsgh ); rpt_port_one( GPIOH ); } void port_inf_one( char *ptr ) { GPIO_TypeDef* GPIOx; uint32_t i,j; uint32_t pinpos; GPIOx = 0; PRINTF( pnmsg2 ); switch ( *ptr ) { case 'a': GPIOx = GPIOA; PUTC( 'A' ); break; case 'b': GPIOx = GPIOB; PUTC( 'B' ); break; case 'c': GPIOx = GPIOC; PUTC( 'C' ); break; case 'd': GPIOx = GPIOD; PUTC( 'D' ); break; case 'e': GPIOx = GPIOE; PUTC( 'E' ); break; case 'h': GPIOx = GPIOH; PUTC( 'H' ); break; } i = GPIOx->MODER; put_rn(); PRINTF( "-->Mode Reg. (0x%08x)",i ); put_rn(); for ( pinpos = 0x00; pinpos < 16; pinpos++ ) { j = GPIO_MODER_MODER0 & (i >> (pinpos * 2)); switch (j) { case GPIO_Mode_IN: PRINTF( "%2d= in", pinpos ); break; case GPIO_Mode_OUT: PRINTF( "%2d=out", pinpos ); break; case GPIO_Mode_AF: PRINTF( "%2d=alt", pinpos ); break; case GPIO_Mode_AN: PRINTF( "%2d=ana", pinpos ); break; default: break; } if ( (pinpos == 3) && (*ptr == 'h') ) { break; } else { if ( pinpos == 7 ) { put_rn(); } else if ( pinpos == 15 ) { ; } else { PRINTF(", "); } } } i = GPIOx->OTYPER; put_rn(); PRINTF( "%s type 1=push-pull, 0= open-drain", pnmsg4 ); put_rn(); reg_print( SIZE32,i); i = GPIOx->OSPEEDR; PRINTF( "%s speed [MHz] (0x%08x)", pnmsg4, i ); put_rn(); for ( pinpos = 0x00; pinpos < 16; pinpos++ ) { j = GPIO_OSPEEDER_OSPEEDR0 & (i >> (pinpos * 2)); switch (j) { case GPIO_Speed_400KHz: PRINTF( "%2d=0.4", pinpos ); break; case GPIO_Speed_2MHz: PRINTF( "%2d= 2", pinpos ); break; case GPIO_Speed_10MHz: PRINTF( "%2d= 10", pinpos ); break; case GPIO_Speed_40MHz: PRINTF( "%2d= 40", pinpos ); break; default: break; } if ( (pinpos == 3) && (*ptr == 'h') ) { break; } else { if ( pinpos == 7 ) { put_rn(); } else if ( pinpos == 15) { ; } else { PRINTF(", "); } } } i = GPIOx->PUPDR; put_rn(); PRINTF( "-->Pullup(pup)/down(pdn) none(no)(0x%08x)",i ); put_rn(); for ( pinpos = 0x00; pinpos < 16; pinpos++ ) { j = GPIO_PUPDR_PUPDR0 & (i >> (pinpos * 2)); switch (j) { case GPIO_PuPd_NOPULL: PRINTF( "%2d= no", pinpos ); break; case GPIO_PuPd_UP: PRINTF( "%2d=pup", pinpos ); break; case GPIO_PuPd_DOWN: PRINTF( "%2d=pdn", pinpos ); break; default: break; } if ( (pinpos == 3) && (*ptr == 'h') ) { break; } else { if ( pinpos == 7 ) { put_rn(); } else if ( pinpos == 15 ) { ; } else { PRINTF(", "); } } } put_rn(); PRINTF( "%s %s", pnmsg5, pnmsg6); i = GPIOx->IDR; reg_print( SIZE32,i); put_rn(); PRINTF( "%s %s", pnmsg4, pnmsg6); i = GPIOx->ODR; reg_print( SIZE32,i); put_rn(); } #endif // USE_PORT #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) void port_mco1_mco2_set(uint8_t n) { GPIO_TypeDef* GPIOx = 0; uint32_t temp = 0x00; if (n == 0){ // Just save the original setting // PA8 -> MCO_1 GPIOx = GPIOA; reg_save0 = GPIOx->AFR[8 >> 3]; reg_save1 = GPIOx->MODER; reg_save2 = GPIOx->OSPEEDR; GPIOx = GPIOC; reg_save3 = GPIOx->AFR[9 >> 3]; reg_save4 = GPIOx->MODER; reg_save5 = GPIOx->OSPEEDR; reg_save6 = RCC->CFGR; } else { // PA8 -> MCO_1 GPIOx = GPIOA; temp = ((uint32_t)(GPIO_AF0_MCO) << (((uint32_t)8 & (uint32_t)0x07) * 4)) ; GPIOx->AFR[8 >> 3] &= ~((uint32_t)0xf << ((uint32_t)(8 & (uint32_t)0x07) * 4)) ; GPIOx->AFR[8 >> 3] |= temp; GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (8 * 2)); GPIOx->MODER |= (0x2 << (8 * 2)); GPIOx->OSPEEDR |= (0x03 << (8 * 2)); // High speed // PC9 -> MCO_2 GPIOx = GPIOC; temp = ((uint32_t)(GPIO_AF0_MCO) << (((uint32_t)9 & (uint32_t)0x07) * 4)) ; GPIOx->AFR[9 >> 3] &= ~((uint32_t)0xf << ((uint32_t)(9 & (uint32_t)0x07) * 4)) ; GPIOx->AFR[9 >> 3] |= temp; GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (9 * 2)); GPIOx->MODER |= (0x2 << (9 * 2)); GPIOx->OSPEEDR |= (0x03 << (9 * 2)); // High speed // Select output clock source RCC->CFGR &= 0x009fffff; if (n == 1){ // MC0_1 output HSE 1/4, MCO_2 output SYSCLK 1/4 // MCO2 MCO2PRE MCO1PRE MCO1 RCC->CFGR |= (0x0 << 30) + (0x6 << 27) + (0x6 << 24) + (0x3 << 22); } else { // MC0_1 output HSE 1/1, MCO_2 output SYSCLK 1/2 // MCO2 MCO2PRE MCO1PRE MCO1 RCC->CFGR |= (0x0 << 30) + (0x4 << 27) + (0x0 << 24) + (0x3 << 22); } } } void port_mco1_mco2_recover(void) { GPIO_TypeDef* GPIOx = 0; // PA8 -> MCO_1 GPIOx = GPIOA; GPIOx->AFR[8 >> 3] = reg_save0; GPIOx->MODER = reg_save1; GPIOx->OSPEEDR = reg_save2; // PC9 -> MCO_2 GPIOx = GPIOC; GPIOx->AFR[9 >> 3] = reg_save3; GPIOx->MODER = reg_save4; GPIOx->OSPEEDR = reg_save5; // MC0_1 & MCO_2 RCC->CFGR = reg_save6; } #endif // defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) void cpu_inf( char *ptr ) { uint32_t m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0; switch (*ptr++) { case 'f' : // sc - show system clock frequency m1 = RCC->CR; PRINTF( "CR = 0x%08x", m1 ); put_rn(); m1 = RCC->PLLCFGR; PRINTF( "PLLCFGR = 0x%08x", m1 ); put_rn(); m1 = RCC->CFGR; PRINTF( "CFGR = 0x%08x", m1 ); put_rn(); m1 = RCC->CIR; PRINTF( "CIR = 0x%08x", m1 ); put_rn(); m1 = RCC->AHB1RSTR; PRINTF( "AHB1RSTR = 0x%08x", m1 ); put_rn(); m1 = RCC->APB2RSTR; PRINTF( "APB2RSTR = 0x%08x", m1 ); put_rn(); m1 = RCC->APB1RSTR; PRINTF( "APB1RSTR = 0x%08x", m1 ); put_rn(); m1 = RCC->AHB1ENR; PRINTF( "AHB1ENR = 0x%08x", m1 ); put_rn(); m1 = RCC->APB2ENR; PRINTF( "APB2ENR = 0x%08x", m1 ); put_rn(); m1 = RCC->APB2LPENR; PRINTF( "APB2LPENR= 0x%08x", m1 ); put_rn(); m1 = RCC->APB1LPENR; PRINTF( "APB1LPENR= 0x%08x", m1 ); put_rn(); m1 = RCC->CSR; PRINTF( "CSR = 0x%08x", m1 ); put_rn(); PRINTF(cmsg11); put_rn(); m1 = PWR->CR; PRINTF( "CR = 0x%08x", m1 ); put_rn(); m1 = PWR->CSR; PRINTF( "CSR = 0x%08x", m1 ); put_rn(); put_rn(); case 'F' : // sF - show system clock frequency m1 = RCC->CFGR & RCC_CFGR_SWS; /* Get SYSCLK source */ switch (m1) { case 0x00: // HSI used as system clock PRINTF( "%s, %s%dHz", cmsg2, cmsg1,HSI_VALUE ); m2 = HSI_VALUE; break; case 0x04: // HSE used as system clock PRINTF( "%s, %s%dHz", cmsg3, cmsg1, HSE_VALUE ); m2 = HSE_VALUE; break; case 0x08: // PLL used as system clock PRINTF("fVCO = fPLL-in x (PLLN/PLLM), fPLL-out = fVCO/PLLP, fUSB-out = fVCO/PLLQ"); put_rn(); m5 = (RCC->PLLCFGR >> 6) & 0x1ff; // PLLN m1 = RCC->PLLCFGR & 0x3f; // PLLM PRINTF( "%s PLLN=%d, PLLM=%d", cmsg4, m5, m1 ); put_rn(); m3 = (RCC->PLLCFGR >> 22) & 0x1; // Clock source if (m3 == 0) { // HSI oscillator clock selected as PLL clock source m2 = (HSI_VALUE * (m5 / m1)); PRINTF( "%s, RC=%dHz", cmsg2, HSI_VALUE ); } else { // HSE selected m2 = (((HSE_VALUE) * m5) / m1); if ((RCC->CR >> 18) & 0x01) { // check HSEBYP bit // HSE(not Xtal) selected as PLL clock source PRINTF( "Use HSE(not Xtal but External Clock)=%dHz", HSE_VALUE ); } else { // HSE(Xtal) selected as PLL clock source PRINTF( "%s, Xtal=%dHz", cmsg3, HSE_VALUE ); } } put_rn(); PRINTF("PLL/Base %s%dHz", cmsg1, m2); put_rn(); m3 = (RCC->PLLCFGR >> 16) & 0x03; // PLLP switch (m3) { case 0: m3 = 2; break; case 1: m3 = 4; break; case 2: m3 = 6; break; case 3: m3 = 8; break; } m4 = (RCC->PLLCFGR >> 24) & 0x0f; // PLLQ PRINTF("%s PLLP=%d, PLLQ=%d", cmsg4, m3, m4); put_rn(); PRINTF("PLL/System %s%dHz", cmsg1, m2/m3); put_rn(); PRINTF("PLL/USB %s%dHz", cmsg1, m2/m4); m2 = m2/m4; if ((m2 > USB_FREQ_H) || (m2 <USB_FREQ_L)) { PRINTF(" -> USB Freq. is out of range!"); } put_rn(); break; default: // Not come here PRINTF( cmsg5 ); break; } put_rn(); PRINTF( "SYSCLK %s%dHz", cmsg6, HAL_RCC_GetSysClockFreq()); put_rn(); PRINTF( "HCLK %s%dHz", cmsg6, HAL_RCC_GetHCLKFreq()); put_rn(); PRINTF( "PCLK1 %s%dHz", cmsg6, HAL_RCC_GetPCLK1Freq()); put_rn(); PRINTF( "PCLK2 %s%dHz", cmsg6, HAL_RCC_GetPCLK2Freq()); put_rn(); put_rn(); // Check RTC Clock PRINTF("RTC Clock"); put_rn(); m1 = (RCC->BDCR >> 8) & 0x03; switch (m1) { case 0: // no clock PRINTF(cmsg7); break; case 1: // LSE PRINTF(cmsg8); break; case 2: // LSI PRINTF("%s 17 to 47, typ.32KHz", cmsg9); break; case 3: // HSE PRINTF( cmsg10 ); m2 = (RCC->PLLCFGR >> 16) & 0x1f; // RTCPRE m3 = HSE_VALUE / m2; PRINTF("%s%dHz", cmsg6, m3); put_rn(); break; default: // Not come here PRINTF(cmsg5); break; } put_rn(); put_rn(); break; case 'c' : // sc - show system CPU information m1 = SCB->CPUID; m2 = ( m1 >> 24 ); if ( m2 == 0x41 ) { PRINTF( "CPU = ARM " ); } else { PRINTF( "CPU = NOT ARM " ); } m2 = ( m1 >> 4 ) & 0xfff; if ( m2 == 0xc24 ) { PRINTF( "Cortex-M4" ); } else { PRINTF( "NOT Cortex-M4" ); } put_rn(); m2 = ( m1 >> 20 ) & 0x0f; PRINTF( "Variant:%x", m2 ); put_rn(); m2 = m1 & 0x7; PRINTF( "Revision:%x", m2 ); put_rn(); PRINTF( "CPU ID: 0x%08x", m1 ); put_rn(); m1 = DBGMCU->IDCODE; PRINTF( "DBG ID: 0x%08x", m1 ); put_rn(); // unique ID // http://waijung.aimagin.com/index.htm?stm32f4_uidread.htm m1 = *(__IO uint32_t *)((uint32_t)0x1FFF7A10); PRINTF("Unique device ID(94bits):(1) 0x%08x ", m1); m1 = *(__IO uint32_t *)((uint32_t)0x1FFF7A14); PRINTF("(2) 0x%08x ", m1); m1 = *(__IO uint32_t *)((uint32_t)0x1FFF7A18); PRINTF( "(3) 0x%08x", m1 ); put_rn(); break; case '?' : default: PRINTF( "sc - System CPU information" ); put_rn(); PRINTF( "sf - System Clock" ); put_rn(); } } #elif defined(TARGET_NUCLEO_L152RE) static __I uint8_t PLLMulTable[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48}; void cpu_inf( char *ptr ) { uint32_t m1, m2, m3, m4, m5; switch (*ptr++) { case 'f' : // sc - show system clock frequency m1 = RCC->CR; PRINTF( "CR = 0x%08x", m1 ); put_rn(); m1 = RCC->ICSCR; PRINTF( "ICSCR = 0x%08x", m1 ); put_rn(); m1 = RCC->CFGR; PRINTF( "CFGR = 0x%08x", m1 ); put_rn(); m1 = RCC->CIR; PRINTF( "CIR = 0x%08x", m1 ); put_rn(); m1 = RCC->AHBRSTR; PRINTF( "AHBRSTR = 0x%08x", m1 ); put_rn(); m1 = RCC->APB2RSTR; PRINTF( "APB2RSTR = 0x%08x", m1 ); put_rn(); m1 = RCC->APB1RSTR; PRINTF( "APB1RSTR = 0x%08x", m1 ); put_rn(); m1 = RCC->AHBENR; PRINTF( "AHBENR = 0x%08x", m1 ); put_rn(); m1 = RCC->APB2ENR; PRINTF( "APB2ENR = 0x%08x", m1 ); put_rn(); m1 = RCC->APB2LPENR; PRINTF( "APB2LPENR= 0x%08x", m1 ); put_rn(); m1 = RCC->APB1LPENR; PRINTF( "APB1LPENR= 0x%08x", m1 ); put_rn(); m1 = RCC->CSR; PRINTF( "CSR = 0x%08x", m1 ); put_rn(); PRINTF( cmsg11 ); put_rn(); m1 = PWR->CR; PRINTF( "CR = 0x%08x", m1 ); put_rn(); m1 = PWR->CSR; PRINTF( "CSR = 0x%08x", m1 ); put_rn(); put_rn(); case 'F' : // sF - show system clock frequency m1 = RCC->CFGR & RCC_CFGR_SWS; /* Get SYSCLK source */ switch (m1) { case 0x00: // MSI used as system clock m4 = ( RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13; m2 = (32768 * (1 << (m4 + 1))); PRINTF( "%s, %s%dHz", cmsg0, cmsg1, m2); break; case 0x04: // HSI used as system clock PRINTF( "%s, %s%dHz", cmsg2, cmsg1,HSI_VALUE ); m2 = HSI_VALUE; break; case 0x08: // HSE used as system clock PRINTF( "%s, %s%dHz", cmsg3, cmsg1, HSE_VALUE ); m2 = HSE_VALUE; break; case 0x0C: // PLL used as system clock // Get PLL clock source and multiplication factor m5 = RCC->CFGR & RCC_CFGR_PLLMUL; m1 = RCC->CFGR & RCC_CFGR_PLLDIV; m5 = PLLMulTable[(m5 >> 18)]; m1 = (m1 >> 22) + 1; PRINTF( "%s Mul=%d, Div=%d", cmsg4, m5, m1 ); put_rn(); m3 = RCC->CFGR & RCC_CFGR_PLLSRC; if ( m3 == 0x00 ) { // HSI oscillator clock selected as PLL clock source m2 = (((HSI_VALUE) * m5) / m1); PRINTF( "%s, RC=%dHz", cmsg2, HSI_VALUE ); } else { // HSE selected m2 = (((HSE_VALUE) * m5) / m1); if ((RCC->CR >> 18) & 0x01) { // check HSEBYP bit // HSE(not Xtal) selected as PLL clock source PRINTF( "Use HSE(not Xtal but External Clock)=%dHz", HSE_VALUE ); } else { // HSE(Xtal) selected as PLL clock source PRINTF( "%s, Xtal=%dHz", cmsg3, HSE_VALUE ); } } put_rn(); PRINTF( "PLL %s%dHz", cmsg1, m2 ); put_rn(); break; default: // Not come here PRINTF( cmsg5 ); break; } put_rn(); PRINTF( "SYSCLK %s%dHz", cmsg6, HAL_RCC_GetSysClockFreq() ); put_rn(); PRINTF( "HCLK %s%dHz", cmsg6, HAL_RCC_GetHCLKFreq() ); put_rn(); PRINTF( "PCLK1 %s%dHz", cmsg6, HAL_RCC_GetPCLK1Freq() ); put_rn(); PRINTF( "PCLK2 %s%dHz", cmsg6, HAL_RCC_GetPCLK2Freq() ); put_rn(); put_rn(); m1 = RCC->CSR & RCC_CSR_RTCSEL; // Check RTC & LCD Clock PRINTF("RTC/LCD Clock"); put_rn(); switch (m1) { case RCC_CSR_RTCSEL_NOCLOCK: PRINTF( cmsg7 ); break; case RCC_CSR_RTCSEL_LSE: PRINTF( cmsg8 ); break; case RCC_CSR_RTCSEL_LSI: PRINTF("%s 26 to 56, typ.38KHz", cmsg9); break; case RCC_CSR_RTCSEL_HSE: PRINTF( cmsg10 ); break; default: // Not come here PRINTF( cmsg5 ); break; } put_rn(); put_rn(); break; case 'c' : // sc - show system CPU information m1 = SCB->CPUID; m2 = ( m1 >> 24 ); if ( m2 == 0x41 ) { PRINTF( "CPU = ARM " ); } else { PRINTF( "CPU = NOT ARM " ); } m2 = ( m1 >> 4 ) & 0xfff; if ( m2 == 0xc23 ) { PRINTF( "Cortex-M3" ); } else { PRINTF( "NOT Cortex-M3" ); } put_rn(); m2 = ( m1 >> 20 ) & 0x0f; PRINTF( "Variant:%x", m2 ); put_rn(); m2 = m1 & 0x7; PRINTF( "Revision:%x", m2 ); put_rn(); PRINTF( "CPU ID: 0x%08x", m1 ); put_rn(); m1 = DBGMCU->IDCODE; PRINTF( "DBG ID: 0x%08x", m1 ); put_rn(); // unique ID // http://false.ekta.is/2013/09/stm32-unique-id-register-not-so-unique/ m1 = *(__IO uint32_t *)((uint32_t)0x1FF80050); PRINTF("Unique device ID(94bits):(1) 0x%08x ", m1); m1 = *(__IO uint32_t *)((uint32_t)0x1FF80054); PRINTF("(2) 0x%08x ", m1); m1 = *(__IO uint32_t *)((uint32_t)0x1FF80058); PRINTF( "(3) 0x%08x", m1 ); put_rn(); break; case '?' : default: PRINTF( "sc - System CPU information" ); put_rn(); PRINTF( "sf - System Clock" ); put_rn(); } } #endif // Select CPU //------------------------------------------------------------------------------------------------- // Monitor Main Program //------------------------------------------------------------------------------------------------- int mon_hw(void) { char *ptr; put_r(); PRINTF("%s [Help:'?' key]", mon_msg); put_rn(); for (;;) { put_r(); PUTC('>'); ptr = linebuf; get_line(ptr, buf_size); put_r(); switch (*ptr++) { //----------------------------------------------------------------------------------------- // Memory //----------------------------------------------------------------------------------------- case 'm' : #if USE_MEM mem_inf(ptr); put_rn(); #else not_select(); #endif // USE_MEM break; //----------------------------------------------------------------------------------------- // Register //----------------------------------------------------------------------------------------- case 'r' : put_r(); PRINTF(mrmsg0); put_rn(); quitflag = 0; for (; quitflag != 0xff;) { PRINTF("r>"); ptr = linebuf; get_line(ptr, buf_size); put_r(); switch(*ptr++) { case 'u' : #if USE_UART switch(*ptr++) { case '1' : PRINTF("%s%s1%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(USART1); break; case '2' : PRINTF("%s%s2%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(USART2); break; #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) case '6' : PRINTF("%s%s6%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(USART6); break; #elif defined(TARGET_NUCLEO_L152RE) case '3' : PRINTF("%s%s3%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(USART3); break; case '5' : PRINTF("%s%s5%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(UART5); break; #endif case '*' : PRINTF( "%s & UART", mrmsg2 ); put_rn(); PRINTF("%s%s1%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(USART1); PRINTF("%s%s2%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(USART2); #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) PRINTF("%s%s6%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(USART6); #elif defined(TARGET_NUCLEO_L152RE) PRINTF("%s%s3%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(USART3); PRINTF("%s%s5%s", mrmsg1,mrmsg2,mrmsg1); usart_reg(UART5); #endif break; case '?' : default: PRINTF( mrmsg3 ); put_rn(); } #else not_select(); #endif // USE_UART break; case 'i' : #if USE_I2C switch(*ptr++) { case '1' : PRINTF("%s%s1%s", mrmsg1,mrmsg4,mrmsg1); i2c_reg( I2C1 ); break; case '2' : PRINTF("%s%s2%s", mrmsg1,mrmsg4,mrmsg1);; i2c_reg( I2C2 ); break; #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) case '3' : PRINTF("%s%s3%s", mrmsg1,mrmsg4,mrmsg1);; i2c_reg( I2C3 ); break; #endif case '*' : PRINTF(mrmsg4); put_rn(); PRINTF("%s%s1%s", mrmsg1,mrmsg4,mrmsg1); i2c_reg( I2C1 ); PRINTF("%s%s2%s", mrmsg1,mrmsg4,mrmsg1); i2c_reg( I2C2 ); #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) PRINTF("%s%s3%s", mrmsg1,mrmsg4,mrmsg1);; i2c_reg( I2C3 ); #endif break; case '?' : default: PRINTF(mrmsg5); put_rn(); } #else not_select(); #endif // USE_I2C break; case 's' : #if USE_SPI switch(*ptr++) { case '1' : PRINTF("%s%s1%s", mrmsg1,mrmsg6,mrmsg1); spi_reg( SPI1 ); break; case '2' : PRINTF("%s%s2%s", mrmsg1,mrmsg6,mrmsg1); spi_reg( SPI2 ); break; case '3' : PRINTF("%s%s3%s", mrmsg1,mrmsg6,mrmsg1); spi_reg( SPI3 ); break; #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) case '4' : PRINTF("%s%s4%s", mrmsg1,mrmsg6,mrmsg1); spi_reg( SPI4 ); break; #endif case '*' : PRINTF(mrmsg6); put_rn(); PRINTF("%s%s1%s", mrmsg1,mrmsg6,mrmsg1); spi_reg( SPI1 ); PRINTF("%s%s2%s", mrmsg1,mrmsg6,mrmsg1); spi_reg( SPI2 ); PRINTF("%s%s3%s", mrmsg1,mrmsg6,mrmsg1); spi_reg( SPI3 ); #if defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) PRINTF("%s%s4%s", mrmsg1,mrmsg6,mrmsg1); spi_reg( SPI4 ); #endif break; case '?' : default: PRINTF(mrmsg7); put_rn(); } #else not_select(); #endif // USE_SPI break; case 't' : // not_yet_impliment(); break; case 'a' : // not_yet_impliment(); break; case 'd' : // not_yet_impliment(); break; case 'w' : // not_yet_impliment(); break; case 'l' : // not_yet_impliment(); break; case 'c' : // not_yet_impliment(); break; case 'x' : // not_yet_impliment(); break; case 'y' : // not_yet_impliment(); break; case '?' : PRINTF("u - USART"); put_rn(); PRINTF("i - I2C"); put_rn(); PRINTF("s - SPI"); put_rn(); PRINTF("t - TIMER"); put_rn(); PRINTF("a - ADC"); put_rn(); PRINTF("d - DAC"); put_rn(); PRINTF("l - LDC"); put_rn(); PRINTF("w - WWDG"); put_rn(); PRINTF("c - COMP"); put_rn(); break; case 'q' : // quit quitflag = 0xff; break; default: PUTC('?'); put_rn(); } } PRINTF(mrmsg8); put_rn(); break; //----------------------------------------------------------------------------------------- // Port //----------------------------------------------------------------------------------------- case 'p' : #if USE_PORT put_r(); PRINTF("Enter port a,b,c,d,e,h & * ? for help"); put_rn(); quitflag = 0; for (; quitflag != 0xff;) { PRINTF("p>"); ptr = linebuf; get_line(ptr, buf_size); put_r(); switch(*ptr) { case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'h' : port_inf_one(ptr); break; case '*' : rpt_port(); break; case '?' : PRINTF("port a,b,c,d,e,h & *"); put_rn(); break; case 'q' : // quit quitflag = 0xff; break; default: PUTC('?'); put_rn(); } } PRINTF(mrmsg8); put_rn(); #else not_select(); #endif // USE_PORT break; //----------------------------------------------------------------------------------------- // System //----------------------------------------------------------------------------------------- case 's' : // System related information #if USE_SYS cpu_inf(ptr); #else not_select(); #endif // USE_SYS break; //----------------------------------------------------------------------------------------- // Help //----------------------------------------------------------------------------------------- case '?' : hw_msg_hlp(); break; //----------------------------------------------------------------------------------------- // Return to main routine //----------------------------------------------------------------------------------------- case 'q' : // Quit put_r(); PRINTF("Return to monitor"); put_rn(); return 0; //----------------------------------------------------------------------------------------- // Special command for DEBUG //----------------------------------------------------------------------------------------- case 'x' : not_yet_impliment(); break; //----------------------------------------------------------------------------------------- // no support //----------------------------------------------------------------------------------------- default: PUTC('?'); put_rn(); break; } } } #endif // defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_L152RE)