Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
BX-24 code conversion
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Forum Index -> ZX-24
Author Message
DH*
Guest





Posted: 06 January 2006, 18:44 PM    Post subject: BX-24 code conversion Reply with quote

I have a BX-24 application which exhausted the limits of that platform. It looks like the ZX-24 expands the limits just enough to allow me to add a few features I had wanted but could not shoehorn into a BX-24.

I make use of the BX-24 registers. Will the following code snippet work with the ZX-24?
Code:

  Dim PulseTrain(0 To 32)  As Integer
  Dim n                    As Integer
  Dim bit                  As Byte

  For n = 0 To 32 
    Register.TCCR1A = 0                     'reset Timer1
    Register.TCNT1H = 0
    Register.TCNT1L = 0
    Register.TIFR = TOV1
    Register.TCCR1B = 2                     'start Timer1
    Call WaitForInterrupt(bxPinRisingEdge)
    LoByte = Register.TCNT1L                'read Timer1
    HiByte = Register.TCNT1H
    PulseTrain(n) = CInt(HiByte) * 256 + CInt(LoByte)
  Next
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 06 January 2006, 23:18 PM    Post subject: Reply with quote

As written, it won't compile in either BasicX or ZBasic because TOV1 is undefined as are LoByte and HiByte. If you add these, you'll get a warning that the definitions of LoByte and HiByte hide system functions by the same name. This can be avoided if you use BasicX compatibility mode (add 'Option Language BasicX' at the beginning of the module).

Note, however, that since the CPU is running twice as fast, the counter also runs twice as fast. The effect will be that the counts will be twice as high as when run on the BX-24 using the same input signal.

The other thing that I would point out is that using the code shown will not provide accurate measurement of timing from rising edge to rising edge. If you need more accuracy you can use InputCapture() and set Register.TimerSpeed1 to 2 to get divide-by-8 resolution. Then, you'll have to allocate an array twice as large since InputCapture() stores the high time and low time separately. You can add the low time and high time together to get the cycle time.
Back to top
DH*
Guest





Posted: 07 January 2006, 0:16 AM    Post subject: Reply with quote

Gee, a few hundred people have been running it for a few years on a BX-24. TOV1 is a constant defined elsewhere. I did say it was a snippet.

I did it this way precisely because InputCapture required twice as much memory.

I also disagree about the accuracy. At least on the BX-24 the accuracy was as good as InputCapture. Anyway, since a 1 is 2.2mS and a 0 is 1.1mS, µS accuracy is not of great importance.

My question, which you did not answer, was more about whether the register definitions will work.
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 07 January 2006, 0:58 AM    Post subject: Reply with quote

Quote:
My question, which you did not answer, was more about whether the register definitions will work.


My apologies; I should have been more explicit. From Section 3.8.1 of the ZBasic Reference Manual:

Quote:
Because the ZX microcontrollers are implemented using a more powerful CPU, some registers available in BasicX don’t actually exist on the ZX CPU but there are equivalent registers. For compatibility, both the original register name and the actual register name are supported. For new applications, the new register names should be used.


It is possible that the function of a certain bit in a given register is not the same on both the mega8535 (on which the BX-24P is based) and the mega32 (on which the ZX-24 is based). I have not yet done an exhaustive comparison to be able to say for certain. In this particular case, however, the bits that you are using in the registers that you use are identical.

If you'd like, I can explain why I claim that InputCapture() is more accurate. Of course, if you are satisfied with the accuracy that you're getting or you need to reduce the RAM use then it doesn't matter.
Back to top
DH*
Guest





Posted: 07 January 2006, 21:37 PM    Post subject: Reply with quote

I also use the BasicX code below to make sure all the bytes have been sent before reversing a half-duplex RS485 line.

Sub FlushCom3()

Do While StatusQueue(OutCom_3)
Loop
Do While ((RAMpeek(21) And &H40) = &H40)
Loop

End Sub

Is there a way to do this in ZBasic?
Back to top
mikep



Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX

Posted: 08 January 2006, 0:26 AM    Post subject: Reply with quote

What does peeking at address 21 with RAMPeek(21) do? This looks like R21 which means you are making use of some undocumented function in BasicX. What am I missing here?

Is it sufficient for you to check that the queue is empty? If not then perhaps you might be able to check the USART status registers on the ATmega32.


Last edited by mikep on 08 January 2006, 2:01 AM; edited 2 times in total
Back to top
DH*
Guest





Posted: 08 January 2006, 1:08 AM    Post subject: Reply with quote

It's not sufficient in BasicX to check the queue. Frank Manning supplied the code (and some for COM1) either in their forums or in their application notes.

Checking the USART registers won't help with a software UART.
Back to top
mikep



Joined: 24 Sep 2005
Posts: 765
Location: Austin, TX

Posted: 08 January 2006, 2:06 AM    Post subject: Reply with quote

It sounds like you are making use of some undocumented feature of BasicX that Frank Manning told you about.

I'm sure Don knows the answer to this but I would assume that if the queue for a software UART is empty then all the bytes have been sent. My guess is that the byte is not taken off the queue until after it is sent on the COM channel.
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 08 January 2006, 3:30 AM    Post subject: Reply with quote

That won't work. ZBasic does not implement the undocumented features nor the internal structures of BasicX, i.e. it is not a BasicX clone. In the ZBasic Reference Manual in the section on compatibility it states, in part:

Quote:
The system-level details of ZBasic are likely to be different than those of BasicX. For example, the system information related to routine invocation, tasks, queues, etc. is probably not the same as that of BasicX so if your program relies on such information it is likely not to work correctly.


However, all is not lost. There is a special function to determine the status of a com port that should provide the functionality that you need without being dependent on internal implementation details. See StatusCom for the details.
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 08 January 2006, 6:35 AM    Post subject: Reply with quote

This should accomplish the same objective and will work for any comm channel.

Code:
Sub FlushCom(ByVal chan as Byte)
   Do While (CBool(StatusCom(chan) And &H04))
   Loop
End Sub
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 08 January 2006, 6:39 AM    Post subject: Reply with quote

Quote:
I would assume that if the queue for a software UART is empty then all the bytes have been sent.


This is not a safe assumption since a byte may be in the midst of being transmitted. If you waited until the queue was empty and then delayed for 10 bit times then it would be safe.

The StatusCom() routine was designed to avoid having to implement this logic and also to avoid having to use undocumented internal data.
Back to top
DH*
Guest





Posted: 09 January 2006, 21:08 PM    Post subject: Reply with quote

Since this specific case is for half duplex RS485, can I save some RAM by using one queue for tx & rx?
Back to top
DH*
Guest





Posted: 09 January 2006, 21:09 PM    Post subject: Reply with quote

Since this specific case is for half duplex RS485, can I save some RAM by using one queue for tx & rx?
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 09 January 2006, 21:34 PM    Post subject: Reply with quote

It will not work to specify the same queue for transmission and reception contemporaneously. The transmitter section will send any byte that it finds in the transmit queue. It can't distinguish between one added by user code and one added by the receiver section.

The only way to safely use the same queue for input and output is to open the port as transmit-only (specify the Rx queue as 0) send the data, close the port and re-open it as receive-only (specify the Tx queue as 0) and receive the data. Depending on the timing in your application, this may not be useful.
Back to top
DH*
Guest





Posted: 10 January 2006, 22:34 PM    Post subject: Reply with quote

What about using one pin for both tx & rx? Will this be a problem?
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZX-24 Time synchro. with the server - Timezone/DST with your computer
Goto page 1, 2  Next
Page 1 of 2

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group