Jump to content
IGNORED

The Compact Computer 40 (CC40)


Recommended Posts

So I reflashed my arduino with the latest HEXTIr.hex using avrdude, and now I am unable to open files nor save, although I can still OLD files on the SD card.

I reverted back to my original file but the problem persisted. I checked the connection points on the shield and everything seems to be OK, but I'm suspecting my shield is acting up here.

Any pointers on debugging?

Link to comment
Share on other sites

I don't have many that are easy to try.  There's debug statements in the code, but you'd need to recompile. A logic analyzer might help as well, but most folks don't have one.  You might try grabbing older versions of the code and seeing if that does anything (if it's the shield, it won't, but it might not be the shield).

 

I'm trying to free up some time to get this back on the bench and debug (I was planning to debug the set device command initially), but it might be a week or so, as there's lot in my list to get done first.

Link to comment
Share on other sites

Just a quick update. I poked around the SD shield again testing the continuity of connections as well as logic signals and could not find any issues. So I put the drive back together again and it worked fine this time around, except for the SE DEV command which gives an IO ERROR 1, meaning that the command was not recognized as valid. This is using the latest HEXTIr.hex build. 

All other commands seem to work as they should (MD, DEL, CD etc...), so I think the SE DEV command is either buggy or there an implementation error somewhere.

If anyone here can double check this it would be great to make sure the issue is not on my end. Just run the following command:

OPEN #255,"20.SE DEV=21". If you do not get an error then try CLOSE #255 and you should get an expected error there since device 20 is now 21.

Link to comment
Share on other sites

I don't think open #255,"se dev=21" will work.  THere's no device number in the open statement.  Checking my manual, open needs to be :  open #<channel>, "<device_number>.<open parms>"

 

So, I think it's open #255,"20.se dev=21"

 

And then the close will fail, because device 20 is gone, but you need to do it to clean up the BASIC pointers.

 

Then, try to open #255,"20.b=9600" should succeed.

 

If the se dev=21 works, then the next step really should be to do open #255,"21.st", which is supposed to permanently store the new device number.

 

 

Link to comment
Share on other sites

So I started looking at the HEXOPS.cpp file and found the following definitions:

static const action_t cmds[] MEM_CLASS = {
                                        {EXEC_CMD_DEV,"de"},
                                        {EXEC_CMD_DEV,"dev"},
                                        {EXEC_CMD_STORE,"st"},
                                        {EXEC_CMD_STORE,"store"},
                                        {EXEC_CMD_NONE,""}
                                       };

So DE and DEV are equivalent.

 

Now looking at the code for the DEV command below, shouldn't the default to the first switch statement use the parse_cmd function instead of the parse_equate function to extract the requested command? I'm not really familiar with the C syntax, but it seems that the former function is used for the STORE command, which actually works, but not for the DEV command which does not...

cmd = (execcmd_t)parse_cmd(cmds, &buf, &len);
  // if a cmd, i will point to location after cmd
  // and cmd will equal type requested
  if(cmd != EXEC_CMD_NONE) {
    //skip spaces
    trim (&buf, &len);
  }
  switch (cmd) {
  case EXEC_CMD_STORE:
    ee_set_config();
    break;
  default:
    cmd = (execcmd_t)parse_equate(cmds, &buf, &len);
    switch(cmd) {
    case EXEC_CMD_DEV:
      if(dev != NULL) {
        rc = HEXSTAT_DATA_ERR; // value too large or not a number
        if(!parse_number(&buf, &len, 3, &value)) {
          if(value <= DEV_MAX) {
            rc = HEXSTAT_DATA_INVALID; // no such device
            for(i = 0; i < registry.num_devices; i++) {
              if(
                  (registry.entry[i].dev_low <= (uint8_t)value)
                  && (registry.entry[i].dev_high >= (uint8_t)value)
                ) {
                registry.entry[i].dev_cur = (uint8_t)value;
                *dev = (uint8_t)value;
                rc = HEXSTAT_SUCCESS;
                break;
              }
            }
          }
        }
      } else {
        rc = HEXSTAT_DATA_INVALID;
      }
      break;
    default:
      // error
      rc = HEXSTAT_OPTION_ERR;
      break;
    }
    break;
  }
  return rc;
}

 

Link to comment
Share on other sites

I used my comment as well, but I think my comment is wrong.

 

Since st works, try just doing open #255,"20.de=21"

 

I checked the source and there is no "set" or "se" in the entire source, so I must have decided to punt and just make the parms verbs themselves.  My apologies.  If your test works, I'll update the code.

 

For anyone who cares:

(main.cpp) The main parser reads the hex data, and determines the operation is open, and to the serial device.  It checks the registry that every specific soft peripheral registers with (registry.cpp) to find an entry to device 20.  It finds the serial.cpp library, so jumps to that.

IN serial.cpp, there is ser_open(), which does the open.  To ensure compatibility with HEXTIr's way to handling configuration when using the drive peripheral, where an open of some text would normally try to open a file with that name, the code (line 342) checks for channel 255.  If found, it immediately starts parsing config, but otherwise, it drops down and tries to do an actual open of a serial part, but it also handles configs there as well.  Both branches call ser_exec_cmds().

ser_exec_cmds() (line 279) tries to break apart the string into pieces, and then it sends each piece to ser_exec_cmd() (line 87)

ser_exec_cmd tries to match the first few letters of the command to one of two lists, shown in lines 61-85.  A cc40 list (b, .ba, d, .da, etc.) and a ti list of additional items (.tw,.nu, etc.).

if the command is not in the first set, then it drops into the default case (line 251) and checks the second set.  if that list doesn't work, it then calls hex_exec_cmd() in line 273

hexops.cpp contains the default config helper function, hex_exec_cmd() line 306.  Just like in serial.cpp, there is a list of commands about the function, as @Vorticon shows.  de and dev are both mapped to command DEV, while st, store are both mapped to STORE.  When the command is parsed into EXEC_CMD_DEV or EXEC_CMD_STORE, the switch statement in lines 327-342 kicks in.  If CMD_ST is found, do it. Otherwise, the code assumes its a "cmd=value" pair, and so tries to parse it.  ONce parsed, it checks if the cmd was DEV, and if so, it updates the registry with the new device ID.

 

 

  • Like 1
Link to comment
Share on other sites

Dang, I forgot about that.  You are most correct, apologies for that as well.

 

Do you have a way to recompile the code?  If so, you can alter the dev in the code for now, while I work on the issue.  Eitehr st is failing silently, and the code never gets called, or the parse_equate is broken.

 

Jim

Link to comment
Share on other sites

5 hours ago, brain said:

Dang, I forgot about that.  You are most correct, apologies for that as well.

 

Do you have a way to recompile the code?  If so, you can alter the dev in the code for now, while I work on the issue.  Eitehr st is failing silently, and the code never gets called, or the parse_equate is broken.

 

Jim

Sorry I don't have the tools to compile CPP. Hopefully it's a minor bug.

Out of curiosity, why was device 20 chosen for the on board RS232 since it was expected to conflict with the external device? I'm assuming it was to maintain compatibility with existing applications that use the RS232 and expect it to be device 20. I wonder how many users here have had a need for that.

Link to comment
Share on other sites

  • 2 weeks later...
  • 1 month later...
  • 2 weeks later...
24 minutes ago, dhe said:

Does the hex-ti-r emulate an rs232?

 

Next to a waffer tape, needed for storage, the rs232 for i/o with the outside is the second most needed peripheral. 

It does and is assigned device #20 which is the same as the hexbus rs232 peripheral. 

  • Like 1
Link to comment
Share on other sites

38 minutes ago, Vorticon said:

It does and is assigned device #20 which is the same as the hexbus rs232 peripheral. 

 

 So why did you go with a hexbus rs232, instead of running it through the hex-ti-r?   Was it just ease of cabling?

Link to comment
Share on other sites

1 hour ago, dhe said:

 

 So why did you go with a hexbus rs232, instead of running it through the hex-ti-r?   Was it just ease of cabling?

Pretty much :) I did not have the needed adapter and I have currently no other use for the RS232 peripheral so may as well put it to good use. It also has a parallel port so I may at some point print out data to a printer as well.

  • Like 1
Link to comment
Share on other sites

  • 2 months later...

Has the idea of an external display for the CC-40 been realized, other than the small number TI produced? I'm all in for one.

 

I was thinking about the hexbus device's RS232 port and the possibility of connecting it via RS232-USB dongle to a Raspberry PI with connected monitor. I'm sure this wouldn't break any speed records but 9600 baud, assuming that's the max for this device, isn't terrible, at least for text. Many of us used VT terminals back in the day and many were operating at that speed, and also had ability to create text effects such as bold, reverse video and colors.

 

Although this wouldn't be deeply integrated (ROM-based) without a lot of work, it'd be pretty easy to write a handful of BASIC methods to at least prove the idea.

 

Other than the speed limitation, it also wouldn't be terribly difficult to emulate more advanced features with a Linux application with a linked graphics package such as SDL, and have that app connect via the USB/serial.

 

I imagine with a bit more ingenuity an external keyboard could also be attached via the RPI.

  • Like 1
Link to comment
Share on other sites

2 hours ago, mrvan said:

Has the idea of an external display for the CC-40 been realized, other than the small number TI produced? I'm all in for one.

 

I was thinking about the hexbus device's RS232 port and the possibility of connecting it via RS232-USB dongle to a Raspberry PI with connected monitor. I'm sure this wouldn't break any speed records but 9600 baud, assuming that's the max for this device, isn't terrible, at least for text. Many of us used VT terminals back in the day and many were operating at that speed, and also had ability to create text effects such as bold, reverse video and colors.

 

Although this wouldn't be deeply integrated (ROM-based) without a lot of work, it'd be pretty easy to write a handful of BASIC methods to at least prove the idea.

 

Other than the speed limitation, it also wouldn't be terribly difficult to emulate more advanced features with a Linux application with a linked graphics package such as SDL, and have that app connect via the USB/serial.

 

I imagine with a bit more ingenuity an external keyboard could also be attached via the RPI.

Great idea. I suppose an external keyboard and monitor could be attached for development purposes and subsequently disconnected for regular use. 

  • Like 1
Link to comment
Share on other sites

There's a thread about this somewhere here. It has the display device protocol in it--for the one that Texas Instruments had working. 

 

I found a cheap (<$20) VFD display.   Futaba brand, I think. 40x4. Chars are 5x7 dots. Usual ASCII characters and  7 ? Slots for user-defined chars. Interface by I2C or SPI (just send it 8 bits for a char.) Thought that would be a nice upgrade. 


*VFD=Vacuum Fluorescent Display, what  we had on VCRs before blue LEDs. (hate blue LEDs.) Speak n Spell type. 

 


 

 

Link to comment
Share on other sites

I've started taking a stab at connecting the HEXTIr via serial port to a RPI, but not getting very far. I always receive 830 bytes from the below programs, where every byte is hex 00, regardless of any baud rate, parity or stop bit permutation. It's possible I'm missing the syntax for the serial port open on line 100 to set baud rate, etc. but the only syntax I found was for the TI-99 and the CC-40 seems to require something different and I've not found any documentation or examples.

 

If @brain or others could share their method for checking out the serial port that would be helpful and I'd gladly plagiarize. 

 

The BASIC program is

100 open #1,"20", display, output

105 for i=1 to 50

110 print "hello world!"

115 next i

120 close #1

 

The C program I used on the RPI, permuting through the baud, parity and stop bits, is

 

// C library headers

#include <stdio.h>

#include <string.h>

 

// Linux headers

#include <fcntl.h> // Contains file controls like O_RDWR

#include <errno.h> // Error integer and strerror() function

#include <termios.h> // Contains POSIX terminal control definitions

#include <unistd.h> // write(), read(), close()

 

int main() {

  // Open the serial port. Change device path as needed (currently set to an standard FTDI USB-UART cable type device)

  int serial_port = open("/dev/ttyUSB0", O_RDWR);

 

  // Create new termios struct, we call it 'tty' for convention

  struct termios tty;

 

  // Read in existing settings, and handle any error

  if(tcgetattr(serial_port, &tty) != 0) {

      printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));

      return 1;

  }

 

  tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)

  tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)

  tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size

  tty.c_cflag |= CS8; // 8 bits per byte (most common)

  tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)

  tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)

 

  tty.c_lflag &= ~ICANON;

  tty.c_lflag &= ~ECHO; // Disable echo

  tty.c_lflag &= ~ECHOE; // Disable erasure

  tty.c_lflag &= ~ECHONL; // Disable new-line echo

  tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP

  tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl

  tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes

 

  tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)

  tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed

  // tty.c_oflag &= ~OXTABS; // Prevent conversion of tabs to spaces (NOT PRESENT ON LINUX)

  // tty.c_oflag &= ~ONOEOT; // Prevent removal of C-d chars (0x004) in output (NOT PRESENT ON LINUX)

 

  tty.c_cc[VTIME] = 10;    // Wait for up to 1s (10 deciseconds), returning as soon as any data is received.

  tty.c_cc[VMIN] = 0;

 

  // Set in/out baud rate to be 9600

  cfsetispeed(&tty, B9600);

 

  cfsetospeed(&tty, B9600);

 

  // Save tty settings, also checking for error

  if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {

      printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));

      return 1;

  }

 

  // Write to serial port

  unsigned char msg[] = { 'H', 'e', 'l', 'l', 'o', '\r' };

  write(serial_port, msg, sizeof(msg));

 

  // Allocate memory for read buffer, set size according to your needs

  char read_buf [256];

 

  // Normally you wouldn't do this memset() call, but since we will just receive

  // ASCII data for this example, we'll set everything to 0 so we can

  // call printf() easily.

  memset(&read_buf, '\0', sizeof(read_buf));

 

  // Read bytes. The behaviour of read() (e.g. does it block?,

  // how long does it block for?) depends on the configuration

  // settings above, specifically VMIN and VTIME

  int num_bytes;

  int i;

 

  while (1) {

     num_bytes = read(serial_port, &read_buf, sizeof(read_buf));

 

     // n is the number of bytes read. n may be 0 if no bytes were received, and can also be -1 to signal an error.

     if (num_bytes < 0) {

         printf("Error reading: %s", strerror(errno));

         return 1;

     }

 

     // Here we assume we received ASCII data, but you might be sending raw bytes (in that case, don't try and

     // print it to the screen like this!)

//   printf("Read %i bytes. Received message: %s", num_bytes, read_buf);

     if (num_bytes) {

        fprintf (stdout, "%d: ", num_bytes);

        for (i = 0; i < num_bytes; i++) {

           fprintf (stdout, "%d ", read_buf[i]);

        }

        fputs ("\n", stdout);

        fflush (stdout);

      }

  }

 

 

  close(serial_port);

  return 0; // success

};

Link to comment
Share on other sites

The defaults in the code are:

 

https://github.com/go4retro/HEXTIr/blob/51ea22df26cbc6beedb13e90dd0e530246948a9c/src/serial.cpp#L569-L584

 

    _config.ser.bpsrate = 300;
    _config.ser.echo = TRUE;  // TODO see exactly what this means.
    _config.ser.length = LENGTH_7;
    _config.ser.line = LINE_CRLF;
    _config.ser.nulls = 0;
    _config.ser.overrun = _cfg.overrun;
    _config.ser.parchk = FALSE;
    _config.ser.parity = PARITY_ODD;
    _config.ser.stopbits = STOP_0;
    _config.ser.xfer = XFER_REC;

The XFER_REC should cause an issue, as defined by the HexBus-Specifications.pdf doc, page 242, but it looks like I did not implement it at all, so all XFER_* behave like XFER_CHAR, which is char in, char out...

 

See if those settings help.  If not, I'd hook it up to a terminal program and boot the system.  It might be that your build has debugging, which is either 57600 or 115200/n/8/1, and it overrides serial.  If so, my bad.  I try to turn it off when a build is ready, but I might forget at times.

 

If you need debugging, I can help, but it'll be a week, as I can't get to my lab this week.

 

Jim

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...