Reading serial port peripherals [SOLVED]
-
- DCEmu Newbie
- Posts: 7
- https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
- Joined: Tue Nov 29, 2022 7:09 am
- Location: Where sailors hang out
- Has thanked: 9 times
- Been thanked: 3 times
Reading serial port peripherals [SOLVED]
I manually compiled Kallisti OS on my PC and also have a broadband module in my DC.
How do you read the serial port at the back? Say I have an I2C gyro module on an Arduino Nano that works over serial port baud rate 9600 and I want to stream roll, pitch, yaw data over into the console. Can I connect GND, 5V, TX on the Arduino to RX on the Dreamcast and read the gyro data for use in a game? What is the library to do that?
How do you read the serial port at the back? Say I have an I2C gyro module on an Arduino Nano that works over serial port baud rate 9600 and I want to stream roll, pitch, yaw data over into the console. Can I connect GND, 5V, TX on the Arduino to RX on the Dreamcast and read the gyro data for use in a game? What is the library to do that?
Last edited by 1337 on Wed Dec 28, 2022 3:35 pm, edited 1 time in total.
- ThePerfectK
- Insane DCEmu
- Posts: 147
- Joined: Thu Apr 27, 2006 10:15 am
- Has thanked: 27 times
- Been thanked: 35 times
Re: Reading serial port peripherals
there is a libary in kernel/arch/dreamcast/include/dc that is intended for scif (serial communication inferface with FIFO). Here is the header: http://gamedev.allusion.net/docs/kos-cu ... if_8h.html
And more appropriately, here's the source, as used by dcload: https://github.com/Kochise/dreamcast-do ... oad/scif.c
Renesas manual on serial communication: https://www.renesas.com/us/en/document/ ... anguage=en
these would be the best places to start reading.
And more appropriately, here's the source, as used by dcload: https://github.com/Kochise/dreamcast-do ... oad/scif.c
Renesas manual on serial communication: https://www.renesas.com/us/en/document/ ... anguage=en
these would be the best places to start reading.
- These users thanked the author ThePerfectK for the post (total 4):
- |darc| • legit nyck • Ian Robinson • 1337
Still Thinking!~~
-
- DCEmu Newbie
- Posts: 7
- Joined: Tue Nov 29, 2022 7:09 am
- Location: Where sailors hang out
- Has thanked: 9 times
- Been thanked: 3 times
Re: Reading serial port peripherals
I made my own serial cable using the top half of a HDMI connector and one of those cheap red breakout boards. The dc-tool-serial client program works on my PC and successfully uploads binaries to the Dreamcast at 115200 baud rate. I run the latest Ubuntu Debian-based distro, the serial board appears as "/dev/ttyUSB0" in the system.
The scif.h and scif.c in the dc-load-serial program (what runs on the Dreamcast) is somewhat different to what's included with KOS, regardless I gave it a try but it doesn't seem to work.
I copy my *.cdi file onto an SD card, then run it from GDEMU so that there's no possibility of something like the debug console blocking the serial port.
At the beginning of the program I initialise the serial port at 9600 baud rate:
Then, inside the program loop, I try to read one character from the stream of data but it's just saying "-1" which is the state when there's no data:
To see if "-1" changes to anything else, I tried sending a binary using dc-tool-serial at baud rate of 9600:
(As I know this program can definitely talk to the DC)
I also tried directly sending stuff to the serial port:
Are there more code examples of someone using the SCIF functions?
Could it be that the use of dbgio to print text on screen disables reading from serial (as it's a debugging library)?
I'm trying to make a free game with a serial port peripheral, like the maracas, it reports location and rotation as a string of text.
Update:
When I use the scif_read, get_char and buffer read functions I don't get anything, so I deconstructed scif.c and looked at the hardware register involved:
And I can see the register changing live on screen in my Dreamcast game every time I send a character from my PC over command line:
So the hardware is working, but I don't know why the libraries aren't.
Now I need to figure out how to read a string.
Update;
I printed all of the registers onto the screen to understand what's happening in the background.
The FIFO register SCFRDR2 is where the data is received
If I just send a string of text out the serial port the whole port gets jammed and no more data can be sent.
In the blocked state, the FIFO register SCFRDR2 stops flashing numbers and the line status register SCLSR2 changes from 0 to 1.
So the only reliable way to send data to the DC is to do it in single bytes like this:
Or this:
But after a while the SCFRDR2 register stops changing (without line status flipping to 1)
And it only starts changing again once a new line command is passed with, say '\n'.
So the only reliable way of sending data I found is by passing single bytes terminated by a new line.
Say, this:
Or this:
I tried the above approx. 500 times and it works consistently, nothing else does.
Update
I can see now where the problem is
The baud rate isn't 9600, it's somewhere between 57600 and 76800, I determined this by installing PuTTy and trying different speed values. When I set the speed to 57600 and then with he PuTTy window open press and hold number 1 on the PC's keyboard, I can see the Dreamcast display '31' under 'Recive fifo data" on screen, When I press 2 I get 32 and other corresponding ASCII codes:
https://www.rapidtables.com/code/text/ascii-table.html
This problem is specific to this program, when I use dc-load-serial *.cdi it can easily read data from the PC at 115200 baud and doesn't complain about anything.
The bit rate register on the Dreamcast reads '1a'.
Update
When I booted into my game again with the PuTTy window open and serial cable connected to the Dreamcast - I got KallistiOS debug messages printed. My guess was correct, the debugging console is enabled and it's interfering with the serial port by forcing its own baud rate. So as long as I use the scif_read() function at 57600 baud, reading the serial port works perfectly fine. Though I would prefer to set and use 115200 baud but don't see the setting in KallistiOS, maybe I need to dig deeper.
scif.c by the way has a funny comment:
Maybe that was written 20 years ago, I have no problem pushing binaries to the console at 115200 baud.
Anyway, I hope this post will be useful to someone who finds it via Google (maybe it will be me in 2 years )
The scif.h and scif.c in the dc-load-serial program (what runs on the Dreamcast) is somewhat different to what's included with KOS, regardless I gave it a try but it doesn't seem to work.
I copy my *.cdi file onto an SD card, then run it from GDEMU so that there's no possibility of something like the debug console blocking the serial port.
At the beginning of the program I initialise the serial port at 9600 baud rate:
Code: Select all
void Initialize()
{
scif_init();
scif_set_parameters(9600, 1);
}
Code: Select all
void Update()
{
dbgio_dev_select("fb");//switch to on-screen printing
printf("Char read: %d", scif_read());
printf("\n");
}
(As I know this program can definitely talk to the DC)
Code: Select all
sudo ./dc-tool-ser -t /dev/ttyUSB0 -b 9600 -x /home/user/Desktop/dreamcast/game/demo.elf
Code: Select all
echo 'A' > /dev/ttyUSB0 9600
Could it be that the use of dbgio to print text on screen disables reading from serial (as it's a debugging library)?
I'm trying to make a free game with a serial port peripheral, like the maracas, it reports location and rotation as a string of text.
Update:
When I use the scif_read, get_char and buffer read functions I don't get anything, so I deconstructed scif.c and looked at the hardware register involved:
Code: Select all
/* receive fifo data register */
#define SCFRDR2 (volatile unsigned char *) 0xffe80014
Code: Select all
scif_flush();
scif_init();
scif_set_parameters(9600, 0);
Code: Select all
printf("Register: %x", *SCFRDR2);
Now I need to figure out how to read a string.
Update;
I printed all of the registers onto the screen to understand what's happening in the background.
Code: Select all
/* serial mode register */
printf("Serial mode:");
printf("%x\n", *SCSMR2);
/* bit rate register */
printf("Bit rate:");
printf("%x\n", *SCBRR2);
/* serial control register */
printf("Serial control:");
printf("%x\n", *SCSCR2);
/* transmit fifo data register */
printf("Transmit fifo:");
printf("%x\n", *SCFTDR2);
/* serial status register */
printf("Serial status:");
printf("%x\n", *SCFSR2);
/* receive fifo data register */
printf("Receive fifo data:");
printf("%x\n", *SCFRDR2);
/* fifo control register */
printf("Fifo control:");
printf("%x\n", *SCFCR2);
/* fifo data count register */
printf("Fifo data count:");
printf("%x\n", *SCFDR2);
/* serial port register */
printf("Serial port:");
printf("%x\n", *SCSPTR2);
/* line status register */
printf("Line status:");
printf("%x\n", *SCLSR2);
If I just send a string of text out the serial port the whole port gets jammed and no more data can be sent.
Code: Select all
root@machine:/home/user# printf 'something' > /dev/ttyUSB0 9600
So the only reliable way to send data to the DC is to do it in single bytes like this:
Code: Select all
root@machine:/home/user# printf '\x86' > /dev/ttyUSB0 9600
Code: Select all
root@machine:/home/user# printf 'A' > /dev/ttyUSB0 9600
And it only starts changing again once a new line command is passed with, say '\n'.
So the only reliable way of sending data I found is by passing single bytes terminated by a new line.
Say, this:
Code: Select all
root@machine:/home/user# printf '%b' '\x86' > /dev/ttyUSB0 9600
Code: Select all
root@machine:/home/user# printf 'A\n' > /dev/ttyUSB0 9600
Update
I can see now where the problem is
Code: Select all
scif_set_parameters(9600, 1);
https://www.rapidtables.com/code/text/ascii-table.html
This problem is specific to this program, when I use dc-load-serial *.cdi it can easily read data from the PC at 115200 baud and doesn't complain about anything.
The bit rate register on the Dreamcast reads '1a'.
Update
When I booted into my game again with the PuTTy window open and serial cable connected to the Dreamcast - I got KallistiOS debug messages printed. My guess was correct, the debugging console is enabled and it's interfering with the serial port by forcing its own baud rate. So as long as I use the scif_read() function at 57600 baud, reading the serial port works perfectly fine. Though I would prefer to set and use 115200 baud but don't see the setting in KallistiOS, maybe I need to dig deeper.
scif.c by the way has a funny comment:
Code: Select all
/* Initialize the SCIF port; baud_rate must be at least 9600 and
no more than 57600. 115200 does NOT work for most PCs. */
/* recv trigger to 1 byte */
Anyway, I hope this post will be useful to someone who finds it via Google (maybe it will be me in 2 years )
- These users thanked the author 1337 for the post:
- ThePerfectK
- ThePerfectK
- Insane DCEmu
- Posts: 147
- Joined: Thu Apr 27, 2006 10:15 am
- Has thanked: 27 times
- Been thanked: 35 times
Re: Reading serial port peripherals [SOLVED]
Thank you so much for not only diving into this topic, but keeping the thread updated with not just your successes, but also your failures. That stuff helps so much, there have been so many topics that I've been able to work out only because decades ago some people took the time to document their efforts. If you don't mind, I'd like to clean up your posts and make a wiki entry about serial port communication!
- These users thanked the author ThePerfectK for the post (total 3):
- |darc| • GyroVorbis • 1337
Still Thinking!~~
-
- DCEmu Newbie
- Posts: 7
- Joined: Tue Nov 29, 2022 7:09 am
- Location: Where sailors hang out
- Has thanked: 9 times
- Been thanked: 3 times
Re: Reading serial port peripherals [SOLVED]
Please go ahead. I will publish the source code once the project is completed. I'm just embarrassed to do it now as it's more hacking than proper programming.ThePerfectK wrote: ↑Thu Jan 05, 2023 3:27 pm If you don't mind, I'd like to clean up your posts and make a wiki entry about serial port communication!
- These users thanked the author 1337 for the post:
- GyroVorbis