semihost server example program

Dependencies:   SWD mbed USBLocalFileSystem BaseDAP USBDAP

/media/uploads/va009039/kl46z-lpc800-360x480.jpg

LPCXpresso
LPC11U68
LPCXpresso
LPC1549
FRDM-KL46ZEA LPC4088 QSB
app-board
LPC1768
app-board
LPC810LPC1114FN28
serverserverserverserverserverclientclient
SWDIOD12D12D12p25p21p4(P0_2)p12
SWCLKD10D10D10p26p22p3(P0_3)p3
nRESET
*option
D6D6D6p34p30p1(P0_5)p23
GNDGNDGNDGNDp1p1p7p22
3.3VP3V3P3V3P3V3p44p40p6p21
flash writeSW2(P0_1)SW3(P1_9)SW1p14
joystick
center
p14
joystick
center

client example:

Import programlpc810-semihost_helloworld

semihost client example program

Target2.cpp

Committer:
va009039
Date:
2013-09-05
Revision:
2:32e9437348ad
Parent:
1:eb30547ba84d
Child:
3:d7a7cde0bfb8

File content as of revision 2:32e9437348ad:

// Target2.cpp 2013/9/5
#include "Target2.h"
#include "mydebug.h"

#define CoreDebug_BASE      (0xE000EDF0UL)
#define DHCSR (CoreDebug_BASE+0)
#define DCRSR (CoreDebug_BASE+4) 
#define DCRDR (CoreDebug_BASE+8)
#define DEMCR (CoreDebug_BASE+12)

#define NVIC_AIRCR 0xE000ED0C

Target2::Target2(PinName swdio, PinName swclk, PinName reset, Serial* usbpc)
    : _swd(swdio, swclk, reset), _pc(usbpc)
{
    r0.setup(this, 0);
    r1.setup(this, 1);
    r2.setup(this, 2);
    r3.setup(this, 3);
    r4.setup(this, 4);
    r5.setup(this, 5);
    r6.setup(this, 6);
    r7.setup(this, 7);
    r8.setup(this, 8);
    r9.setup(this, 9);
    r10.setup(this, 10);
    r11.setup(this, 11);
    r12.setup(this, 12);
    sp.setup(this, 13);
    lr.setup(this, 14);
    pc.setup(this, 15);
    xpsr.setup(this, 16);
}

bool Target2::setup()
{
    _swd.Setup();
    _swd.JTAG2SWD();
    
    uint32_t data;
    uint8_t ack = _swd.Transfer(DP_IDCODE, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }
    TEST_ASSERT(data == 0x0bb11477);

    Abort();

    data = 0x0;
    ack = _swd.Transfer(DP_SELECT, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }

    ack = _swd.Transfer(DP_RDBUFF, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }

    data = CSYSPWRUPREQ | CDBGPWRUPREQ;
    TEST_ASSERT(data == 0x50000000);
    ack = _swd.Transfer(DP_CTRL_STAT, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }

    ack = _swd.Transfer(DP_RDBUFF, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }

    ack = _swd.Transfer(DP_CTRL_STAT_R, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }
    TEST_ASSERT(data == 0xf0000040);

    data = CSYSPWRUPREQ | CDBGPWRUPREQ | 0x04000000;
    TEST_ASSERT(data == 0x54000000);
    ack = _swd.Transfer(DP_CTRL_STAT, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }

    ack = _swd.Transfer(DP_RDBUFF, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }

    data = CSYSPWRUPREQ | CDBGPWRUPREQ | MASKLANE;
    TEST_ASSERT(data == 0x50000f00);
    ack = _swd.Transfer(DP_CTRL_STAT, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }

    ack = _swd.Transfer(DP_RDBUFF, &data);
    TEST_ASSERT(ack == SWD_OK);
    if (ack != SWD_OK) {
        return false;
    }
    return true;
}

void Target2::Reset()
{
    _swd.reset();
}

uint32_t Target2::readMemory(uint32_t addr)
{
    _setaddr(addr);

    uint32_t data;
    uint8_t ack = _swd.Transfer(AP_DRW_R, &data); // dummy read
    TEST_ASSERT(ack == SWD_OK);

    ack = _swd.Transfer(DP_RDBUFF, &data);
    TEST_ASSERT(ack == SWD_OK);
    return data;
}

void Target2::readMemory(uint32_t addr, uint32_t* data, int count)
{
    if (count == 0) {
        return;
    }

    _setaddr(addr);
    
    uint8_t ack = _swd.Transfer(AP_DRW_R, NULL); // dummy read
    TEST_ASSERT(ack == SWD_OK);

    for(int i = 0; i < count-1; i++) {
        ack = _swd.Transfer(AP_DRW_R, data++);
        TEST_ASSERT(ack == SWD_OK);
    }
    ack = _swd.Transfer(DP_RDBUFF, data);
    TEST_ASSERT(ack == SWD_OK);
}

void Target2::writeMemory(uint32_t addr, uint32_t data)
{
    writeMemory(addr, &data, 1);
}

void Target2::writeMemory(uint32_t addr, uint32_t* data, int count)
{
    _setaddr(addr);

    while(count-- > 0) {
        uint8_t ack = _swd.Transfer(AP_DRW_W, data);
        TEST_ASSERT(ack == SWD_OK);
        data++;
    }
}

uint8_t Target2::readMemory8(uint32_t addr)
{
    _setaddr8(addr);

    uint32_t data32;
    uint8_t ack = _swd.Transfer(AP_DRW_R, &data32); // dummy read
    TEST_ASSERT(ack == SWD_OK);

    ack = _swd.Transfer(DP_RDBUFF, &data32);
    TEST_ASSERT(ack == SWD_OK);
    return (data32 >> ((addr & 0x03) << 3)) & 0xff;
}

void Target2::writeMemory8(uint32_t addr, uint8_t data)
{
    _setaddr8(addr);

    uint32_t data32 = data;
    data32 <<= ((addr & 0x03) << 3);
    uint8_t ack = _swd.Transfer(AP_DRW_W, &data32);
    TEST_ASSERT(ack == SWD_OK);
}

void Target2::_setaddr(uint32_t addr)
{
    uint32_t ctl = CSW_VALUE|CSW_SIZE32;
    TEST_ASSERT(ctl == 0x23000052);
    uint8_t ack = _swd.Transfer(AP_CSW, &ctl);
    TEST_ASSERT(ack == SWD_OK);

    ack = _swd.Transfer(DP_RDBUFF, NULL);
    TEST_ASSERT(ack == SWD_OK);

    ack = _swd.Transfer(AP_TAR, &addr);
    TEST_ASSERT(ack == SWD_OK);

    ack = _swd.Transfer(DP_RDBUFF, NULL);
    TEST_ASSERT(ack == SWD_OK);
} 

void Target2::_setaddr8(uint32_t addr)
{
    uint32_t ctl = CSW_VALUE|CSW_SIZE8;
    TEST_ASSERT(ctl == 0x23000050);
    uint8_t ack = _swd.Transfer(AP_CSW, &ctl);
    TEST_ASSERT(ack == SWD_OK);

    ack = _swd.Transfer(DP_RDBUFF, NULL);
    TEST_ASSERT(ack == SWD_OK);

    ack = _swd.Transfer(AP_TAR, &addr);
    TEST_ASSERT(ack == SWD_OK);

    ack = _swd.Transfer(DP_RDBUFF, NULL);
    TEST_ASSERT(ack == SWD_OK);
} 

void Target2::Abort()
{
    uint32_t data = 0x1e;
    uint8_t ack = _swd.Transfer(DP_ABORT, &data);
    TEST_ASSERT(ack == SWD_OK);
}

int Target2::getStatus()
{
    return readMemory(DHCSR) & 6 ? TARGET_HALTED : TARGET_RUNNING;
}

bool Target2::wait_status(int status, int timeout_ms)
{
    Timer t;
    t.reset();
    t.start();
    while(t.read_ms() < timeout_ms) {
        if (getStatus() == status) {
            return true;
        }
    }
    return false;
}

void Target2::halt()
{
    writeMemory(DHCSR, 0xa05f0003);     
}

void Target2::resume()
{
    writeMemory(DHCSR, 0xa05f0001);     
}

void Target2::step()
{
    writeMemory(DHCSR, 0xa05f0005);     
}

uint32_t CoreReg::read()
{
    _target->writeMemory(DCRSR, _reg);
    return _target->readMemory(DCRDR);
}

void CoreReg::write(uint32_t value)
{
    _target->writeMemory(DCRDR, value);
    _target->writeMemory(DCRSR, _reg|0x10000);
}

void CoreReg::setup(Target2* target, uint8_t reg)
{
    _target = target;
    _reg = reg;    
}