Odroid N2 UART Custom Baud Rate for MIDI

Post Reply
stepy
Posts: 10
Joined: Tue Sep 10, 2019 11:12 pm
languages_spoken: english
ODROIDs: Odroid C2, N2, VU7
Has thanked: 6 times
Been thanked: 1 time
Contact:

Odroid N2 UART Custom Baud Rate for MIDI

Unread post by stepy » Mon Oct 07, 2019 11:29 pm

Is it possible for an Odroid N2, UART port, to operate, at a non-standard baud rate?

My test setup is as follows:

Operating system is Armbian Buster.

Followed the instructions on the Odroid N2 Wiki, in order to enable and use the UART_EE_A feature.

https://wiki.odroid.com/odroid-n2/appli ... /gpio/uart

Connected an oscilloscope to the Odroid N2,

Header J2, Pin 8, which gives the TXD output.

Using

command line

sudo stty -F /dev/ttyS1 115200

echo "somestringdata" > ttyS1

or

my own custom software

Am able to set standard baud rates and send data, which arrives correctly, on the oscilloscope.
For example, 9600, 115200.

However, the baud rate, that I require, for Midi, is a non-standard

31250

When I try to set this baud rate, it causes an error, or falls back, to a standard baud rate. The closest standard baud rate is 38400, but this will not work for Midi.

In the past, the solution that I have successfully used, on a Raspberry Pi 3 with Raspbian is as follows.

There are various hacks/fixes that can be applied. These are related to the Pi's configuration. It is hardware and operating system dependent and also quite fiddly to setup. But it does work.

In short, if I am not mistaken, I believe that the UART clock and various divisors are 'tricked' or set in such a way, so that the desired Midi 31250 baud rate, is attained. In other words, after the fix has been applied, select a standard 38400 and you get 31250.

Tried searching the web, for solution like this, or any other solution, for the Odroid N2, but could not find much.

Is the Odroid N2 hardware able to work with 31250 baud rate?

If yes, then what are the configuration parameters and where can they be found, in order to achieve this?

Any help would be very much appreciated, thanks.

User avatar
odroid
Site Admin
Posts: 32519
Joined: Fri Feb 22, 2013 11:14 pm
languages_spoken: English
ODROIDs: ODROID
Has thanked: 184 times
Been thanked: 349 times
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by odroid » Tue Oct 08, 2019 9:41 am

According to the UART device driver source code, there seems no falls back function to a standard baud rate. So there would be no hardware limitation.
https://github.com/hardkernel/linux/blo ... #L537-L587

I think a similar method in this link might be a solution even I have zero experience though.
https://stackoverflow.com/questions/194 ... e-on-linux
These users thanked the author odroid for the post (total 2):
ManuelFantoni (Wed Oct 09, 2019 7:08 pm) • stepy (Fri Oct 11, 2019 4:11 am)

stepy
Posts: 10
Joined: Tue Sep 10, 2019 11:12 pm
languages_spoken: english
ODROIDs: Odroid C2, N2, VU7
Has thanked: 6 times
Been thanked: 1 time
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by stepy » Fri Oct 11, 2019 4:09 am

Thanks very much for your reply. It was very helpful. Learnt a lot about device drivers. Am familiar with C but am still struggling to get it to work.

Tried the suggestion of setting speed to 38400 and custom devisor to 48. (baud_base/31250 = 48) Did this using linux setserial program, with the appropriate parameters. setserial seems to set and show the parameters correctly, but still do not see 31250 midi baud rate on the oscilloscope. Also setserial is shown as being depreciated.

Tried the suggestion of setting speed to 38400 and tty->alt_speed to 31250, but could not figure out how to do it.

If I am not mistaken, it seems that both of these mechanisms, may be depreciated or not supported in the meson uart device driver. Please correct me if I am not understanding correctly.

Therefore, would be great-full for any help.

How do you get 31250 baud rate out of the Odroid N2 UART Port?

Thanks for any help or suggestions

stepy
Posts: 10
Joined: Tue Sep 10, 2019 11:12 pm
languages_spoken: english
ODROIDs: Odroid C2, N2, VU7
Has thanked: 6 times
Been thanked: 1 time
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by stepy » Sun Oct 20, 2019 12:42 am

Since my last post have read everything that I can find, on the web, related to setting a non-standard UART baud rate, in Linux.

It seems that the list of Linux standard baud rates, has not kept up with modern hardware, so is tied to the past and does not look like changing any time soon.

The suggested data structures, functions to manipulate them and low level kernel services, are from a past era of early Linux. They are way out of date.

Many of the dependencies seem like an unfathomable rats nest. The whole mechanism seems overly complicated and built on rigid, sketchy foundations and bygone standards from the past.

It is not my intention to criticise this system. Can see historically, how it has evolved from Unix and early Linux. Also appreciate that supporting such a diversity of hardware and requirements is no easy feat, to say the least.

On the one hand, it has mechanisms that have been tested and in place for a very long time. There seems to have been, a resistance to change, for fear of breaking something.

On the other hand, to keep up with the multitude of evolving hardware and evolving requirements, various modifications, fixes, hacks, standards, functions, constants, data structures, and flags, etc., have been added over the years.

Unfortunately, it appears to have reached a point, where it has become so complex that it is almost unusable, for anything other than the standard baud rates. Please correct me if I am mistaken or missing something.

Have written several programs in C, in order to test the many suggested ways of setting a non-standard baud rate. There seems to be about five or six main ways of doing it. They all rely on manipulating bits, inside bytes, inside structures, which are accessed via various services and functions.

Each test program that I have written works, in the sense that it is able to, write to and verify, by reading back the values, in the various data structures. However, none of them can successfully set a custom baud rate. Additionally, it is not clear what the dependencies are. For example there seems to be so many different versions of the mechanism and its constants, that when you set a certain bit in a data structure, there is no easy way to know if that bit is even relevant or being ignored.

Think I have now exhausted my search for an example that actually works, in the context of this thread.

Considered alternatives such as bit banging a software uart out through the gpio pins. Apart from a quick and dirty solution, for example a slow, crude tx only Uart, it is not a good solution.

Considered hacking the device driver or writing some c code to manipulate it. Spent a long time studying the device driver code, but do not have enough knowledge to understand it fully. Again, as above, get confused over the dependencies, what is calling what, which included files, functions, constants and structures are relevant.

Alternatively use a separate Uart chip or something like an arduino to do the serial port, but this seems very indirect and wasteful, when there are already three serial ports on the Odroid N2.

Therefore my two questions still stand.

I wonder if the kind folks at Odroid could answer this if possible.


Can the Odroid N2 Uart run at a non-standard baud rate, for example 31250?

If yes, then how do you do it?

Thanks for any help

User avatar
odroid
Site Admin
Posts: 32519
Joined: Fri Feb 22, 2013 11:14 pm
languages_spoken: English
ODROIDs: ODROID
Has thanked: 184 times
Been thanked: 349 times
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by odroid » Mon Oct 21, 2019 9:00 am

We will try a hack into the kernel driver for your easier life.
These users thanked the author odroid for the post:
stepy (Tue Oct 22, 2019 3:51 am)

User avatar
tony.hong
Posts: 45
Joined: Tue Jun 04, 2019 1:49 pm
languages_spoken: korean
ODROIDs: All
Location: korea
Has thanked: 11 times
Been thanked: 9 times
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by tony.hong » Mon Oct 21, 2019 4:21 pm

Hi, stepy

I edited UART driver code to set baudrate to 31250 when setting baudrate to 38400.

I wrote test code using wiringPi and measured buadrate.

UART driver after editing

linux/drivers/amlogic/uart/meson_uart.c

Code: Select all

static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
{
	u32 val;
	struct meson_uart_port *mup = to_meson_port(port);
	struct platform_device *pdev = to_platform_device(port->dev);

	while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_EMPTY))
		cpu_relax();

#ifdef UART_TEST_DEBUG
	if (port->line != 0)
		baud = 115200;
#endif

	// this part is added.
	// trace_printk() is not neccesarry, it is just for debugging.
	trace_printk("Your baudrate: %ld\n", baud);
	if(baud == 38400)
	{
		baud = 31250;
		trace_printk("Change to %ld\n", baud);
	}

...
Linux kernel build Ref: https://wiki.odroid.com/odroid-n2/softw ... ing_kernel
Changes of Installation section
arch/arm64/boot/Image -> arch/arm64/boot/Image.gz
arch/arm64/boot/dts/meson64_odroidn2.dtb -> arch/arm64/boot/dts/amlogic/meson64_odroidn2.dtb


Test code

Code: Select all

#include <stdio.h>
#include <wiringSerial.h>

int main(void)
{
        int fd1, fd2;
        fd1 = serialOpen("/dev/ttyS1", 38400);
        fd2 = serialOpen("/dev/ttyS2", 38400);

        serialPutchar(fd1, 0xAA); // 10101010
        serialPutchar(fd1, 0xAA);

        int count = 0;
        while(1)
        {
                if(serialDataAvail(fd2))
                {
                        printf("%c", serialGetchar(fd2));
                        count++;
                        if(count == 2)
                        {
                                break;
                        }
                }
        }

        serialClose(fd1);
        serialClose(fd2);
}
Before editing
scope_1.png
scope_1.png (21.61 KiB) Viewed 540 times
When transmitting 10101010, (1s) / pulse-width is baudrate.

1s/26.088us is 38331 ~= 38400.

After editing
scope_2.png
scope_2.png (21.07 KiB) Viewed 540 times
1s/32.002us is 31248 ~= 31250.

Debugging with ftrace

Code: Select all

root@odroid:/home/odroid# stty -F /dev/ttyS0 38400
root@odroid:/home/odroid# cat /sys/kernel/debug/tracing/trace
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
...
 0)               |  uart_set_termios() {
 0)               |    uart_change_speed.isra.2() {
 0)               |      meson_uart_set_termios() {
 0)   0.875 us    |        uart_get_baud_rate();
 0)               |        /* Your baudrate: 38400 */
 0)               |        /* Change to 31250 */
 0)   0.250 us    |        uart_update_timeout();
 ...
 
Have a good day, stepy. 8-)
Last edited by tony.hong on Mon Oct 21, 2019 4:46 pm, edited 1 time in total.
These users thanked the author tony.hong for the post (total 2):
rooted (Mon Oct 21, 2019 10:39 pm) • stepy (Tue Oct 22, 2019 3:50 am)

User avatar
tony.hong
Posts: 45
Joined: Tue Jun 04, 2019 1:49 pm
languages_spoken: korean
ODROIDs: All
Location: korea
Has thanked: 11 times
Been thanked: 9 times
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by tony.hong » Mon Oct 21, 2019 4:27 pm

Ps. If you use Ubuntu 18.04, Ref: viewtopic.php?f=55&t=36220

sudo odroid-config
5. Interfacing Options -> 5 Serial (Enable/Disable Serial(UART) interface)
99 Laboratory -> 2 WiringPi installation (WiringPi installation for Odroid)

Is it helpful? Click 'Say Thanks' button ↗ :lol:
These users thanked the author tony.hong for the post (total 2):
mad_ady (Mon Oct 21, 2019 8:12 pm) • rooted (Mon Oct 21, 2019 10:40 pm)

stepy
Posts: 10
Joined: Tue Sep 10, 2019 11:12 pm
languages_spoken: english
ODROIDs: Odroid C2, N2, VU7
Has thanked: 6 times
Been thanked: 1 time
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by stepy » Tue Oct 22, 2019 4:22 am

Hi Tony,

Thank you very much for, the example driver code and the test code, this is very helpful.

Had a look at the, Linux kernel build Ref, link above, that you kindly supplied.

Do I need to follow the full "Cross Compile - HOST-PC/Ubuntu" instructions?

It is quite long and complex.

or

Is there a shorter way of doing it by just recompiling the edited driver with out rebuilding the whole kernel, or maybe some other simple procedure?

If it is necessary to rebuild the whole kernel, then am not sure exactly which steps to follow. I do not have Ubuntu.

The target machine is an Odroid N2 with Armbian Buster.

Also have available

PC with Debian Buster
Laptop with Windows 7

Thanks for your fast and valuable answers.

Am still struggling a bit, any further help would be very much appreciated.

User avatar
tony.hong
Posts: 45
Joined: Tue Jun 04, 2019 1:49 pm
languages_spoken: korean
ODROIDs: All
Location: korea
Has thanked: 11 times
Been thanked: 9 times
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by tony.hong » Tue Oct 22, 2019 9:52 am

You can choose either Cross or Native. I think the wiki is quite complex as you think. So I edit that.

If you want to cross compile, Sequence is below. Cross-compiling on Debian might be no problem.
  • Installing required packages
  • Toolchain (6.3.1)
  • Checkout(Linux tab)
  • <- edit driver
  • Compile(Basic tab)
  • Installation(Linux tab)
My knowledge about Kernel is shallow so I don't know how partial rebuilding affects the whole.

I don't have any experience with Armbian kernel. about Armbian, https://forum.armbian.com/

stepy
Posts: 10
Joined: Tue Sep 10, 2019 11:12 pm
languages_spoken: english
ODROIDs: Odroid C2, N2, VU7
Has thanked: 6 times
Been thanked: 1 time
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by stepy » Sat Nov 02, 2019 1:47 am

Hi Tony,

Thanks very much for your reply. The steps above and your edits in the wiki make it much clearer.

I followed the steps for cross compile.

Used PC with Debian Buster as the build machine.

It worked and created the target files. I did not continue from that point, because wanted Armbian as the target, not Ubuntu. However was useful to learn the build process.

See Armbian docs

https://docs.armbian.com/Developer-Guid ... eparation/

for information on building an Odroid Armbian operating sytem.

Armbian Build
The directory below, on the build computer:

/home/build

Was used to build the operating system. I cloned it from github.

The target image file and compressed file end up in the directory below:

/home/build/output/images

Either of these files can be used to create a bootable SD card.

Etcher is used for this, on the build machine.

The entire build process was done on the build machine. It needs to be a fast machine with plenty of disk space. Even then, it is very complicated and time consuming.

Tool Chain
Tried building with Vagrant but wasted lots of time trying to setup the tool chain. Could not get it to work. Could only find limited old stuff on forums. Conclusion, for my setup, it is unusable, out of date dependencies, etc.

Used Docker, this seemed to work much better.

Dependencies

The build directory contains files related to Armbian. It contains a configuration file, that allows the build process, to access Hardkernel's source files.
Which is where the Hardkernel's uart device driver source file, is located.

I created a fork, (not to be confused with a branch), in my account, on github, from the Hardkernel's repository on github. The fork in my account, then showed as being in sync with the Hardkernel version. In other words my fork is identical to the original.

Edited the source file in my fork. Then committed it. Then shows my fork as being one commit ahead of Hardkernel's.

Paths Config File

See "User provided sources config overrides" in Armbian docs link above.

Created

build/userpatches/sources

directory and put

odroidn2.conf

into it.

Then edited the file and replaced the Hardkernel's, kernel repository path, with my github kernel repository path.
In other words it will build from my fork, containing the edited source file.

Finally, put the operating system image onto an SD card. Put the SD card onto the Odroid N2. Powered up the Odroid N2. Did basic configuration. Set the Baud Rate to 38400.

Tested the UART, success, it worked. Phew, that was a really long one to get working!

(Previously, in an attempt to avoid re-building the whole system, tried various other methods with patches, branches, local repository on Build PC, etc., but could not get it to work. Was too complicated and could not fully understand it. Wasted quite a bit of time. The brute force hack method described above seems to be the cleanest and easiest method, that I could find.

One draw back is that if there are any similar edits to a source file, then the whole procedure has to be repeated and a new image put onto the SD card. Then an existing Odroid N2, project would then have to be re-installed from scratch after putting the new SD card into the Odroid N2.

In other words, if you are in the middle of an Odroid N2 development project and want to edit the device driver source file, you have to re-install the entire operating system, project files and dependencies. But anyway, for now, it works and that was the goal. Great!)

Thanks again for all the help.
These users thanked the author stepy for the post:
tony.hong (Tue Nov 05, 2019 5:44 pm)

User avatar
odroid
Site Admin
Posts: 32519
Joined: Fri Feb 22, 2013 11:14 pm
languages_spoken: English
ODROIDs: ODROID
Has thanked: 184 times
Been thanked: 349 times
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by odroid » Sat Nov 02, 2019 10:01 am

Glad to hear that you made it work. :D

BTW, can you tell me which MIDI devices you are trying to connect to the N2 directly?

stepy
Posts: 10
Joined: Tue Sep 10, 2019 11:12 pm
languages_spoken: english
ODROIDs: Odroid C2, N2, VU7
Has thanked: 6 times
Been thanked: 1 time
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by stepy » Sat Nov 02, 2019 11:19 pm

Thank you for your interest.

The only device that I have connected, to the Odroid N2, so far, is an oscilloscope, in order to see what is coming out of the serial TX pin, on the gpio header connector.

Have designed my own Midi Interface PCB. It will be connected to the serial TX and RX pins, on the gpio header connector. It has standard 5 pin din connectors for Midi In and Midi Out, so that a regular Midi keyboard/synth can be connected. The first prototype design has not been finalised yet. Wanted to make sure that am able to get the correct signals to and from the Odroid N2 first.

In the past created a similar project, using a Raspberry Pi 3. Used an off the shelf Midi interface from Hobbytronics http://www.hobbytronics.co.uk/midi-brea ... yword=midi I believe this product is now discontinued. Used wiringpi and a hack, in order to get the correct Midi Baud Rate from the Uart serial port on the gpio header connector.

It worked well, except it did not work when connected to a Novation Circuit, but was ok on several other keyboards/synths. Think the reason that it may not have work with Novation Circuit might be down to the non-standard design of the Hobbytronics Midi Interface, possibly the electrical signalling levels. It seems suitable for hobbyist and will probably work with most keyboards. However this is only a guess, as did not investigate further. Apart from that it worked very well.

One concern that I had with the project, was having a dependency on wiring pi and the Midi Baud Rate hack. Did not want my project to be so tightly bound to this mechanism, because with out it, the midi port would not work. Also very difficult to port to other hardware and operating systems. This is the problem that am experiencing now. It has taken considerably longer to do it the second time around, now on the Odroid N2. One would usually expect to get a result faster, after having the experience, from the first time around.

Another reason that have not finalised the Midi interface pcb design yet, is that it is required to work on all Midi keyboards/synths new or old, as far as possible. The expectation is for a professional Midi Port that any musician can use with no problems. Just plug in your synth and it works.

From what I have learned so far, it seems quite tricky, there is quite a lot to consider, the selection and availability of components, and the electrical specification, whilst trying to adhere to the Standard Specification at www.midi.org as much as possible. The software side has already been discussed above.

Have noticed in many forums, that an alternative solution, for getting Midi in and out from a single board computer such as Odroid, is to use a USB to Midi interface. This is usually simpler and faster to setup and get working. Have also investigated various other ways of getting Midi In and Out. For example, using other interfaces on the N2 gpio header connector, SPI, etc,. N2 to arduino, etc,. to Midi In / Out. In the end, the serial ports on the N2 seemed the best choice for this project.

In summary the project requires both types of Midi interface on an Odroid N2, with Armbian Buster Operating System:

MIDI IN - 5 pin din circular connector
MIDI OUT - 5 pin din circular connector

USB - The user plugs in their USB to Midi interface.

Now that have managed to create an OS image, with a Uart that has a Midi Baud Rate, shall put it onto Odroid N2, re-install the project and continue the design of the Serial to Midi Din Connector Interface PCB.

As this is only a relatively small part of the overall project, which has other i/o user interfaces, am hopeful to find ways in which it is not necessary to reinstall the operating system, the project, dependencies and configurations, each time a low level fragment of code needs to be tweaked, in order to get the hardware to do what is required. Anyway for now the solution works, that's cool.

I think the original question has now been answered, so am not sure if should start another subject, however, would be great full for any help, suggestions or questions.

Thank you

User avatar
mad_ady
Posts: 6789
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, N1, H2, N2
Location: Bucharest, Romania
Has thanked: 216 times
Been thanked: 165 times
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by mad_ady » Sun Nov 03, 2019 12:02 am

Since you're using buildroot, you're running a custom system without a package manager. You could manually compile missing software (like we used to do in ghe old days), or use docker to deploy various software and you get rid of the burden of regenerating your firmware. Of use one of the standard distros that are kind enough to provide a package manager (blessed be its soul!).
These users thanked the author mad_ady for the post:
stepy (Fri Nov 08, 2019 12:27 am)

stepy
Posts: 10
Joined: Tue Sep 10, 2019 11:12 pm
languages_spoken: english
ODROIDs: Odroid C2, N2, VU7
Has thanked: 6 times
Been thanked: 1 time
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by stepy » Fri Nov 08, 2019 12:23 am

Hi mad_ady

Thank you for your suggestions.

Am not very familiar with buildroot. On wikipedia it is described as: "Buildroot is a set of Makefiles and patches that simplifies and automates the process of building a complete and bootable Linux environment for an embedded system". Shall read up, on this.

What I did was edit the uart device driver source code. Build the whole operating system (Armbian) from scratch, following the instructions at https://docs.armbian.com/Developer-Guid ... eparation/

Added one or two apps as part of the build. This all ends up as an image file. Then use Etcher to put the image onto an SD card. Then put the SD card into the Odroid N2. At this point the Odroid is ready for it's first boot. (Incidentally package manager is included, for example apt-get).

After this first boot, login, and basic configuration, etc. The contents of the SD card will now be different from the original image. Loosely speaking, for example, I could now call this new os version "foobian". Next I do several manual configuration tweaks to the system. (these would be very tricky to do automatically as part of the build, but i guess in theory is possible). Build and install some apps that are not available as executable packages. Therefore, the foobian image on the SD card in the Odroid has changed again.

At this point, the main focus would be on the development of the project files. These will be changing frequently through out the life of the project. But mostly can be thought of simply as a directory with lots of files. Therefore easier to backup.

Have a work flow where, before making any risky changes, the SD card in the Odroid, is cloned to a new image file, on a separate PC. If the changes cause a problem. Then can restore, by putting the recent foobian image from the pc on to an SD card using Etcher.

This backup and duplication system works ok, except if you have to tweak a low level operating system source file. Then you have to go right back to the start. In other words re-build the operating system. Then re-do all the steps again, as above.

It would be good if there was an easy solution to this. At the start of a development project, there is often no way to anticipate, if any low level os changes will be required. If you are in the middle of a complex project, you do not want to start again from scratch, because a single line of code in a device driver needed to be changed. Am not sure if I am missing a trick, in the whole pipeline, from initial design to a reproducible SD card in an Odroid N2 as a final product. Any suggestions are welcome.

Thanks.

User avatar
mad_ady
Posts: 6789
Joined: Wed Jul 15, 2015 5:00 pm
languages_spoken: english
ODROIDs: XU4, C1+, C2, N1, H2, N2
Location: Bucharest, Romania
Has thanked: 216 times
Been thanked: 165 times
Contact:

Re: Odroid N2 UART Custom Baud Rate for MIDI

Unread post by mad_ady » Fri Nov 08, 2019 3:39 am

Ok, here are some tips:
1. After you manually customize your OS to your liking make a backup (try odroid-backup). You can restore it later if needed.
2. Invest your time in ansible. It's a framework that allows you to define a set of actions that can be done on a system (like a fancy script). It can help you do loads of things - manage packages, compile from source, manage files, etc. It's a bit difficult to learn but in the end you get anrecepie that you can run on a brand new system and it will bring it into a known state.

Post Reply

Return to “Hardware and peripherals”

Who is online

Users browsing this forum: No registered users and 4 guests