NXP LPC1850 評価ボード用に作成したソフトウェアをデバッグしようとしています。現時点では、コードを停止すると、C コードのどこにあるのかわかりませんが、逆アセンブラー ウィンドウには表示されます。
ハングしている行はアドレス 0x40 にあります。命令は BN です。ARM インフォメーション センターで調べましたが、アセンブラについては何も知りません。
0x0: 0x9ff0 LDR R7, [SP, #0x3c0]
0x2: 0x1008 ASRS R0, R1, #32
0x4: 0x2bad CMP R3, #173 ; 0xad
0x6: 0x1040 ASRS R0, R0, #1
0x8: 0x0041 LSLS R1, R0, #1
0xa: 0x1040 ASRS R0, R0, #1
0xc: 0x0043 LSLS R3, R0, #1
0xe: 0x1040 ASRS R0, R0, #1
0x10: 0x0045 LSLS R5, R0, #1
0x12: 0x1040 ASRS R0, R0, #1
0x14: 0x0047 LSLS R7, R0, #1
0x16: 0x1040 ASRS R0, R0, #1
0x18: 0x0049 LSLS R1, R1, #1
0x1a: 0x1040 ASRS R0, R0, #1
0x1c: 0x0000 MOVS R0, R0
0x1e: 0x0000 MOVS R0, R0
0x20: 0x0000 MOVS R0, R0
0x22: 0x0000 MOVS R0, R0
0x24: 0x0000 MOVS R0, R0
0x26: 0x0000 MOVS R0, R0
0x28: 0x0000 MOVS R0, R0
0x2a: 0x0000 MOVS R0, R0
0x2c: 0x004b LSLS R3, R1, #1
0x2e: 0x1040 ASRS R0, R0, #1
0x30: 0x004d LSLS R5, R1, #1
0x32: 0x1040 ASRS R0, R0, #1
0x34: 0x0000 MOVS R0, R0
0x36: 0x0000 MOVS R0, R0
0x38: 0x004f LSLS R7, R1, #1
0x3a: 0x1040 ASRS R0, R0, #1
0x3c: 0x1645 ASRS R5, R0, #25
0x3e: 0x1040 ASRS R0, R0, #1
0x40: 0xe7fe B.N 0x40
0x42: 0xe7fe B.N 0x42
0x44: 0xe7fe B.N 0x44
0x46: 0xe7fe B.N 0x46
0x48: 0xe7fe B.N 0x48
0x4a: 0xe7fe B.N 0x4a
0x4c: 0xe7fe B.N 0x4c
0x4e: 0xe7fe B.N 0x4e
0x50: 0x0000 MOVS R0, R0
0x52: 0x0000 MOVS R0, R0
0x54: 0x0000 MOVS R0, R0
0x56: 0x0000 MOVS R0, R0
0x58: 0x0000 MOVS R0, R0
0x5a: 0x0000 MOVS R0, R0
0x5c: 0x0000 MOVS R0, R0
0x5e: 0x0000 MOVS R0, R0
誰かが何が起こっているのか、そしておそらくその時点でプログラムがハングしている理由を説明できれば、私は非常に感謝しています.
編集:以下にCコードを追加
#include "NXP\iolpc4350.h"
#include "stdint.h"
#include "modules\i2c_drv.h"
#include "modules\drv_nvic.h"
#define IRC_FREQ 12000000
#define XTAL_FREQ 12000000
//nt32_t ClockFrequency;
uint32_t I2C0_PCLK;
unsigned char Data[2];
#define MULTF 15
#define PCA9502_ADDR 0x4D
volatile uint8_t flag0=0;
#define flTick ( flag0 )
#define flTickSet() ( flag0 = 0xFF )
#define flTickClear() ( flag0 = 0x00 )
/*************************************************************************
* Function Name: InitClock
* Parameters: none
*
* Return: none
*
* Description: Initialize PLL and clock dividers. FCCO = 320MHz,
* PLL1_OUT = 160MHz
*
*************************************************************************/
void InitClock(void)
{
/* 1. Init XTAL OSC */
CGU_XTAL_OSC_CTRL_bit.HF = 0; /* Xtal.freq is between 1MHz and 15MHZ */
CGU_XTAL_OSC_CTRL_bit.BYPASS = 0; /* Xtal.osc is connected */
CGU_XTAL_OSC_CTRL_bit.ENABLE = 0; /* Xtal.osc is enabled */
/* 2. Wait for OSC ready > 2ms */
for(volatile uint32_t j = 20000; j; j--);
/* 3. Switch to OSC clk */
/* BASE_M4_CLK */
CGU_BASE_M4_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (6ul << 24) /* Source is XTAL osc. */
;
/* BASE_APB1_CLK */
CGU_BASE_APB1_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (6ul << 24) /* Source is XTAL osc. */
;
/* BASE_APB3_CLK */
CGU_BASE_APB3_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (6ul << 24) /* Source is XTAL osc. */
;
/* BASE_SPIFI_CLK */
CGU_BASE_SPIFI_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (6ul << 24) /* Source is XTAL osc. */
;
/* 4. Init PLL1 - In clk - OSC (12MHz)
N = 3, M = 80, P = 1 VCO - 320MHz, PLL1 OUT - 160MHz */
CGU_PLL1_CTRL_bit.PD = 1; /* Power down PLL1 */
CGU_PLL1_CTRL_bit.BYPASS = 0; /* CCO clock sent to post-dividers */
CGU_PLL1_CTRL_bit.DIRECT = 0; /* Direct CCO output disabled */
CGU_PLL1_CTRL_bit.FBSEL = 0; /* CCO output as feedback divider */
CGU_PLL1_CTRL_bit.PSEL = 1-1; /* Post divider P = 1 */
CGU_PLL1_CTRL_bit.NSEL = 3-1; /* N = 3 */
CGU_PLL1_CTRL_bit.MSEL = 80-1; /* M = 80 */
CGU_PLL1_CTRL_bit.CLK_SEL = 6; /* Source is XTAL osc. */
CGU_PLL1_CTRL_bit.AUTOBLOCK = 1; /* Autoblock during freq.change enabled */
/* 5. Enable PLL1 */
CGU_PLL1_CTRL_bit.PD = 0; /* Power up (enable) PLL1 */
/* 5. Wait for the PLL1 to achieve lock */
while(!CGU_PLL1_STAT_bit.LOCK);
/* 6. Dividers */
/* IDIVA - /4 input 160MHz, output 40MHz */
CGU_IDIVA_CTRL_bit.AUTOBLOCK = 1; /* Autoblock during freq.change enabled */
CGU_IDIVA_CTRL_bit.IDIV = 4-1; /* IDIV = 4 */
CGU_IDIVA_CTRL_bit.CLK_SEL = 9; /* Source is PLL1 */
CGU_IDIVA_CTRL_bit.PD = 0; /* Enable IDIVA */
/* 7. Init Clock output stages */
/* BASE_M4_CLK, APB0, APB2 - 160MHz */
CGU_BASE_M4_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (9ul << 24) /* Source is PLL1 */
;
/* BASE_APB1_CLK - 160MHz*/
CGU_BASE_APB1_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (9ul << 24) /* Source is PLL1 */
;
/* BASE_SPIFI_CLK - 40MHz */
CGU_BASE_SPIFI_CLK = (1ul << 11) /* Autoblock during freq.change enabled */
| (12ul << 24) /* Source is IDIVA */
;
/* Enable M4 Bus clock */
CCU1_CLK_M4_BUS_CFG_bit.RUN = 1;
/* Enable APB 1 Bus clock */
CCU1_CLK_APB1_BUS_CFG_bit.RUN = 1;
/* Enable SCU clock */
CCU1_CLK_M4_SCU_CFG_bit.RUN = 1;
/* Set I2C0 module frequency = APB1 freq */
I2C0_PCLK = 160000000;
}
/*************************************************************************
* Function Name: RIT_IRQHandler
* Parameters: none
*
* Return: none
*
* Description: Repetitive interrupt timer handler
*
*************************************************************************/
void RITIMER_IRQHandler(void)
{
flTickSet();
/* Clear interrupt */
RIT_CTRL_bit.RITINT = 1;
NVIC_ClearPendingIRQ(NVIC_RITIMER);
}
/*************************************************************************
* Function Name: RIT_Init
* Parameters: none
*
* Return: none
*
* Description: Initialization of repetitive interrupt timer
*
*************************************************************************/
void RITIMER_Init(void)
{
/* Value for 0.25s timer interrupt @ 180MHz timer clock */
RIT_COUNTER = 0;
RIT_COMPVAL = 0x2AEA540;
RIT_CTRL_bit.RITEN = 1;
RIT_CTRL_bit.RITENCLR = 1;
/* Enable interrupt */
NVIC_EnableIRQ(NVIC_RITIMER);
NVIC_SetPriority(NVIC_RITIMER, 16);
}
/*************************************************************************
* Function Name: main
* Parameters: none
*
* Return: none
*
* Description: main
*
*************************************************************************/
int main()
{
// Configures Clock Generation Unit
InitClock();
// Force a RESET to Cortex-M0
RGU_RESET_CTRL1 = ~RGU_RESET_ACTIVE_STATUS1 | RGU_RESET_CTRL1_M0APP_RST;
// Configures Repetitve Interrupt Timer
RITIMER_Init();
// Configure the onboard LED - GPIO4.1
GPIO_CLR4 = 1 << 1;
GPIO_DIR4 |= 1 << 1;
// Init I2C
I2C_InitMaster(400000);
// Everything below this line I have added in myself - Mitchell
/* Configure PC_11 and PC_12 to serve as
GPIO6[10] and GPIO6[11] to act as data select
for SPP0_SSEL multiplexer
1. Set as outputs
2. Choose INTLCD_SSEL (option 0) as output by clearing both outputs
3. Configure both pins as GPIO
*/
// 1
GPIO_DIR6 |= 0x0C;
// 2
GPIO_PIN6 &= ~0x0C;;
// 3
SCU_SFSPC_11_bit.MODE = 4;
SCU_SFSPC_12_bit.MODE = 4;
// Set LCD_RST to reset the LCD
RGU_RESET_CTRL0 |= RGU_RESET_CTRL0_LCD_RST;
// LCD_RST autoclears when complete
// wait until this done before moving on
while(RGU_RESET_STATUS1_bit.LCD_RST == 1);
/* SPI slave select is an active low signal.
This means that to communicate with the onboard LCD,
SSP0_SSEL must be cleared
*/
while(1)
{
}
}