Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

SmittyHalibut
Copy link

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

confirmed operation works with reading CTS (mode 5)
src/main.c Outdated
@@ -53,6 +53,7 @@ const char *usage =
"\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
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
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.)

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
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.

src/main.c Outdated
Comment on lines 233 to 235
if (mode == 4)
{
mode = 4;
Copy link
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
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.

src/rl78.c Outdated
{
if (mode == 4) // operating in mode 5
{
printf("No GPIO SW reset available, must use switch\r\n");
Copy link
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.

src/rl78.c Outdated
{
printf("No GPIO SW reset available, must use switch\r\n");
}
else {
Copy link
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.

src/rl78.c Outdated
@@ -40,48 +48,105 @@ static void rl78_set_reset(port_handle_t fd, int mode, int value)
{
serial_set_dtr(fd, level);
}
}
Copy link
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.

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

// Determine UART mode from mode argument
Copy link
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)

if (MODE_UART_1 == (mode & MODE_UART))
{
r = SET_MODE_1WIRE_UART;
communication_mode = 1;
}

Copy link
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.

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
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 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
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.

src/rl78.c Outdated
if (3 <= verbose_level)
{
printf("Send 1-byte data for setting mode\n");
}
serial_write(fd, &r, 1);
if (1 == communication_mode)
if ((1 == communication_mode) | (5 == communication_mode))
Copy link
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 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
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.

src/rl78.c Outdated
serial_flush(fd);

}
else if ((mode == 0) | (mode == 1) | (mode == 2))
Copy link
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.

src/main.c Outdated
@@ -473,9 +490,18 @@ int main(int argc, char *argv[])
{
if (1 <= verbose_level)
{
printf("Reset MCU\n");
if (mode == 4) // operating in mode 5
Copy link
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.

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

Choose a reason for hiding this comment

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

MODE_RESET_INPUT

src/rl78.c Outdated
{
if (mode == 4) // operating in mode 5
Copy link
Author

Choose a reason for hiding this comment

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

MODE_RESET_INPUT

src/rl78.c Outdated
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,
Copy link
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

src/rl78.c Outdated
{
printf("No GPIO SW reset available, must use switch\r\n");
}
else {
int level = (mode & MODE_INVERT_RESET) ? !value : value;

if (MODE_RESET_RTS == (mode & MODE_RESET))
Copy link
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)))

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
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.

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
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.)

src/rl78.c Outdated
@@ -131,7 +197,7 @@ int rl78_send_cmd(port_handle_t fd, int cmd, const void *data, int len)
buf[len + 4] = ETX;
int ret = serial_write(fd, buf, sizeof buf);
// Read back echo
if (1 == communication_mode)
if ((1 == communication_mode) | (5 == communication_mode))
Copy link
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 ==

src/rl78.h Outdated
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
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
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