'Super Com Z" Communication Support Routines

Here you can share completed projects or parts of projects that may be useful to others. You may post files relevant to ZBasic - source code, schematics, etc.
zbasicandy
Posts: 193
Joined: 25 January 2006, 19:56 PM

'Super Com Z" Communication Support Routines

Post by zbasicandy »

I modified some of the routines to run on the "Super Com Z" 4 port communications board. You will find these general routines handy for serial port communications.
Attachments
ComSupport_R2.bas
General and board specific serial port communications routines
(47.72 KiB) Downloaded 3678 times
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

There has got to be a more generic way to do this rather than duplicate and try to keep all the code in sync for each port. Here is some untested code that parameterizes the port number:

Code: Select all

private const InBufSize as INTEGER = 50   ' 41-byte buffer.
private const OutBufSize as INTEGER = 50  ' 41-byte buffer.

private const minLogicalPort as Byte = 3
private const maxLogicalPort as Byte = 6

public InBuf(1 To InBufSize, minLogicalPort to maxLogicalPort) as BYTE
public OutBuf(1 To OutBufSize, minLogicalPort to maxLogicalPort) as BYTE

'==============================================================================
Private Function getInputBuffer(ByVal buffer as UnsignedInteger, ByVal port as Byte) as Integer
	getInputBuffer = CInt(buffer) + InBufSize * CInt(port - minLogicalPort)
End Function

Private Function getOutputBuffer(ByVal buffer as UnsignedInteger, ByVal port as Byte) as Integer
	getOutputBuffer = CInt(buffer) + OutBufSize * CInt(port - minLogicalPort)
End Function

'=========================================================================================
'Subroutines - Generic for all ZX-xx's
'=========================================================================================
public sub OpenSerialPort(ByVal port as Byte, ByVal BaudRate as LONG)
	' Opens serial port n at the specified baud rate.
	CALL OpenQueue(CByteArray(getInputBuffer(Inbuf.DataAddress, port)), InBufSize)
	CALL OpenQueue(CByteArray(getOutputBuffer(Outbuf.DataAddress, port)), OutBufSize)
	CALL OpenCom(port, BaudRate, _
		CByteArray(getInputBuffer(Inbuf.DataAddress, port)), _
		CByteArray(getOutputBuffer(Outbuf.DataAddress, port)))
END sub

'===============================================================================
public sub PutByte(ByVal port as Byte, ByVal Value as BYTE) 
	' Sends one byte of binary data to serial port n. The byte is sent
	' directly without translating it to a STRING type.
	CALL PutQueueByte(CByteArray(getOutputBuffer(Outbuf.DataAddress, port)), Value)
END sub
...
....
and so on
Note I also changed PutQueue to PutQueueByte.

This code could be even cleaner but MemAddress does not support a two-dimensional array. The documentation is not clear on this point.
Mike Perks
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

MemAddress does not support a two-dimensional array
I'm not sure I understand exactly what you mean. This code is perhaps simpler and seems to work correctly.

Code: Select all

Public Sub OpenSerialPort(ByVal port as Byte, ByVal BaudRate as Long)
	If &#40;&#40;port >= minLogicalPort&#41; And &#40;port <= maxLogicalPort&#41;&#41; Then
		' Opens serial port n at the specified baud rate. 
		Call OpenQueue&#40;CByteArray&#40;Inbuf&#40;1, port&#41;.DataAddress&#41;, InBufSize&#41; 
		Call OpenQueue&#40;CByteArray&#40;Outbuf&#40;1, port&#41;.DataAddress&#41;, OutBufSize&#41; 
		Call OpenCom&#40;port, BaudRate, CByteArray&#40;Inbuf&#40;1, port&#41;.DataAddress&#41;, _ 
				CByteArray&#40;Outbuf&#40;1, port&#41;.DataAddress&#41;&#41;
	End If
End Sub 
- Don Kinzer
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

The code:

Code: Select all

MemAddress&#40;Inbuf&#40;1, port&#41;&#41;
causes a compile error of:

Code: Select all

Error&#58; function "MemAddress" parameter 1, multi-dimension arrays cannot be passed as parameters
I thought I tried the variation of code you suggested with DataAddress and also got a compiler error. It obviously works.

I think there is enough information now for ZBasicAndy to rewrite his code to be more generic and take up less program memory. And he will appreciate the flexibility when ZBasic supports 12 serial ports ;)
Last edited by mikep on 31 March 2006, 23:11 PM, edited 1 time in total.
Mike Perks
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

MemAddress(Inbuf(1, port)) causes a compile error
Indeed it does. I confirmed the the following code, embodying the same idea, compiles without error in BasicX.

Code: Select all

Dim u as new UnsignedInteger
Dim ai&#40;1 to 5, 2 to 10&#41; As Byte
Dim i as Integer

Sub Main&#40;&#41;
	u = MemAddressU&#40;ai&#40;1, i&#41;&#41;
End Sub
- Don Kinzer
zbasicandy
Posts: 193
Joined: 25 January 2006, 19:56 PM

Post by zbasicandy »

Don, I tried your suggestion and I got several compiler errors:
Note: Mikep code works and compiles OK.
Note: ZBasic IDE Version: 1.0.4 / ZBasic Compiler version 1-1-18 / ZX-40 Firmware 1.1.6

Test_CommSupport.bas:201: Error: missing comma, operator or right parenthesis, identifier "CByteArray"
Test_CommSupport.bas:201: Error: missing comma, operator or right parenthesis, identifier "OpenQueue"
Test_CommSupport.bas:202: Error: missing comma, operator or right parenthesis, identifier "CByteArray"
Test_CommSupport.bas:202: Error: missing comma, operator or right parenthesis, identifier "OpenQueue"
Test_CommSupport.bas:203: Error: missing comma, operator or right parenthesis, identifier "CByteArray"
Test_CommSupport.bas:203: Error: missing comma, operator or right parenthesis, identifier "OpenCom"
Public Sub OpenSerialPort(ByVal port as Byte, ByVal BaudRate as Long)
If ((port >= minLogicalPort) And (port <= maxLogicalPort)) Then
' Opens serial port n at the specified baud rate.
Call OpenQueue(CByteArray(Inbuf(1, port).DataAddress), InBufSize)
Call OpenQueue(CByteArray(Outbuf(1, port).DataAddress), OutBufSize)
Call OpenCom(port, BaudRate, CByteArray(Inbuf(1, port).DataAddress), CByteArray(Outbuf(1, port).DataAddress))
End If
End Sub
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

I can compile the code below with v1.1.18 with no errors. Would you try this (limited to just the code shown) and see what you get? If this compiles OK then there is an interaction somewhere that needs to be isolated. I suspect that it may be an error prior to the code cited from which the compiler did not fully recover.

Code: Select all

private const InBufSize as INTEGER = 50   ' 41-byte buffer. 
private const OutBufSize as INTEGER = 50  ' 41-byte buffer. 

private const minLogicalPort as Byte = 3 
private const maxLogicalPort as Byte = 6 

public InBuf&#40;1 To InBufSize, minLogicalPort to maxLogicalPort&#41; as BYTE 
public OutBuf&#40;1 To OutBufSize, minLogicalPort to maxLogicalPort&#41; as BYTE 

Sub Main&#40;&#41;
End Sub

Public Sub OpenSerialPort&#40;ByVal port as Byte, ByVal BaudRate as Long&#41; 
	If &#40;&#40;port >= minLogicalPort&#41; And &#40;port <= maxLogicalPort&#41;&#41; Then 
		' Opens serial port n at the specified baud rate. 
		Call OpenQueue&#40;CByteArray&#40;Inbuf&#40;1, port&#41;.DataAddress&#41;, InBufSize&#41; 
		Call OpenQueue&#40;CByteArray&#40;Outbuf&#40;1, port&#41;.DataAddress&#41;, OutBufSize&#41; 
		Call OpenCom&#40;port, BaudRate, CByteArray&#40;Inbuf&#40;1, port&#41;.DataAddress&#41;, CByteArray&#40;Outbuf&#40;1, port&#41;.DataAddress&#41;&#41; 
	End If 
End Sub 
- Don Kinzer
DH*

Post by DH* »

This thread appears to address the issue I was pondering about 6 weeks back in the Queues for COM3, 4, 5, 6 thread in the ZBasic Language forum.

How do you use StatusQueue with the input queues defined in this manner?

It would be hepful if there were a system level nibble for all 4 queues so that one call would tell if there was any input to any of the 4 ports.
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

This thread appears to address the issue I was pondering about 6 weeks back ...
I remember that. I should have thought of this technique then.
How do you use StatusQueue with the input queues defined in this manner?
The CByteArray() construction can be used anywhere an "array of Byte" parameter is required.

Code: Select all

Function SerialDataAvailable&#40;ByVal port as Byte&#41; as Boolean
	SerialDataAvailable = StatusQueue&#40;CByteArray&#40;Inbuf&#40;1, port&#41;.DataAddress&#41;&#41; 
End Function
- Don Kinzer
zbasicandy
Posts: 193
Joined: 25 January 2006, 19:56 PM

Comm routine doesn't compile

Post by zbasicandy »

Don said
I can compile the code below with v1.1.18 with no errors
I tried it "all alone" on a blank project page - and it still fails with the same errors!
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

zbasicandy wrote:Don, I tried your suggestion and I got several compiler errors:
Note: ZBasic IDE Version: 1.0.4 / ZBasic Compiler version 1-1-18 / ZX-40 Firmware 1.1.6

Test_CommSupport.bas:201: Error: missing comma, operator or right parenthesis, identifier "CByteArray"
Test_CommSupport.bas:201: Error: missing comma, operator or right parenthesis, identifier "OpenQueue"
Test_CommSupport.bas:202: Error: missing comma, operator or right parenthesis, identifier "CByteArray"
Test_CommSupport.bas:202: Error: missing comma, operator or right parenthesis, identifier "OpenQueue"
Test_CommSupport.bas:203: Error: missing comma, operator or right parenthesis, identifier "CByteArray"
Test_CommSupport.bas:203: Error: missing comma, operator or right parenthesis, identifier "OpenCom"
Public Sub OpenSerialPort(ByVal port as Byte, ByVal BaudRate as Long)
If ((port >= minLogicalPort) And (port <= maxLogicalPort)) Then
' Opens serial port n at the specified baud rate.
Call OpenQueue(CByteArray(Inbuf(1, port).DataAddress), InBufSize)
Call OpenQueue(CByteArray(Outbuf(1, port).DataAddress), OutBufSize)
Call OpenCom(port, BaudRate, CByteArray(Inbuf(1, port).DataAddress), CByteArray(Outbuf(1, port).DataAddress))
End If
End Sub
For Don. I can also compile this code which is why I pointed ZBasicAndy back to this forum.
Mike Perks
zbasicandy
Posts: 193
Joined: 25 January 2006, 19:56 PM

Comm routine doesn't compile

Post by zbasicandy »

I am "eat crow" on this one. My compiler was only 1.1.10 (last month) instead of the newer one 1.1.18. I found it by "double checking" the map file.
This brings up another point. With all the changes to each module e.g. compiler, IDE and firmware would it be possible to click on ONE button or help menu to show all three revision versions or maybe when it compiles, show at the bottom of the screen.
Another point, the release for 1.1.18 was just an exe and not an install exe. Would it also be possible to send with the version update an installer to update to module version in question. I am only talking from a newbee frame of mind!
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

Would it also be possible to send with the version update an installer...?
It could be done that way. My thought was that it was simpler to just extract a file from a .zip archive.
[W]ould it be possible to click on ONE button or help menu to show all three revision versions or maybe when it compiles, show at the bottom of the screen?
It may be possible to modify the IDE so that the compiler version is displayed in the About box. Displaying the firmware version number is somewhat more difficult but it possibly could be done as well. In the interim, you could add the version display option to your .pjt file as shown in the sample below. This will cause the compiler version to be displayed as part of the output of every build.

Code: Select all

--version
--list=test.lst
test.bas
- Don Kinzer
DH*

Post by DH* »

dkinzer wrote:
MemAddress(Inbuf(1, port)) causes a compile error
Indeed it does. I confirmed the the following code, embodying the same idea, compiles without error in BasicX.

Code: Select all

Dim u as new UnsignedInteger
Dim ai&#40;1 to 5, 2 to 10&#41; As Byte
Dim i as Integer

Sub Main&#40;&#41;
	u = MemAddressU&#40;ai&#40;1, i&#41;&#41;
End Sub
Do you plan to change MemAddress so it will work with multi-dimensional arrays? For an old geezer who has to type with only one (arthritic) hand, the CByteArray construction is cruel and unusual punishment. :(
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

dhouston wrote:Do you plan to change MemAddress so it will work with multi-dimensional arrays? For an old geezer who has to type with only one (arthritic) hand, the CByteArray construction is cruel and unusual punishment. :(
I think you misunderstand what you have to code. The two versions are:

Code: Select all

CByteArray&#40;MemAddress&#40;InBuf&#40;1, port&#41;&#41;
and

Code: Select all

CByteArray&#40;InBuf&#40;1, port&#41;.DataAddress&#41;
There are a few things that can help you (or anyone):
1. Use Ctrl-space to get an autocompletion list. For example I can type MemAddress with 4 keystrokes: M, e, Ctrl-space, Enter
2. ZBasic allows things to be mixed-case so don't worry about caps

I assume you are already using other tools to help with your physical impairment which reduce or made it easier to type.
Mike Perks
Post Reply