Page 1 of 1

Hello_World puzzler

Posted: 21 April 2013, 17:31 PM
by GTBecker
Here's something like the Hello_World that ZX devices run when new (plus Com9):

Code: Select all

'	option ConsoleSpeed 0
	option TargetDevice ZX24x
Private devId(1 to 10) as Byte
Private devName as String
Private Com1InQ(1 to 20) as Byte
Private Com1OutQ(1 to 20) as Byte
Private Com9InQ(1 to 20) as Byte
Private Com9OutQ(1 to 20) as Byte
Private Const crlf as string = chr(13) & chr(10)
Private	say(1) as string

Public Sub Main()
'	Call OpenQueue(Com1InQ, SizeOf(Com1InQ))
'	Call OpenQueue(Com1OutQ, SizeOf(Com1OutQ))
'	Call OpenCom(1, 19200, Com1InQ, Com1OutQ) 
	
	Call OpenQueue(Com9InQ, SizeOf(Com9InQ))
	Call OpenQueue(Com9OutQ, SizeOf(Com9OutQ))
	Call OpenCom(9, 9600, Com9InQ, Com9OutQ)
	
	' get device name
	System.DeviceID(devID)
	devName = MakeString(devId.DataAddress, SizeOf(devID))
	Dim i as byte
	i = StrFind(devName, Chr(0))
	If &#40;i <> 0&#41; Then
		devName = Left&#40;devName, i-1&#41;
	End If

	say&#40;0&#41; = devName & " says..."
	say&#40;1&#41; = "   Hello, world!"

	Do	' endless
		' alernate LEDs, say hello
		Call Hello&#40;0&#41;
		Call Hello&#40;1&#41;
	Loop
End Sub

Private sub Hello&#40;ByVal i as byte&#41;
	Debug.Print say&#40;i&#41;
'	Call PutQueueStr&#40;Com1OutQ, say&#40;i&#41; & crlf&#41;
	Call PutQueueStr&#40;Com9OutQ, say&#40;i&#41; & crlf&#41;
	Call PutPin&#40;Pin.RedLED, 0&#41;
	Call Delay&#40;0.5&#41;
	Call PutPin&#40;Pin.RedLED, 1&#41;
	Call PutPin&#40;Pin.GreenLED, 0&#41;
	Call Delay&#40;0.5&#41;
	Call PutPin&#40;Pin.GreenLED, 1&#41;	
End Sub
If Com1 uses Debug.Print it works but if Com1 opens queues and its port, and uses PutQueueStr, it fails. What am I missing?

Posted: 22 April 2013, 10:32 AM
by GTBecker
In contrast to the -24x behavior, the code above works on a -24n (excepting Com9, of course) whether using Debug.Print or opened Com1 and PutQueueStr().

Later edit: the -24n worked apparently because Option SignOn Off had been expressed in earlier code and remains that way in persistent ram if not reexpressed.

Posted: 23 April 2013, 10:43 AM
by GTBecker
This code appears to show that Option SignOn On causes native devices (at least the -24n and -24x) to crash if OpenCom1 is called before the signon string makes it out:

Code: Select all

   option TargetDevice ZX24x
   option SignOn On
Private Com1InQ&#40;1 to 30&#41; as Byte
Private Com1OutQ&#40;1 to 30&#41; as Byte

Public Sub Main&#40;&#41;

   call delay&#40;0.002&#41;

   Call OpenQueue&#40;Com1InQ, SizeOf&#40;Com1InQ&#41;&#41;
   Call OpenQueue&#40;Com1OutQ, SizeOf&#40;Com1OutQ&#41;&#41;

   Call OpenCom&#40;1, 19200, Com1InQ, Com1OutQ&#41;

   Call PutQueueStr&#40;Com1OutQ, "via PutQueue"&#41;
End Sub

Either increasing the delay period >=0.006S or commenting the OpenCom1 allows "ZBasic v4.1.3" (and the subsequent "via PutQueue") to appear - otherwise the machine crashes when Com1 tries to open.

Re: Hello_World puzzler

Posted: 23 April 2013, 11:42 AM
by dkinzer
GTBecker wrote:If Com1 uses Debug.Print it works but if Com1 opens queues and its port, and uses PutQueueStr, it fails. What am I missing?
The problem here is that the serial channel is being re-configured in the middle of the outputting of the sign on message. You can add a loop just before opening Com1 to ensure that outputting of the sign on message has completed.

Code: Select all

Do While &#40;&#40;StatusCom&#40;1&#41; And &H04&#41; <> 0&#41;
Loop
An alternate strategy is to turn off the sign on message using Option SignOn Off.

Posted: 23 April 2013, 12:07 PM
by GTBecker
Further, it appears that Option ConsoleSpeed 0 does not behave in native devices as documented:

"For native mode devices, the console speed can be set to zero thereby requesting that the console serial channel not be open initially. In this case, if you want to use the console serial channel you must specifically open it."

With Option ConsoleSpeed 0, on a -24x, opening Com1 to 19200 appears to work, but a subsequent PutQueueStr to Com1 resets the machine.

Code: Select all

    option ConsoleSpeed 0
   option TargetDevice ZX24x
   option SignOn Off
Private Com1OutQ&#40;1 to 30&#41; as Byte

Public Sub Main&#40;&#41;
   Call OpenQueue&#40;Com1OutQ, SizeOf&#40;Com1OutQ&#41;&#41;
   Call OpenCom&#40;1, 19200, 0, Com1OutQ&#41;
   Call PutPin&#40;Pin.RedLED, 0&#41;
   
   Call PutQueueStr&#40;Com1OutQ, "via PutQueue"&#41;
   Call PutPin&#40;Pin.RedLED, 1&#41;
   Call PutPin&#40;Pin.GreenLED, 0&#41;
End Sub
If ConsoleSpeed is zero, the red LED flashes as the machine is repeatedly reset when PutQueueStr is called. If set to 19200, the code succeeds and the green LED is lit.

Do I misunderstand ConsoleSpeed 0?

Posted: 23 April 2013, 20:02 PM
by dkinzer
GTBecker wrote:With Option ConsoleSpeed 0, on a -24x, opening Com1 to 19200 appears to work, but a subsequent PutQueueStr to Com1 resets the machine.
In this specific case, the ZBasic compiler is not emitting the code necessary to include the ISRs for Com1. Consequently, when data is put in the queue and an interrupt is thus generated the device resets.

You can work around the issue by adding the code below to your Main() subroutine, before any code or data declarations.

Code: Select all

#c
   ZB_REQUEST_SYM&#40;zb_com1_ISR&#41;;
#endc
I believe that we have located the source of the problem and identified a solution. We'll post an update to the compiler when testing has been completed.

Posted: 23 April 2013, 22:35 PM
by GTBecker
Thanks, Don. Both remedies work.

Posted: 26 April 2013, 11:36 AM
by dkinzer
dkinzer wrote:We'll post an update to the compiler when testing has been completed.
Now available as v4.1.6 on the Downloads Page. The update is not yet in the installer so download the .zip file and extract the executable to the ZBasic installation directory, copying or renaming the existing ZBasic.exe first if a backup is desired.

Posted: 23 May 2013, 15:43 PM
by jay
I've been having a somewhat similar problem, except, I'm running with the generic license on a AtMega328P and using just debug.print... it is a slightly modified version of Don's "Hello, world" example he posted to me 14 December 2008 in the zx-1281 topic.

While trying to understand my problem, I found that with "SignOn ON" and the CallTask cmdTask, taskStack commented out, getDeviceID() returns 0f0f0f0f. Running the Calltask, getDeviceID() returns 1e950f (correct device). When SignOn is OFF, getDeviceID() workes correctly with or without the Calltask. I also found at times, when SignOn had never been specified (on a new device), letting CallTask (ZXCmdMode) run, would not allow the program to start from power up. I had to download the application to restart. I tried with v4.1.7 compiler, Signon displays ZBasic v4.1.3 ..

Also, verified the ZB_REQUEST_SYM and StatusCom(!) do loop mentioned previously had no effect.

It appears SignOn Off solves all the issues.

Regards,

..jay

Modified code...

Code: Select all

Option TargetDevice ATMega328P
Option DeviceParameter package "PDIP-28"
Option DeviceParameter clockFrequency 14745600
Option ConsoleSpeed 57600
Option DeviceParameter rtcFrequency 512
Option DeviceParameter rtcScale 2
Option DeviceParameter swUartDivisor 64
Option DeviceParameter swUartMinSpeed 300
Option DeviceParameter swUartMaxSpeed 19200
Option DeviceParameter swUartBaseSpeed 0
Option DeviceParameter timerSpeed1Divisor 1
Option DeviceParameter timerSpeed2Divisor 8
Option DeviceParameter ZBasicBootloader true
Option SignOn Off

#define RedLed = D.2
#define GreenLed = D.3

Private msg as StringVectorData&#40;&#123; " says...", "    Hello, world" &#125;&#41;
Private device as String

Private Const cmdChar as Byte = &H04

Private Const stackSize as Integer = 200

Private taskStack&#40;1 to stackSize&#41; as Byte

Sub Main&#40;&#41;
    Dim j as Integer

    ' launch the ATN detection task
    CallTask cmdTask, taskStack

    ' get the device identification string
    device = getDeviceID&#40;&#41;

    ' loop forever displaying the hello world message
    j = 1
    Do
        Call Hello&#40;j&#41;
    Loop

End Sub

'
'' Hello
'
' This subroutine displays one of two strings depending on the
' passed index &#40;of which only the least significant bit is used&#41;.
'
Private Sub Hello&#40;ByRef idx as Integer&#41;
    ' advance the string index and limit its value
    idx = &#40;idx + 1&#41; And 1

    ' display the indexed string, for string 0, add the device identifier prefix
    If &#40;idx = 0&#41; Then
        Debug.Print device;
    End if
    Debug.Print msg&#40;idx + 1&#41;

#if defined&#40;RedLED&#41; And defined&#40;GreenLED&#41;
    ' for devices with LEDs, flash the red and green LEDs for a half second each
    Call PutPin&#40;RedLED, zxOutputLow&#41;
    Call Delay&#40;0.25&#41;
    Call PutPin&#40;RedLED, zxOutputHigh&#41;
    Call PutPin&#40;GreenLED, zxOutputLow&#41;
    Call Delay&#40;0.25&#41;
    Call PutPin&#40;GreenLED, zxOutputHigh&#41;
#else
    ' for devices without LEDs, simply delay for a second
    Call Delay&#40;1.0&#41;
#endif
End Sub

'
'' getDeviceID
'
' Retrieve the device identifer and return it as a string.
'
Private Function getDeviceID&#40;&#41; as String
    Dim idLen as Integer
    Dim i as Integer
    Dim id&#40;1 to 10&#41; as Byte

    ' note that the 'id' array will be null terminated
    Call System.DeviceID&#40;id&#41;

    ' determine the length of the identification string
    idLen = 0
    For i = 1 to UBound&#40;id&#41;
        If &#40;id&#40;i&#41; = 0&#41; Then
            Exit For
        End If
        idLen = idLen + 1
    Next i

    ' create a string containing the identification string
    getDeviceID = MakeString&#40;id.DataAddress, idLen&#41;
End Function

'
'' cmdTask
'
' The sole purpose of this task is to check the input queue for the ATN
' character and, when found, invoke the ZX command mode.
'
Sub cmdTask&#40;&#41;
    Do
        If &#40;StatusQueue&#40;CByteArray&#40;Register.RxQueue&#41;&#41;&#41; Then
            Dim c as Byte
            Call GetQueue&#40;CByteArray&#40;Register.RxQueue&#41;, c, 1&#41;
            If &#40;c = cmdChar&#41; Then
                Call ZXCmdMode&#40;&#41;  ' 
            End If
        End If
        Call Sleep&#40;0&#41;
    Loop
End Sub