RC15 Serial & GPIO

I have a program that uses GPIO and serial connections at the moment I use the modules:-GPIO 0.60
PISerial 0.74
These are running on a PI B+ and every thing works fine.

The device I’m using is connected on the serial connection it waits for a single ASCII byte G to V
it the responds with a G-V or g-v depending on the information it has.

Anyway if I use the OS_SerialOp commands in RC15 I cannot receive any characters from
the device, I can send a byte using SerialOp OK, The device has an LED on the front of the unit
that only lights if the correct ASCII code has been used.

As I can send the correct byte to the unit I am assuming that the format and baud rate
are correctly set I realise there is a seperate setting of baud rate for the receive.

I am using:-

SYS “OS_SerialOp”,3,byte for TXSYS “OS_SerialOp”,4 TO ,byte%

in receive byte% is always 0

GPIO seems to operate correctly

BTW if I trySYS “GPIO_ReadMode”,14 TO byte%
byte%=4 should this be 5(Uart) or am I reading the help manual wrong! (possible:-)

The Serial module is now in ROM so you should not load the serial block drivers !SerialDev (it is now obsolete) – if you load the block drivers (PiSerial_xxx SWIs) as well as the Serial module in ROM (OS_Serial SWIs) you won’t receive anything.

I have now got serial working with RC15.
After looking at the circuit diagram I realized that I have an RS485 half duplex connection
which basically means both the transmit and receive use the same twisted pair.

In this situation you normally use a master (Raspberry PI) and slaves (in my case PIC chips)
The master transmits a slave ID byte which the slaves then respond to in this way to can have many slave devices.

I have to add the OS_Hardware command to ensure that the transmission is complete before I start receiving data from the slaves.
I suspect that PiSerial must have waited for the byte to be sent before returning control to the program? and that is why the original worked.

I have downloaded the source for the raspberry pi and I’m now trying to compile. It looks that only for one serial port something is done . The HAL entry HAL_UARTPorts only gives one port back. ( It is there in the code ). How is the opinion here should the second serial port also be supported ? And how ?. I want to give it a go to code it.

As I understand it the second serial port (the “mini UART”) derives its clock from the CPU clock. So any time the CPU frequency changes the UART will need to be reconfigured.

The OS will adjust the CPU clock to try and save on power when the system is idle. So we could extend the OS to allow the UART driver to be aware of those transitions and either prevent them from happening or re-adjust itself accordingly. But the GPU can also decide to adjust the CPU clock itself (e.g. to stop the system overheating), and I don’t think it directly notifies us when that happens. So unless the CPU is locked at the slowest frequency the mini UART is always going to be a bit unstable.

If you want to try writing a driver for the mini UART, I think you have three options available:

Implement it within the HAL (change HAL_UARTPorts to return 2, and fix up the other UART functions to behave appropriately depending on which UART number is specified). However the separation between the HAL and the OS might make it difficult to automatically cope with the CPU clock changing.

Implement it within a RISC OS module that exposes the serial port as a device in the DeviceFS filesystem (the current serial port is exposed this way). If the driver conforms to the interfaces described in this doc then it should be compatible with software which is capable of using the main serial port via its DeviceFS entry. The BCMSupport module contains the CPU clock driver, so if you were to implement the serial driver in that module then it could be directly notified of any changes to the CPU clock that are made by RISC OS. Potentially it could also regularly poll the GPU to see if the GPU has changed the clock speed without us knowing about it.

The mini UART is described in the public BCM2835 datasheet, this page has a link to it and a bunch of document errata.

However, if you’re interested in getting the Pi 3’s bluetooth chip working, it might be better to go with the approach Linux uses: Use the PL011 UART for bluetooth and use the mini UART for the debug/serial terminal. HAL_UARTStartUp adjusts the pin mux settings so that the PL011, you should be able to adjust (or just disable) that code so that it uses the right pin mux settings for the bluetooth chip. You may also want to delete lines 273-278 inclusive so that higher UART transfer rates can be used (note that this will also break the clock divider calculation, since UARTCLK is hardwired to 3MHz). IIRC, apart from having a higher clock rate and not being affected by the CPU clock rate, the PL011 also has deeper FIFOs than the mini UART, so it’s definitely the best choice when you want performance & reliability.

Yes, I want to get the Bluetooth chip working I think that is a little bit less complicated than the WiFi part of the CYW43438 . The CYW43438 is if I have read the documentation correctly connected to the PL011 but I want to have the mini UART also working.
What would be in the spirit off the current RISCOS development ?. HAL or in a separate module ( and perhaps put it later in HAL ). I presume if I put it in module the Shared C lib is ‘available’.

Putting it in the HAL would be more consistent with other platforms. In theory it should also be the simplest way of getting it up and running, since you won’t need to worry about writing your own DeviceFS interface (the Serial module automatically populates DeviceFS with devices for all of the HAL UARTs)

However, placing it in the HAL will make it difficult to deal with the CPU clock changes: One of the design goals of the HAL is to make it OS-agnostic, so you can’t really have the HAL call arbitrary RISC OS SWIs in order to monitor the CPU speed.

If you want to implement it within the HAL, perhaps the cleanest option would be to have the HAL export a new HAL device containing whatever entry points are necessary to allow the UART driver to be notified of clock changes. Then the BCMSupport module can detect that device and call it whenever it’s changing the CPU speed.

Mainwhile I made some progress and I’m now writing the miniUART driver in C with already preparing to be put in the HAL. Sorry for the delay but the problem with work it consumes so much free time.
I have two questions:
1) Where are the interrupts handled or do you know if the AUX ( MiniUART and some SPI ) is already handled in the interrupt handling
2) Where can I find the device (interrupt) number to be returned by int HAL_UARTDevice(int port) ?.
Simple questions ;-)

The last time I looked (C v4), ansilib was a rather “all or nothing” library, in that you either linked all or most of it, or nothing.

It’s a shame Acorn never bothered to implement their libraries properly so you only needed to link in the functions actually used (and their dependencies) and not huge swathes of unnecessary code “because it is in the same source file”…

The last time I looked (C v4), ansilib was a rather “all or nothing” library, in that you either linked all or most of it, or nothing.

I came across a possible need for strlcpy, and I found there is a libbsd maintained for GNU linux primarily, I think. It is intended to link as a whole, but to use a single function, it could be taken out of it’s C file and used. The include files look like they would exist as include/bsd/string.h etc, but once again, you could probably have a local src declaration header like “bsd.h”.
Edit: actually I guess you dont need the declaration when not linking to the library and have the function locally.
I dont know if the use in cat(ting) to a unix domain socket would be possible anyway, so I haven’t bothered.
I have nearly completed an autobuilder version for dash, and have added a builtin cat command. yash looked simpler, but it is maintained by a japanese person and it is totally UTF-8. Those functions are commented out (if 0) in unixlib, is this because RISC OS itself can’t do UTF-8 in a way that is needed?
ps: The water is getting too warm downunder for the Emperor penguins food source, Maybe you could take a few migrants up your way now things have cooled down (-:

1) Where are the interrupts handled or do you know if the AUX ( MiniUART and some SPI ) is already handled in the interrupt handling

If the code is in the HAL (implementing the HALUARTAPI), then the Serial module (aka the DualSerial component in CVS) which will be in charge of registering & implementing the interrupt handler (making use of the appropriate HALUART calls, e.g. HAL_UARTInterruptID to determine the cause of the interrupt)

If you’re implementing a prototype outside of the HAL, you’ll have to register & implement the interrupt handler manually (using OS_ClaimDeviceVector to register the handler with the OS, followed by HAL_IRQEnable to make sure the interrupt isn’t masked in the interrupt controller) – and if you’re using C then this would ideally be done in a module, so that CMHG veneers can be used to allow your C code to be called by the kernel (since the kernel doesn’t know how to set up the C environment your code needs). Or you could conceivably test the code by polling the interrupt register (i.e. whenever you’re expecting an interrupt, call your HAL_UARTInterruptID implementation in a loop until it says something’s happening)

2) Where can I find the device (interrupt) number to be returned by int HAL_UARTDevice(int port) ?.

I believe it will be 29, aka iDev_GPU_AuxInt from hdr.BCM2835 in the HAL sources. But because it’s a shared interrupt (shared with two of the SPI busses) you’ll also have to set bit 31 so that OS_ClaimDeviceVector knows to treat it as a shared interrupt (but when you call e.g. HAL_IRQEnable, bit 31 must be masked out!). You’ll also have to interact with the AUXEnables and AUXIRQ registers (similar to the SPI code) to enable/disable and check for the UART interrupt.

Another question I have made a C header file ( I’m writing the drivers in C instead of assembler ) would it be desirable to have the same names as in in the hdr.BCM2835 or will this lead to a clash ?.
For the rest busy typing ;-)