Menu (English) | | | Linux & Asm x86-32 | | | PIC microchip | | | Debian Packages | | | Links | | | Javastation Sun | | | Weblog | | | About |
Menu (Nederlands) | | | Linux & Asm x86-32 | | | PIC microchip | | | Tux maakt koffie | | | Links | | | | | Weblog | | | Over |
Dit kan je natuurlijk op verschillende manieren doen. Het grootste probleem is natuurlijk dat het niet altijd evident is om kabels van de PC naar de koffiemachine (of eenders welk ander elektrisch toestel) te trekken. Daarom ben ik op zoek gegaan naar een draadloze manier om dit te verwezelijken. PHILIPS verkoopt draadloze afstands-schakelsystemen. Deze bestaan uit een draadloze zender die een of meedere apparaten kan bedienen. Hiervoor wordt gebruik gemaakt van een draadloze ontvanger die in het stopkontakt wordt gestoken. |
Deze afstandsbediening is vrij eenvoudig aan te passen, zodat je hem kan aansluiten op de PC. Het enige wat je daarvoor nodig hebt is een ULN2803. Ikzelf heb die afstandsbediening zo aangesloten op een IO-kaartje dat in mijn PC aanwezig is, maar het zou ook via de printerpoort moeten werken. |
||
Om uiteindelijk de afstandsbediening aan te sturen dien je de gepaste waarde naar de IO-poort (of printerpoort) te sturen. Onder GNU/Linux kan je dit bv. doen met hetvolgende C-programma, dat ik vroeger eens als voorbeeld heb ontvangen (LINUX.B fidonet).
= Deze bewaar ik : Linux ===============================================KeepIt= Msg : 30 [1-87] Rcv From : Pros Robaer 27-May-97 20:22:14 2:292/8013.4 To : Jan Wagemakers 2:292/8133 Subj : Linux & Assembler =====================================================================REM_LINUX= * Copied from: LINUX.B Hallo Jan, Op Sun, 25 May 97 08:29:28 +0200 schreef je naar Pros Robaer: PR>> BTW: als je (zoals elke rechtgeaarde bitneuker) met je parallelle PR>> poort of iets dergelijks wil gaan prossen, vergeet dan niet om eerst PR>> netjes toestemming te vragen [ioperm()], of je programma vliegt er PR>> uit... JW> Whue, dat is voorlopig nog chinees voor mij ;-) Net zo min als je geheugen mag gebruiken, dat niet aan jouw programma is toegewezen door het OS, mag je geen I/O-poorten gebruiken, zonder het eerst te vragen. Doe je het toch, dan werpt het OS je programma er uit vanwege een "Segmentation Fault"... Daarmee ben je nog niet klaar. Als "normale" user zal je geen toestemming krijgen om zo'n programma uit te voeren. Remedie: ofwel log je in als root, ofwel zet je het UID-bit v/h prog. Zo: chown root.root poorttest chmod 4755 poorttest JW> En nu we er toch over bezig zijn, ik heb in mijn kompjoeter een zelfgebouwd JW> (elektuur) I/O-kaartje zitten. Onder dos kan ik dan BV. Ledjes laten JW> oplichten door : - mov dx,0310h JW> - out dx,al JW> Enig idee of dit ook onder Linux gaat? Dit zou moeten werken: ----BEGIN-C-SOURCE---poorttest-------------------------------------- /* * poorttest * * schrijf iets naar poort 0x310 */ #include <stdio.h> #include <stdlib.h> #define INLINE inline #include <unistd.h> unsigned short poort = 0x310; int byte; static INLINE void outb (short port, char val) { __asm__ volatile ("out%B0 %0,%1"::"a" (val), "d" (port)); } /* * voor het geval je een poort wil lezen. * gebruik: byte = inb (het-adres-van-de-poort); */ static INLINE unsigned char inb (short port) { unsigned int ret; __asm__ volatile ("in%B0 %1,%0":"=a" (ret):"d" (port)); return ret; } int main (int argc, char *argv[]) { if (argc != 2) { printf (" Gebruik: %s <x>, waarbij x = 0...255\n", argv[0]); exit (2); } /* * als het programma meerdere malen naar dezelfde I/O-poort moet * schrijven, volstaat het 1 maal ioperm () aan te roepen. */ ioperm (poort, 1, 1); byte = atoi (&argv[1][0]); outb (poort, byte); } ----eind-C-SOURCE--------------------------------------------------- Plaats dit stuk potjeslatijn in een bestand (poorttest.c), en compileer het met de magische woorden: gcc -s -O3 -Wall -w -o poorttest poorttest.o Hierna zou een "./poorttest 123" de byte 123 naar I/O-adres 0x310 moeten schrijven. Meer info vindt je in 1 v/d mini-HOWTO's. Vriendelijke groeten vanwege Pros (die ook al eens graag een bitje neukt :) --- Sprot 1.0 #0001 * Origin: Rivendel (2:292/8013.4) =====================================================================REM_LINUX=
Omdat ik echter iemand ben die een voorliefde heeft voor assembler, heb ik dit C-Programma omgezet naar assembler (GNU as). Niet dat dit echte voordelen heeft, de koffie zal niet merkbaar sneller klaar zijn ;-)
Hieronder zie je de assembler versie.
=============================================================================== .globl main .type main,@function main: popl %ecx # Hoeveel argumenten? cmpl $0x2, %ecx # port nummer --> Steeds 2 argumenten nodig jne help # niet 2 --> geef help tekst popl %ecx # skip argument 1 (= bestandsnaam prog) movl $101, %eax # "ioperm" (system call = 101). movl $0x310, %ebx movl $1, %ecx movl $0x310, %edx int $0x80 # Vraag ioperm voor poort 0x310 popl %ecx # haal argument van stack : %ecx = nummer call atoi # konverteer string (nummer) naar byte (%dl) movl %edx, %eax # %al = nummer movw $0x310, %dx # port 310(hex) outb %al, %dx jmp stop help: movl $gebruik, %ecx movl $9, %edx call print movl (%esp), %ecx # ecx = argument 1 = naam programma movl $1, %edx lus: cmpb $0, (%ecx) je ok incl %edx incl %ecx jmp lus ok: popl %ecx call print movl $info, %ecx movl $26, %edx call print stop: movl $1, %eax # Exit movl $0, %ebx int $0x80 #------------------------------------------------------------------------------ print: # Druk een string af #------------------------------------------------------------------------------ # Ontvangt : %ecx = adres van de af te drukken string # %edx = lengte van de af te drukken string #------------------------------------------------------------------------------ movl $4, %eax # nummer van syscall 'write()' movl $1, %ebx # schrijf naar stdout int $0x80 # roep syscall aan ret #------------------------------------------------------------------------------ #------------------------------------------------------------------------------ atoi: # konverteer een string (0 ... 255) naar een getal. #------------------------------------------------------------------------------ # Ontvangt : %ecx = adres van de te konverteren string # Geef terug : %dl = het getal #------------------------------------------------------------------------------ xorl %eax, %eax xorl %ebx, %ebx movl %ecx, %edi incl %edi cmpb $0, (%edi) je l1 incl %edi cmpb $0, (%edi) je l2 l3: movb (%ecx), %dl subb $48, %dl movb $100, %al mulb %dl movl %eax, %ebx incl %ecx l2: movb (%ecx), %dl subb $48, %dl movb $10, %al mulb %dl incl %ecx l1: movb (%ecx), %dl subb $48, %dl addb %al, %dl addb %bl, %dl ret #------------------------------------------------------------------------------ .data gebruik: .ascii "Gebruik: " info: .ascii " <x>, waarbij x = 0...255\n" ===============================================================================
as port.s -o port.o ld port.o -e main -o port
Zo, dit was het dan. Nu ga ik rustig een taske koffie drinken ;-)
Meer informatie over het maken van koffie met je PC vind je op http://www.tldp.org/HOWTO/mini/Coffee.html