newaetech / naeusb

USB library for ChipWhisperer devices
Apache License 2.0
14 stars 3 forks source link

Setting nrst via naeusb in firmware does not work #11

Open nikitalita opened 5 months ago

nikitalita commented 5 months ago

I am currently attempting to get the N76E003 (and other NuMicro 8051 chips) ICP programmer into the CW firmware. Part of the ICP programming algorithm is that you have to send a certain sequence on the reset line with specific timing in order to get it into ICP mode. So in order to do that, I have to be able to toggle the nRST line in firmware.

However, in my testing with the ChipWhisperer Lite, I am not able to get the naeusb firmware to toggle reset on or off at all.

Here's the output of my logic analyzer with a test function with just me toggling the NRST, PDID, and PDIC pins on and off at 100ms intervals: image

I am configuring the NRST pin the same way that all the other things in naeusb do:

    gpio_configure_pin(PIN_TARG_NRST_GPIO, (PIO_TYPE_PIO_OUTPUT_1 | PIO_DEFAULT));

I have tried a number of things; using different target boards, setting the scope up with default setup, not setting it up with the default setup, setting nrst to high, low, etc. beforehand, none of it seems to work. I am out of ideas as to things I can try at this point.

To reproduce, stick this in naeusb_usart.c:

#define REQ_TEST_THING 96
#include "gpio.h"
#include "delay.h"
bool test(){
    gpio_configure_pin(PIN_TARG_NRST_GPIO, (PIO_TYPE_PIO_OUTPUT_1 | PIO_DEFAULT));
    gpio_configure_pin(PIN_PDIDTX_GPIO, PIN_PDIDTX_OUT_FLAGS);
    gpio_configure_pin(PIN_PDIDRX_GPIO, PIN_PDIDRX_FLAGS);
    gpio_configure_pin(PIN_PDIC_GPIO, PIN_PDIC_OUT_FLAGS);
    for (int i = 0; i < 10; i++){
        gpio_set_pin_low(PIN_TARG_NRST_GPIO);
        gpio_set_pin_low(PIN_PDIDTX_GPIO);
        gpio_set_pin_low(PIN_PDIC_GPIO);
        delay_ms(100);
        gpio_set_pin_high(PIN_TARG_NRST_GPIO);
        gpio_set_pin_high(PIN_PDIDTX_GPIO);
        gpio_set_pin_high(PIN_PDIC_GPIO);
        delay_ms(100);
    }
    return false;
}

void test_void(){
    test();
}
bool usart_setup_out_received(void)
{

    switch(udd_g_ctrlreq.req.bRequest) {
    case REQ_TEST_THING:
        udd_g_ctrlreq.callback = test_void;
        return true;
        break;
    [...]

then run this in python:

    REQ_TEST_THING = 0x96
    scope = cw.scope()
    scope.default_setup()
    scope.io.nrst = None
    scope_logger.setLevel(logging.DEBUG)
    usb = scope._getNAEUSB()
    # p.open()
    for i in range(10):
        scope.sc.serial.sendCtrl(REQ_TEST_THING, REQ_TEST_THING, bytearray())

My setup is a chipwhisperer lite connected directly to a UFO board with any target board.

nikitalita commented 5 months ago

I have also confirmed that it isn’t something with my particular scope by setting scope.io.nrst via the python api on the host machine, and that does work; setting it to high, low, and high_z produces the expected output.

jpcrypt commented 5 months ago

What does scope.io.cwe.oa.sendMessage(0x80, "CW_IOROUTE_ADDR", Validate=False, maxResp=8)[5] return?

nikitalita commented 5 months ago

0

nikitalita commented 5 months ago

(before and after running that test function)

jpcrypt commented 5 months ago

In order for the SAM3U's TARGET_NRST pin (PA17) to be passed on to the target nRST pin, the CW-lite FPGA must be placed in "AVR programming mode" by calling scope.io.cwe.setAVRISPMode(True).

This will also affect how the MOSI and SCK pins are driven-- MOSI will get driven from SAM_MOSI (PA14), SCK will get driven from SAM_SCK (PA15).

nikitalita commented 5 months ago

Yup, that fixed it, thanks. This should probably be documented somewhere, I was banging my head against the wall for a few hours there.

jpcrypt commented 5 months ago

I hear your pain... there is no documentation at all for the capture hardware's firmware, since we don't expect most users to touch it, and so it hasn't been a priority. Be aware that all the target connections go through the FPGA, and if you ever run into a situation like this, don't hesitate to ping us for help!