Sunday, 20 May 2012
 
 
A+ | A- | Reset
Forums Microcontrollers AVR How to address I/O pins by pin number? (0 viewing) 
Go to bottom Post Reply
TOPIC: How to address I/O pins by pin number?
#79
spamiam
Posts: 33
graphgraph
User Offline
How to address I/O pins by pin number? 4 Years, 6 Months ago  
I am trying to think of a simple way to address I/O pins by the OM128 pin number.

Normally one would simply (for example) use DDRE or PINE, or PORTE. THen maybe AND or OR it with a bit number.

But how do do this by pin number (e.g. pin 13).

I thought of having a big look-up table 40 entries with 4 items per entry (PORT,PIN,DDR, and BIT). This look-up table is relatively big (160 bytes), but it probably could be stored in progmem.

Is this the simplest way to do it?

BTW, there are 2 issues. One is converting the macro DDRE to a memory location like 0x38. The other is then converting the value 0x38 back to the memory location.

I bet this has been solved for the VM of the ZX series, but I am not sure if there is an official "Oak Micros" suggested easiest or best technique.

-Tony
  The administrator has disabled public write access.
#83
Mike
Posts: 82
graph
User Online Now
Re:How to address I/O pins by pin number? 4 Years, 6 Months ago  
For the ZBasic VM there is clearly a function that converts the pin number to registers. And if you use the notation "B.3", the compiler converts it to the appropriate pin number for the device. However pin numbers are problematic because pin 13 can do different things on different ZX devices. The same is true for AVR devices of course.

The real question here is what is the problem you are trying to solve? Is it device independence or something else.

In the Oak Micros examples and particularly omdevice.h, I use #defines for pins which are defined depending on the device. For example the red LED is defined as follows:
Code:

 /* defines for LEDs for Oak Micros devices */ #if defined(__AVR_ATmega32__) || defined(__AVR_ATmega644__)     /* Use port D for 44 pin devices */     #define PROGLED_PORT    PORTD     #define PROGLED_DDR     DDRD     #define PROGLED_RED     PD7     #define PROGLED_GREEN   PD5 #elif  defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__)     /* Use port E for 64 pin devices */     #define PROGLED_PORT    PORTE     #define PROGLED_DDR     DDRE     #define PROGLED_RED     PE7     #define PROGLED_GREEN   PE5 #else     #error "no LED definition for MCU" #endif

  The administrator has disabled public write access.
#85
spamiam
Posts: 33
graphgraph
User Offline
Re:How to address I/O pins by pin number? 4 Years, 6 Months ago  
The problem I am trying to solve is the desire to avoid having to know/remember anything about port and bit numbering as it relates to physical pins on the OM device. Especially since it is liable to change from device to device as time goes on.

While the user will still have to handle the PORT, DDR, and PIN functions, I want them not to have to deal with _which_ port, etc it is, and only know that it has DDR, etc that needs to be manipulated.

I hope I explained the rationale well enough. The bottom line is that I would like to be able to get down to something very ZX-like in manipulating the pins. Eventually having something as clear as PutPin(PinNum,Function);
where function is INPUT_TRISTATE,INPUT_HIGH, OUTPUT_HIGH, OUTPUT_LOW.
And the matching code of GetPin(PinNum); These may be able to expand to macros and a lookup table, or to a subroutine call plus macros and a lookup table.

What I see is something initially like this (written off the top of my head, so it is not going to work as is):

In a header there will be this:
Code:

 #IFDEF (__atmega128__)//maybe this would be better checking for an OM128      #DEFINE OM_PORTE = 0x38;  //an example of a memory mapped port location      #DEFINE OM_DDRE = 0x39;      #DEFINE OM_PINE = 0x40;      //other similar defines for all other port combinations #ENDIF



Then somewhere (a header?) will be this:

Code:

 //entries are PORT,DDR,PIN,BIT #DEFINE PORT = 0 #DEFINE DDR = 1 #DEFINE PIN = 2 #DEFINE BIT = 3 unsigned char pin_table[] = { 0,0,0,0,//pin1  zeros signify an illegal I/O pin 0,0,0,0,//pin2 0,0,0,0,//pin3 0,0,0,0,//pin4 OM_PORTE,OM_DDRE,OM_PINE,(

  The administrator has disabled public write access.
#86
spamiam
Posts: 33
graphgraph
User Offline
Re:How to address I/O pins by pin number? 4 Years, 6 Months ago  
DRAT my post got cut off somehow! I will summarize the missing text....

the rest of that code window was supposed to look like:
OM_PORTE, OM_DDRE,OM_PINE, (1WPIN_BIT);

s to simplify it further, to

PutPin(PinNum,Function);

This would check the function code and then expand to 2 lines setting the respective DDR and PORT bits

I have to review how to write a multi-step macro....

-Tony

P.S. The forum software keeps cutting off my code. I think it does not like the double less than sign used as a "shift". I will stop re-writing the code. Unfortunately, my examples are all messed up.
 
Last Edit: 2007/11/15 12:17 By spamiam.
  The administrator has disabled public write access.
#94
spamiam
Posts: 33
graphgraph
User Offline
Re:How to address I/O pins by pin number? 4 Years, 6 Months ago  
Here is some code that works pretty well to create a"PutPin" method of accessing physical I/O pins.

It uses a cumbersome look-up table, which is "slow" (37 ASM instructions?) but it works.

It is not fully featured yet, and only has the first 6 pins specified. It was a test of the technique.

Comments?

-Tony

P.S. The BAK files are some attempts to make a faster almost purely macro-based version.
File Attachment:
File Name: Pin_Functions.zip
File Size: 5733
  The administrator has disabled public write access.
#100
Mike
Posts: 82
graph
User Online Now
Re:How to address I/O pins by pin number? 4 Years, 6 Months ago  
I have several comments and then some code for you.

The macro approach only really works if you use constants for the pin numbers. If you need to uuse variables then you will need functions to access the ports.

At this time the om128 does not really support ports A, C, and G. You can write to these ports but they will affect the extended RAM. This means you only need to define pin numbers for 5 through 36 (or 1 through 40 if you prefer).

The Studio makefile does not contain invoke avr-objcopy to create the lss file so I prefer to use the standard WinAVR generated Makefile.

I have been reading the thread you started on avrfreaks and the best implementation that meets the requirements is the one suggested by cpluscon.

I have take his idea and implemented complete GetPin and PutPin functions as given in the attachment. The GetPin function is 48 bytes and PutPin is 132. I have written a small test program and this code seems to work quite well.
File Attachment:
File Name: om128_pin_numbers.zip
File Size: 8256
  The administrator has disabled public write access.
Go to top Post Reply
All Content Copyright 2005-2011 Oak Micros. All Rights Reserved. See Terms and Conditions.
Powered by Joomla and osCommerce.