Common mailbox/buffers for disconnecting the string handler from the driver code
I am close to releasing the new formatter which is based on jonnymacs jm_fullduplexserial object. I've totally decoupled the formatter from the pasm driver(s) so that I now can run multiple copies of the formatter to support up to 16 port/slots (actually an arbitrary value).
I now have a multiport serial driver (up to 16 ports although I did a version of 64 with 58 tested) and an LCD Driver. The same formatter code runs them both, and will do so for other drivers such as VGA, Keyboard, etc.
However, I discovered that configuring the ports with pin numbers, baud, etc was a problem. So my solution is to have a configuration mailbox to pass the configuration parameters and the standard port mailbox which contains the buffer head/tail/start/end pointers to the respective buffers.
Passing all those parameters was complex to say the least. So I abandoned that method (was working).
The alternative is to just edit a big list in the program with pin numbers for the relevant ports supported. They can still be changed on the fly, but this makes it easier to describe and implement from a users point of view.
Now the problem. Many of you know I have a real problem with not being able to force the location of code/variables/buffers into specifi hub locations. Well, this just bit me on the a....
Here is my big >100 line set of parameters that supports
- Serial configuration (16 ports)
- LCD configuration (1 port)
- 16 port/slots of pointers to buffer head/tail/start/end
- A buffer for each of the used port/slots (ie can be <16)
I have it contained in a DAT section. PropTool/pnut doesn't support include or ifdef
Here is this part of the code
'' ==================================================================================================================== dat { port/slots configuration, parameters and buffers} '' ==================================================================================================================== '' WARNING: Within the following groups, the order and size must be maintained !!! port_lcd_config {3 longs} '\ LCD configuration long @port_params '| ptr to port_params byte 0<<7 | LCD_SLOT '| inactive | slot# where: 1=active, bbbb=slot# byte LCD_CE '| LCD: Serial clock enable pin byte LCD_RST '| LCD: Reset pin (can be reset by software) byte LCD_DC '| LCD: Data / Command selection pin byte LCD_SDA '| LCD: Serial Data MOSI pin byte LCD_CLK '| LCD: Serial Clock pin byte LCD_LED '| LCD: LED backlight enable pin (hi to enable - ~2.4mA) byte LCD_SDO '/ LCD: Serial Data MISO pin port_ser_config {3 longs} '\ Multiport SERIAL configuration long @port_params '| ptr to port_params port_control '| (keep together!) byte {0} 0<<7 | 0<<6 | SER_RX {63} '| inactive | recv | pin# where: {slot} 1=active, 1=xmit, bbbbbb=pin# byte {1} 0<<7 | 1<<6 | SER_TX {62} '| inactive | xmit | pin# byte {2} 0 '| unused byte {3} 0 '| unused byte {4} 0 '| unused byte {5} 0 '| unused byte {6} 0 '| unused byte {7} 0 '| unused byte {8} 0 '| unused byte {9} 0 '| unused byte {10} 0 '| unused byte {11} 0 '| unused byte {12} 0 '| unused byte {13} 0 '| unused byte {14} 0 '| unused byte {15} 0 '/ unused port_params {16*4 = 64 longs} '\ max (16 ports) of 4 longs... port[slot]: buffer ptrs to p_head, p_tail, p_start, p_end long {0} @BUF0 '| \ {slot 0} p_head SERIAL-RX (ptr to current head of buffer) long @BUF0 '| | p_tail " (ptr to current tail of buffer) long @BUF0 '| | p_start " (ptr to start of buffer) long @BUF0+BUF_SIZE '| / p_end " (ptr to end+1 of buffer) long {1} @BUF1 '| \ {slot 1} p_head SERIAL-TX long @BUF1 '| | p_tail " long @BUF1 '| | p_start " long @BUF1+BUF_SIZE '| / p_end " long {2} @BUF2 '| \ {slot 2} p_head LCD long @BUF2 '| | p_tail " long @BUF2 '| | p_start " long @BUF2+BUF_SIZE '| / p_end " long {3} 0 '| \ {slot 3} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {4} 0 '| \ {slot 4} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {5} 0 '| \ {slot 5} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {6} 0 '| \ {slot 6} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {7} 0 '| \ {slot 7} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {8} 0 '| \ {slot 8} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {9} 0 '| \ {slot 9} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {10} 0 '| \ {slot 10} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {11} 0 '| \ {slot 11} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {12} 0 '| \ {slot 12} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {13} 0 '| \ {slot 13} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {14} 0 '| \ {slot 14} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '| / p_end " long {15} 0 '| \ {slot 15} p_head -unused- long 0 '| | p_tail " long 0 '| | p_start " long 0 '/ / p_end " ' Define buffers for up to 16 port/slots... ' -- 2 serial port/slots... (1 fdx uart serial ports) ' -- 1 LCD port/slot BUF0 byte 0[BUF_SIZE] '\ serial buffer(s): tx must follow rx when using quick method "openfdxport" BUF1 byte 0[BUF_SIZE] '/ BUF2 byte 0[BUF_SIZE] '> LCD buffer 'add more if required (max 16) '' ====================================================================================================================
Now the problem is this gets relocated. But the real issue is that the longs that contain addresses eg
- @port_params
- @BUF0
- etc
all insert an incorrect relative address into these hub locations. So when I pull these by reading via pasm or via long[port_control] I get the relative address, not the actual address where the buffers, etc are physically located.
As you can see, there are quite a number for a little piece of code that's about to grow substantially as more ports/drivers are added.
If the code is compiled without spin, then the physical hub addresses can be forced, and they work as expected.
Any ideas how to get past this without the cumbersome mess of physically re-plugging every corrected pointer back into the table?
Comments
Here is a piece of spin code writing out to the same formatter object, but being redirected to either the serial port or the LCD. It works but the initialisation is terrible.
Declare the objects
Open the objects (note the parameters are now simplieied)
And to use the serial and lcd objects
One potential suggestion was to compile the block as pasm only where the addresses would be correct, and then load the binary into the man code.
While this would work for me, the real benefit of this method is for general use where we can have a single "format" object and many "driver" objects all working harmoniously together.
These are the supported methods in the formatter object
You will probably recognise most of them! They are from jonnymacs fantastic jm-fullduplexserial and jm_nstr objects. Thanks Jon