Page 1 of 1

Zx 1280 - Reading value from I/O Ports

Posted: 24 January 2009, 1:02 AM
by angad
Hi,
I am using zx 1280 for a time critical medical device. I need to communicate with different MCUs connected to zx using the I/O ports (PORTA through PORT J). Since its a time sensitive system, I need read a set a six bytes from the I/O port (say PORTA) in a sequential fashion within 1 micro second. The MCU that sends these values is in synch with zx.

The problem that I am facing is, in order to read the value from a port I could find instructions that read a single bit (eg: get pin)

I need some function that can fetch a port value directly into a byte variable.

I tried the following statement, but I could nt ready the value

Option PortB "PPPPPPPP"
.
.
.
Dim var as byte = 0
byte = Register.PortB
.
.
.
This dint work out, but instead I did the following and it worked at the expense of extra time

for i = 0 to 7
if(getpin(porta(i))=1) then
call putpin(portf(i),1)
else
call putpin(portf(i),0)
next

byte = Register.PortF

This loop is consuming a lot of additional time. I have worked on several other controllers and even the simpler ones that belong to 8051 family have simple statements that let us read a byte from the port

Appreciate all your help !


Thank You.

Zx 1280 - Reading value from I/O Ports

Posted: 24 January 2009, 5:46 AM
by GTBecker
> ... byte = Register.PortB

Try Register.PinB, but you'll not be able to meet your 6bytes/uS
criterion unless you use an external FIFO cache and the data is in
bursts that allow sufficient time to empty the FIFO and process that data.


Tom

Re: Zx 1280 - Reading value from I/O Ports

Posted: 24 January 2009, 7:30 AM
by mikep
You need to read the mega1280 datasheet to correctly use the port registers. See table 37 on page 84. For inputs you set the DDRx register (e.g. DDRB) to 0 and the PORTx register controls whether you tristate or use pullups. This is the same as using "Option Portx" as you have done.

To read the port value, use the PINx register as Tom recommends.

I think that it will be extremely difficult to get the timing you want with the ZX-1280 because of the extra work done by the virtual machine. In most applications this is not an issue, but in your time-sensitive application you are probably better off with a ZX-1280n where the ZBasic code is compiled to AVR machine code.

Zx 1280 - Reading value from I/O Ports

Posted: 24 January 2009, 8:04 AM
by GTBecker
> ... probably better off with a ZX-1280n where the ZBasic code is
compiled to AVR machine code.

Still, it's likely to be difficult to get six reads with handshaking in
one uS, isn't it?

Tom

Re: Zx 1280 - Reading value from I/O Ports

Posted: 24 January 2009, 8:20 AM
by mikep
GTBecker wrote:Still, it's likely to be difficult to get six reads with handshaking in
one uS, isn't it?
At a clock speed of 14.7456 MHz, each instruction cycle takes 67.8ns. Therefore in 1 microsecond the AVR can execute just less than 15 cycles. This gives just enough time to read the 6 I/O registers and loop back to do it over.

So yes, this isn't enough time to do anything with the data. Even if the AVR runs at 20MHz, its maximum speed, there still isn't much time to do anything. Options are:
1. Decrease the frequency of I/O reads to something like 5us
2. Get a different microcontroller that is faster
3. Use some other kind of technology that can process data @ 6 Mbyte/sec or faster such as a FPGA.

Re: Zx 1280 - Reading value from I/O Ports

Posted: 24 January 2009, 11:25 AM
by mikep
angad wrote:I am using zx 1280 for a time critical medical device. I need to communicate with different MCUs connected to zx using the I/O ports (PORTA through PORT J). Since its a time sensitive system, I need read a set a six bytes from the I/O port (say PORTA) in a sequential fashion within 1 micro second. The MCU that sends these values is in synch with zx.
Perhaps you can explain your problem in more detail so we can help with possible solutions. There is already a MCU sending 6 bytes of parallel data. Is this data simply redistributed to the other MCUs? So why not use some discrete logic or a CPLD for this? How often is the data changing? Is it really changing every microsecond?

Perhaps you could image how you would do this with a 8051 that had more I/O? Then we could extrapolate that to the mega1280 which does have all the I/O you need.

RE

Posted: 24 January 2009, 21:27 PM
by angad
@ Tom and Mike

Thanks for the very prompt update !

Mike, I think you are right about DDRx registers. I checked the datasheet, shall implement this thing and get back if i find success.

Right now, I do not have the code, shall get back with code from my lab on monday !

The Zx continuously polls for values from the host on port b. When it receives all six values it just port this the corresponding MCUs. The data is differentiated by reading 3 bit status pins.

For now, I need to know if its possible to read the port value as a byte directly when DDR is configured

eg: Dim variable as byte = 0
variable = register.portB

I do not want to waste time by reading 8 pins of port B individually.

I too feel 1 us is a very short duration for 6 reading values.


Once again, thanks for the update, Appreciate it !

Regards,
Angad

Re: RE

Posted: 24 January 2009, 21:47 PM
by dkinzer
angad wrote:I think you are right about DDRx registers. I checked the datasheet, shall implement this thing and get back if i find success.
In your original post, you indicated that you were using

Code: Select all

Option PortB "PPPPPPPP"
This has the same effect as the following two lines:

Code: Select all

Register.DDRB = 0     ' set all Port B pins to inputs
Register.PORTB = &Hff ' enable pullup resistors on all Port B pins
Once this is done (by either method), the values being applied to the Port B pins can be read using Register.PinB as others have indicated.

Posted: 25 January 2009, 0:10 AM
by angad
@dkinzer

Thanks for the update ! My only concern is reading values of all the pins on any I/O port using a single instruction from zbasic library. I feel its not worth reading each bit and then writing these 8 bits into a byte variable.

Can anyone suggest on this !

Regards,
angad

Zx 1280 - Reading value from I/O Ports

Posted: 25 January 2009, 4:46 AM
by GTBecker
> ... variable = register.portB

I'm sure you've read these responses incorrectly three times now.

Not Register.PORTB.  Register.PINB will read all eight pins simultaneously.



Tom

Posted: 25 January 2009, 7:37 AM
by dkinzer
angad wrote:I feel its not worth reading each bit and then writing these 8 bits into a byte variable.
Nor is it necessary. It can be done simply by reading the correct register. Assuming that the I/O pins are already set to be inputs (using either of the methods described in an earlier post) you simply use

Code: Select all

portVal = Register.PinB
You won't get what you intended if you use either Register.PortB or Register.DDRB instead. Each of the three registers associated with an I/O port has a specific purpose. The datasheet for any AVR device describes the basic functionality of each of these registers. There are some minor differences with the newer AVR models (e.g. the effect of writing to PINx) but the fundamentals are the same.

Posted: 25 January 2009, 15:28 PM
by angad
@Tom and Dkinzer

You are right, I misinterpreted the thing because the command had PIN in it.
Thanks for correcting me.



Thanks for your patience!