Skip to content

Add Mode 5: Physical reset, for UARTS with only RTS, no DTR.#28

Draft
SmittyHalibut wants to merge 3 commits intomsalau:masterfrom
Jeak:master
Draft

Add Mode 5: Physical reset, for UARTS with only RTS, no DTR.#28
SmittyHalibut wants to merge 3 commits intomsalau:masterfrom
Jeak:master

Conversation

@SmittyHalibut
Copy link
Copy Markdown

This is a draft pull request so I can comment on the sum of two commits.

Jeak added 2 commits March 31, 2024 21:20
confirmed operation works with reading CTS (mode 5)
Comment thread src/main.c Outdated
"\t\t\tn=2 Two-wire UART, Reset by DTR\n"
"\t\t\tn=3 Single-wire UART, Reset by RTS\n"
"\t\t\tn=4 Two-wire UART, Reset by RTS\n"
"\t\t\tn=5 Single-wire UART, Hardware Reset, reset state read by CTS (modified mode 1/3)\n"
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's all "hardware reset." I'd say "Manual reset button" instead.

Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will probably want to update this after seeing below about mode being a bitmap. n=5 is as you describe, but n=6 will be Two-wire UART, Manual Reset. (You get it for free when mode is a bitmap.)

Comment thread src/main.c Outdated
Comment on lines +128 to +135
// For debug
//printf("Communication mode passed to rl78 funcs: %i\r\n", mode);
//printf("Mode value expression: %i\r\n",mode_val_expr);
return EINVAL;
}
// For debug
//printf("Communication mode passed to rl78 funcs: %i\r\n", mode);
//printf("Mode value expression: %i\r\n",mode_val_expr);
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally, you'd remove your temporary debugging code from the commit before issuing a PR. Or, wrap it in if (verbose_level > whatever) block.

Comment thread src/main.c Outdated
Comment on lines +233 to +235
if (mode == 4)
{
mode = 4;
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is only ever run if mode == 4 so assigning it to 4 is unnecessary.

Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, treating mode as a bitmap (see below), you might as well still allow this, and use it when detecting CTS.

That is, just remove this change and go back to the original code. It's ok if MODE_INVERT_RESET bit is set.

Comment thread src/rl78.c Outdated
{
if (mode == 4) // operating in mode 5
{
printf("No GPIO SW reset available, must use switch\r\n");
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pedantic Pet Peeve of mine: feel free to ignore. ;-)

Switches are latching and/or sliding/rotating, buttons are momentary and/or linear motion. This is a button, not a switch.

Yes, yes, this depends on how you implement the hardware. But I've never seen a Reset Switch, only ever Reset Buttons. Possibly a Reset Momentary Switch on front-panels of old mini-computers. But these are almost certainly going to be buttons.

Comment thread src/rl78.c Outdated
{
printf("No GPIO SW reset available, must use switch\r\n");
}
else {
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub won't let me select the whole block here.

But fix the indentation below.

Comment thread src/rl78.c Outdated
{
serial_set_dtr(fd, level);
}
}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is broken down to here.

Comment thread src/rl78.c Outdated
unsigned char r;
//(mode = desired communication mode from terminal input - 1)

// Determine UART mode from mode argument
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation (just the one line)

Comment thread src/rl78.c
r = SET_MODE_1WIRE_UART;
communication_mode = 1;
}

Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove blank line.

Comment thread src/rl78.c Outdated
Comment on lines 72 to 85
if (4 <= verbose_level)
{
if (mode == 4) // Special case for mode 5
{
communication_mode = 5;
printf("Using communication mode 5 (HW RESET with CTS reading RESET)\n");
}
else
{
printf("Using communication mode %u%s\n",
(mode & (MODE_UART | MODE_RESET)) + 1,
(mode & MODE_INVERT_RESET) ? " with RESET inversion" : "");
}
}
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why the behavior changes when you change your verbosity level. communication_mode = 5 shouldn't be inside if (4 <= verbose_level)

Or rather, you shouldn't be setting communication_mode at all, which is why it broke when you increased the verbosity. :-)

Comment thread src/rl78.c
Comment on lines +93 to +117
int reset = serial_get_cts(fd);
if (reset == 1)
{
while (1) // while CTS/RESET is high, wait
{
reset = serial_get_cts(fd);
if (reset == 0)
{
printf("Got reset press. Hang on...\n");
usleep(100000);
printf("Let go of RESET.\n");
break;
}
}
}

while (1) // while CTS/RESET is low, wait
{
reset = serial_get_cts(fd);
if (reset == 1)
{
printf("Got reset release. Attempting to set communication mode...\n");
break;
}
}
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is overly complex to read.

Also, lets allow for inverted reset here. Add:

bool active = (mode & MODE_INVERT_RESET) ? 0 : 1;

Test my active logic here. I might have it backwards.

Replace the first block with just:

while (serial_get_cts(fd) == active)
{
    usleep(1000);
}

Then move the printf(); usleep(); printf() block outside the while loop.

Replace the second block with:

while (serial_get_cts(fd) != active)
{
    usleep(1000);
}

Then move the printf() outside the while loop.

The usleep(1000) just keeps it from completely locking up a CPU while waiting.

Comment thread src/rl78.c Outdated
}
serial_write(fd, &r, 1);
if (1 == communication_mode)
if ((1 == communication_mode) | (5 == communication_mode))
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

communication_mode is just whether it's a 1-wire or 2-wire. Since mode 5 is a 1-wire, just test for 1 here. This is part of the treating mode as a bit-map change.

Read: Undo this change. Only test for (1 == communication_mode) as originally done.

Comment thread src/rl78.c
Comment on lines 157 to 163
int rl78_reset(port_handle_t fd, int mode)
{
serial_set_txd(fd, 1); /* TOOL0 -> 1 */
rl78_set_reset(fd, mode, 0); /* RESET -> 0 */
usleep(10000);
rl78_set_reset(fd, mode, 1); /* RESET -> 1 */
serial_set_txd(fd, 1); /* TOOL0 -> 1 */
rl78_set_reset(fd, mode, 0); /* RESET -> 0 */
usleep(10000);
rl78_set_reset(fd, mode, 1); /* RESET -> 1 */
return 0;
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too much indentation. Fix this.

Comment thread src/rl78.c Outdated
serial_flush(fd);

}
else if ((mode == 0) | (mode == 1) | (mode == 2))
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if (MODE_RESET_INPUT_FALSE == (mode & MODE_RESET_INPUT))

Actually, this is just else.

Comment thread src/main.c Outdated
if (1 <= verbose_level)
{
printf("Reset MCU\n");
if (mode == 4) // operating in mode 5
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When used to determine whether reset is controlled by the code, or triggered by the user, change if (mode == 4) to if (MODE_RESET_INPUT_TRUE == (mode & MODE_RESET_INPUT))

This happens in multiple places. I'll just say MODE_RESET_INPUT in future comments to mean the same thing.

Comment thread src/main.c Outdated
printf("Resetting MCU...\n");
}
}
if (mode != 4) // Case for HW reset switch
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MODE_RESET_INPUT

Comment thread src/rl78.c Outdated
static void rl78_set_reset(port_handle_t fd, int mode, int value)
// Set reset signal for MCU based on mode (not applicable for mode 5 with hardware switch)
{
if (mode == 4) // operating in mode 5
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MODE_RESET_INPUT

Comment thread src/rl78.c Outdated
else
{
printf("Using communication mode %u%s\n",
(mode & (MODE_UART | MODE_RESET)) + 1,
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(mode & (MODE_UART | MODE_RESET | MODE_RESET_INPUT)) + 1

Comment thread src/rl78.c
else {
int level = (mode & MODE_INVERT_RESET) ? !value : value;

if (MODE_RESET_RTS == (mode & MODE_RESET))
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be messing with RTS or DTR if we are inputing the reset signal.

if ((MODE_RESET_RTS == (mode & MODE_RESET)) && (MODE_RESET_INPUT_FALSE == (mode && MOST_RESET_INPUT)))

Comment thread src/rl78.c Outdated
Comment on lines +74 to +78
if (mode == 4) // Special case for mode 5
{
communication_mode = 5;
printf("Using communication mode 5 (HW RESET with CTS reading RESET)\n");
}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't change communication_mode here. I think we want this to stay either 1 or 2. You can still output the verbose message, but trigger that based on (mode & MODE_RESET_INPUT == MODE_RESET_INPUT_TRUE instead of mode == 4.

Comment thread src/rl78.c Outdated
serial_set_txd(fd, 0); /* TOOL0 -> 0 */
if (wait)
// Begin reset procedure
if (mode == 4) // sequencing for mode 5
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (MODE_RESET_INPUT_TRUE == (mode & MODE_RESET_INPUT))

(ngl, I don't understand putting the constant before the == thing. But maintaining code style is more important than using MY code style.)

Comment thread src/rl78.c Outdated
int ret = serial_write(fd, buf, sizeof buf);
// Read back echo
if (1 == communication_mode)
if ((1 == communication_mode) | (5 == communication_mode))
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. Only test for 1 ==

Comment thread src/rl78.h
Comment on lines +73 to 84
// Communication modes passed to RL78 funcs
// Mode 1: MODE
#define MODE_UART 1
#define MODE_UART_1 0
#define MODE_UART_2 MODE_UART
#define MODE_RESET 2
#define MODE_RESET_DTR 0
#define MODE_RESET_RTS MODE_RESET
#define MODE_MAX_VALUE (MODE_UART | MODE_RESET)
#define MODE_MAX_VALUE 4
//#define MODE_MAX_VALUE (MODE_UART | MODE_RESET)
#define MODE_MIN_VALUE 0
#define MODE_INVERT_RESET 0x80
Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok this is the big "mode as a bit-map" thing I've been talking about above.

Bit 1 of mode is whether it's a 1-wire or 2-wire serial protocol.
Bit 2 of mode is whether RESET is on DTR or RTS.

We should make Bit 4 of mode be whether RESET is an INPUT or not. All my comments above are to change the code for this.

Here, we need these #defines to be:

...
#define MODE_RESET_RTS   MODE_RESET
#define MODE_RESET_INPUT   4
#define MODE_RESET_INPUT_FALSE 0
#define MODE_RESET_INPUT_TRUE  MODE_RESET_INPUT
#define MODE_MAX_VALUE  (MODE_UART | MODE_RESET | MODE_RESET_INPUT)
...

Copy link
Copy Markdown
Author

@SmittyHalibut SmittyHalibut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whew! Ok.

There are a few style and formatting comments buried in here, don't lose those.

But the biggest change I'm requesting is that we continue to treat mode as a bit-map, instead of just a sequentially assigned arbitrary mode number. Modes 1 through 4 are actually a bit map of features, one of which matters to us. So I propose we keep with that bit map, and add another bit that is "Is Reset an input or not?" When we continue to use bit 1 to determine whether it's a 1-wire or 2-wire protocol, and bit 2 to determine which output pin to use for reset (which doesn't matter in our case).

OR! Possibly use that bit to select between CTR and DSR for the input pins. shrug or don't bother with that, and just stick to CTR.

In any case, most of my actual code changes in this review are to implement this change.

- Replaced references to mode numerically with references to bitmap
- Style fixes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants