Shop OBEX P1 Docs P2 Docs Learn Events
Multiport Serial & LCD Text Drivers with common Format I/O Object (similar to jm_fullduplexserial) — Parallax Forums

Multiport Serial & LCD Text Drivers with common Format I/O Object (similar to jm_fullduplexserial)

Cluso99Cluso99 Posts: 18,069
edited 2021-02-12 20:57 in Propeller 2

At last I have achieved this :sunglasses:
Renamed thread to better title

Update 2021-02-13 v064: Added "demo_fullduplexserial.spin2" single UART demo; renamed demo files; removed debug code from the format object

rr_format_IO.spin2
A common standalone formatting object based on jonnymac’s fullduplexserial and jm_nstr objects with the serial driver section replaced with a common decoupled hub buffer interface.

  • All I/O is decoupled via hub buffers using the head, tail, start and end hub pointers (not indexes)
  • Up to 16 port/slots are supported although this can be extended (I've done 64 as an exercise)
  • Each port/slot supports a one-way transmission (ie a transmitter or a receiver)
  • FullDuplex is supported by using two port/slots
  • Now you can write your code and decide which I/O driver to add later by simply substituting the I/O driver object(s) with other(s).
  • Doesn’t just work with serial drivers
  • Multiport serial object (included) supporting up to eight (8) full-duplex or up to sixteen (16) mix of transmit and receive serial pins (port/slots)
  • LCD Text Driver (included) supporting ST7796S chip based 4.0in TFT 480x320 color LCD (or similar) with 8x8 font giving 60x40 columns x rows. Basic text functions supported.

rr_format_IO.spin2 features

  • Based on the brilliant object by @JonnyMac (jm_fullduplexserial and jm_nstr)
  • jm_nstr is incorporated into the object rather than it being a separate object
  • Most calls are the same - some have a prefix of tx to be IMHO more consistent
  • Additional calls are provided for memory dumps (hex with ascii), etc
  • Input (receive) characters, strings, etc. Receive strings support basic backspace editing.
  • Output (transmit) characters, strings, formatted strings, hex, decimal, octal, etc.
  • This object interfaces to the hub buffers using the head, tail, start and end hub pointers (not indexes)
  • It incorporates a transmit and a receive interface
  • Multiple copies of this object can be used, up to a total of 16 combined transmit and receive port/slots
  • Provides a common method interface for standard formatting methods while being decoupled from the separate I/O driver(s) physically used. ie the formatting object is not embedded with the I/O Driver code.
  • Stand-alone Multiport Serial (supports a single full-duplex serial too) already completed.
  • Stand-alone LCD Text Driver already completed. Can be used as a template/basis for other LCD displays.
  • VGA and Keyboard Drivers coming soon.

Advantages

  • No longer do you need to build formatting routines into every driver eg serial, LCD, VGA, HDMI, Keyboad, etc
  • There will not be the subtle method naming differences that come with using the formatting methods built in to every I/O driver eg out, tx, txchr to name a few
  • Driver code is much smaller and simpler, meaning they are easier to write and debug
  • User code doesn't need to cater for the differences
  • User code written for serial can be swapped for LCD, VGA or most other character style devices (ie excludes Flash and SD)
  • The buffer interface is simple and code snippets can/will be provided - currently just copy them from the example provided drivers
  • Using simple switching, the drivers can be substituted, even on the fly - demo coming

Disadvantages

  • Only usable with FlexSpin as it uses @@@ to get absolute hub address for buffers etc

I/O Device Drivers
Currently two I/O Device Drivers are posted here:

  • rr_ser_drv_multiport16.spin2 is a multiport serial driver supporting up to eight (8) full-duplex UARTS or a mix of up to sixteen (16) single transmitters and receivers. A 64 port version has been tested using 29 full-duplex UARTS.
  • rr_lcd_drv_text_60x40 supporting an LCD color text 60x40 (480x320 pixels) - a cheap SPI LCD commonly available on eBay etc for around $12. I have a 4.0" version using the ST7796S driver chip and I've noticed there are versions around 3.5in too. The ILxxxx chip is similar and should work with minor tweaks.
    Mine has the Touch chip interface too. @MRoberts has posted code for the touch interface on my LCD thread a couple of weeks back but I haven't had time to look at it properly yet.

  • I will be doing a VGA driver shortly

  • Followed by USB Keyboard using @garryj driver code

Demos

  • demo_fullduplexserial.spin2 demonstrates one (1) serial UART port on P63-62.
  • demo_fullduplexserial3.spin2 demonstrates three (3) serial UART ports, one on P63-62, a second on P1-0, and a third on P3-2. Link (or place shunts) on P0-1 and P2-3. Typing on your serial terminal will echo the characters to the second and then to the third port and back to the first.
  • demo_serial_lcd.spin2 demonstrates one (1) serial UART port on P63-62, plus one (1) LCD transmit port with the LCD 4" SPI on pins P41-47. Pins are compile time configurable, or run-time with additional code to read and set them in a call, just like fullduplexserial.

If anyone has any ideas for better file naming please let me know. They're not that good :(

BTW I fixed a small configuration bug too so I have posted a new zip file and removed the older zip file.

As always, post bugs or comments here. Enjoy :sunglasses:

Comments

  • Cluso99Cluso99 Posts: 18,069

    reserved for more info

  • Cluso99Cluso99 Posts: 18,069

    From the demo_ser_lcd code, here is the OBJ declaration

    OBJ
      ser    : "rr_format_IO_060"                   ' SERIAL: opens recv & xmit format/handler     (same cog) - based on jonnymacs jm_fullduplexserial & jm_nstr
      serdrv : "rr_ser_drv_multiport16"             ' SERIAL: starts multiport pasm driver         (new  cog)
    
      lcd    : "rr_format_IO_060"                   ' LCD:    opens xmit format/handler            (same cog) - based on jonnymacs jm_fullduplexserial & jm_nstr
      lcddrv : "rr_lcd_drv_text_60x40"              ' LCD:    starts lcd pasm driver               (new  cog) - lcd text driver 4in 480x320 color ST7796 SPI
    

    And here is the setup code

    ' open fdx serial port...
      ser.open_fdx_slot(@port_params, SER_SLOT, SER_SLOT+1)                                             ' SERIAL: opens recv & xmit format/handler     (same cog)
      sercog := serdrv.start_driver(@port_ser_config)                                                   ' SERIAL: starts multiport pasm driver         (new  cog)
      serdrv.config_fdx_port(@port_ser_config, SER_SLOT, SER_RX, SER_SLOT+1, SER_TX, MODE, BAUD)        ' SERIAL: add/configure serial ports/smartpins (same cog) 
    
    ' open/start the LCD format/handler & pasm driver...
      lcd.open_tx_slot(@port_params, LCD_SLOT)                                                          ' LCD:    opens xmit format/handler            (same cog)
      lcddrv.config_pins(@port_lcd_config, LCD_CE, LCD_RST, LCD_DC , LCD_SDA, LCD_CLK, LCD_LED, LCD_SDO) 'LCD:    set pins first       
      lcdcog := lcddrv.start_driver(@port_lcd_config, LCD_SLOT)                                         ' LCD:    starts lcd pasm driver               (new  cog)
    

    and an example of outputting to both ports (the same messages but they do not need to be)

      ser.fstr0(string("------------------------------------------------\r\n"))
      ser.fstr0(string("Serial and LCD drivers and format/handlers v060 \r\n"))
      ser.fstr1(string("  Serial driver started in cog %1x\r\n"), sercog-1)
      ser.fstr1(string("  LCD    driver started in cog %1x\r\n"), lcdcog-1)
    
    
      lcd.fstr0(string("------------------------------------------------\r\n"))
      lcd.fstr0(string("Serial and LCD drivers and format/handlers v060 \r\n"))
      lcd.fstr1(string("  Serial driver started in cog %1x\r\n"), sercog-1)
      lcd.fstr1(string("  LCD    driver started in cog %1x\r\n"), lcdcog-1)
    

    and for good measure, here is a hub memory dump call of the port_params list

      addr := @port_params
      ser.fstr1(string("Port-params     %8x\r\n"), addr)
      ser.txdump(addr, addr+(4*4*16)-1)
      ser.txcr()
    

    and the dump it actually produces

    Port-params         2420
    02420: 20 25 00 00  20 25 00 00  20 25 00 00  60 25 00 00  ' %.. %.. %..`%..'
    02430: 77 25 00 00  85 25 00 00  60 25 00 00  A0 25 00 00  'l%..q%..`%...%..'
    02440: C8 25 00 00  C8 25 00 00  A0 25 00 00  E0 25 00 00  '.%...%...%...%..'
    02450: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    02460: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    02470: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    02480: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    02490: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    024A0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    024B0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    024C0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    024D0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    024E0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    024F0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    02500: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    02510: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  '................'
    

    This dump above shows the 16 slots, each being one line long. There are 3 slots being used in my demo with the first two being the serial recv and xmit, followed by the LCD xmit. Each line has the pointer to the hub buffer being used with the order head, tail, start and end.
    So the second line at $0000_2430 has
    head = $0000_2575
    tail = $0000_2585
    start = $0000_2560
    end = $0000_25A0 (ie end+1)

  • Cluso99Cluso99 Posts: 18,069
    edited 2021-02-12 18:15

    Here's the setup code for demo_serial3.spin2 which demonstrates three (3) serial ports. I've supplied buffers for up to 4 fdx ports (8 port/slots/pins). If you want to try more let me know and I'll describe how to configure them (easy). Next release I'll do that just in case.

      ser1.open_fdx_slot(@port_params, SER_SLOT,   SER_SLOT+1)                                          ' SERIAL: opens recv & xmit format/handler     (same cog)
      ser2.open_fdx_slot(@port_params, SER_SLOT+2, SER_SLOT+3)                                          ' SERIAL: opens recv & xmit format/handler     (same cog)
      ser3.open_fdx_slot(@port_params, SER_SLOT+4, SER_SLOT+5)                                          ' SERIAL: opens recv & xmit format/handler     (same cog)
      sercog := serdrv.start_driver(@port_ser_config)                                                   ' SERIAL: starts multiport pasm driver         (new  cog)
      serdrv.config_fdx_port(@port_ser_config, SER_SLOT,   SER_RX, SER_SLOT+1, SER_TX, MODE, BAUD)      ' SERIAL: add/configure serial ports/smartpins (same cog) 
      serdrv.config_fdx_port(@port_ser_config, SER_SLOT+2, 1,      SER_SLOT+3, 0,      MODE, BAUD)      ' SERIAL: add/configure serial ports/smartpins (same cog) 
      serdrv.config_fdx_port(@port_ser_config, SER_SLOT+4, 3,      SER_SLOT+5, 2,      MODE, BAUD)      ' SERIAL: add/configure serial ports/smartpins (same cog) 
    

    I just hard-coded the pins 0-3 and slots 2-5.

  • Great work. I hope this is used widely and others build drivers to fit within this paradigm.
    Now if only the Parallax tools can support this in some way, even if it means reserving fixed locations for the configuration and buffer pointers that don’t change with the program being compiled.

  • Cluso99Cluso99 Posts: 18,069

    @AJL said:
    Great work. I hope this is used widely and others build drivers to fit within this paradigm.
    Now if only the Parallax tools can support this in some way, even if it means reserving fixed locations for the configuration and buffer pointers that don’t change with the program being compiled.

    In my P2 OS I need these buffers/pointers/tables to be fixed in hub just below the dual-mapped top 16KB. IIRC the dual-mapping gets removed once the 16KB is write protected. So the region I'm meaning is below $7C000 so I'll probably take the 4K $7Bxxx.
    This way I can load self compiled binaries that know about the fixed buffers/pointers/tables using a "CON" only object. They don't need to know about any of the loaded drivers (ie device drivers).

Sign In or Register to comment.