Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Super IO Chip programming in C

Status
Not open for further replies.

modest16081982

Programmer
Jan 17, 2007
6
US
Hello,

Can anyone help me in getting started with Super IO chip programming? Baiscally, I have a Super IO SMSC chip and I wanted to test particular Pins on that Chip and find out if those Pins can be used as Input or Output or not? Right now those Pins are not connected (or doing) to anything?
I was told by someone that I can do this in C language. Also I have the datasheet for this Super IO programming.

I have done lots of C programming but not related to Hardware. Does anyone has any sort of prior experience related to this kind of question?

Your help will be greatly appreciated.

Thanks
 
Also, is it memory mapped or I/O mapped? If it is memory mapped, are the ports at word intervals in the memory?
 
It is an AMD Geode LX-800 platform. I intend to develop the C program executable for DOS (16 bit) system from my workstation and then transfer it to LX machine with DOS installed on it. It is a IO mapped.

I have the datasheet for the Super IO chip also with me. I also know register address where I need to input the Data and I know the address from where to read the output.

I only have this much information. How do I start from here? I mean from scratch.

Thank you guys for your quick response.
 
I assume you'll be working in 16 bits. Say the chip is mapped to address B000:0. Most compilers have a macro of some sort to convert this to an address. So you'll have something like
Code:
volatile unsigned short* theChip = MAKEPTR (0xB000, 0);
You'll have to check with your compiler to see what macros they have to create pointers. Declare it as volatile as it can change outside program control.

Say the registers are TOM, DICK and HARRY at 0xB000:0, 0xB000:2 and 0xB000:4. One way of doing it is using enums.
Code:
enum CHIPREG { TOM = 0, DICK, HARRY };
Note that because theChip has been defined as unsigned short, it goes in steps of 2 bytes. If it were unsigned char, it would be in steps of 1 and if it were unsigned long, it would be in steps of 4.

Say to do something you need to put 0xBAAD in TOM and 0xBEEF in HARRRY with a small delay in between
Code:
theChip[TOM] = 0xBAAD;
dummyDelay = dummyDelay / 2;
theChip[HARRY] = 0xBEEF;
That is about as complicated as it gets. If you change the location of the superchip then all you need to do is change the initial address.
 
Try early Borland C++ 3.00 or similar. There were function calls for port IO (inportb(), outportb(), etc.), for BIOS interrupts and functions, also keyword interrupt allowing hardware interrupt processing inside of user application.
 
Sorry I misread it - it was IO mapped: not memory mapped. The inport range of instructions is actually quite inefficient. It is possible to miss cycles if they are not inlined or are actually implemented as a subroutine with a push, pop and return. You might be better off using the assembler version if there is such an option.
Code:
unsigned short value;
__asm {
   mov DX, SUPERCHIP
   in AX, DX
   move value,AX
}
If SUPERCHIP is in the range 0-255, you can just use in AX,SUPERCHIP
 
xwb, thank you very much. I really appreciate all your help. Sorry to bother you again, but I have couple of further questions.

Question 1:
When you asked about whether the chip is IO mapped or Memory mapped, I think I was sure but now I am not. Although here is the link for the Chipset Datasheet.


How can we tell from this whether it is IO mapped or Memory Mapped.

Question 2:
The good news is that I have some further piece of information. The chip is mapped at C000:0 and so my Address and Data Register are at C70 & C71 and I need to do the following:
a)Write 10h to C70
b) And get the output from C71

Question 3:
Also, is there any basic resource from where I can learn the basic of this kind of programming in C. Suppose if I want to look at some examples on google related to this, what should I search for?

Would really appreciate if you can help me out.

Thanks
 
Q1 - Can't really tell from the DataSheet - I'm not a hardware engineer. I think you can have it both as ports and registers.

Q2 - You didn't say whether 0c70 and 0c71 were 8 bit or 16 bit ports. Assuming they are 16 bit ports, in assembler it is something like
Code:
mov DX,0C70H
out DX,10H
mov DX,0C71H
in  AX,DX
mov result, AX
In C, it would be something like
Code:
outw (0xc70, 0x10);
result = inw (0xc71);
Depends on the I/O instructions: you have to check your compiler.

Q3: Don't know of any books. I learnt most of the stuff over the years.
 
xwb:
> The inport range of instructions is actually quite inefficient. It is possible to miss cycles

Are you sure? Are in/out instructions somehow slower than usual memory access in case of memory mapped registers? I suppose, data loss could appear in both cases, when data processing routines are too slow. I see the only difference - memory mapped devices don't need in/out instructions to be ported to C or digging into inline asm includes - registers could probably be programmed directly from C using ordinary pointers?

modest16081982:
> Also, is there any basic resource from where I can learn the basic of this kind of programming in C.

I'm currently quite far from the topic, but I don't think there is a big logical difference, do it in C or in asm. Device programming consists of reading/writing of ports/registers, setting/checking bits in control registers, processing interrupts, etc. Read something general about device programming. The only difference between C and asm is the speed.
 
mingis I meant the inportb, inportw as implemented by vendors: not the in/inw in assembler. I have had timing issues in the past when I used them but I've never had timing issues in assembler. Can get quite bad when you're playing with interrupts.
 
In the dear dead days beyond recall of the ISA bus, I/O used to add wait states.

I don't know what the PCI bus does about this.

I noticed in the datasheet that the interface seems to be I/O mapped and not memory mapped.
 
Don't know anything about this particular application, but (1) Some chips can't process ins and outs as fast as the processor can execute them. So sometimes you need to send an "out" to tell a chip what you want it to do, wait a short time, and then use an "in" to find out what the chip said; (2) "in" and "out" are very slow instructions compared to memory access; this doesn't matter normally, but was (is?) a big issue for high-performance graphics low-level code.

Someone mentioned hardware interrupts and writing interrupt handlers in ancient Borland C++ using the interrupt keyword. My experience of this is in Borland Pascal for DOS, but the situation is the same: Remember that typical C and C++ uses a great deal of stack space, but hardware interrupt handlers can be called at any time; even when your program has called something in DOS (for instance you're reading the keyboard). (a) you can't call most bits of DOS again from within DOS (not reentrant), so your interrupt handler must not use any instruction likely to call any one of a huge range of DOS things. And (b) when the processor is doing something in DOS, there is no certainty about how big the stack is; it may have been changed to one of DOS's internal stacks, which are sometimes ridiculously small. So your code must be very careful about local variables, calls to other things, and anything that uses stack.
 
Hello Guys,

I appreciate all your efforts. Can anyone give me a sample piece of code for the following:

The chip is mapped at address 0xC000:0 and so my Address and Data Register are at C70 & C71 (I calculated this from manual) and I need to do the following then:
a)Write 10h to C70
b)And get (read) the output from C71

I would really appreciate if some can give me a sample code along with special variables that are required. Also a similar program which does almost the same thing would also do.

Thank you once again.
 
If it is memory mapped and that these are 8 bit ports
Code:
unsigned char* theChip = (unsigned char*) mkptr (0xc000,0);
const unsigned int ADDR = 0xC70;
const unsigned int DATA = 0xC71;
unsigned char result;

theChip[ADDR] = (unsigned char) 0x10;
result = theChip[DATA];
 
No, as mentioned before, it is an IO mapped with 8 bit ports.

Thanks again for the help.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top