lunes, 8 de julio de 2019

Uso de Pizero con interrupciones en RISC OS es facil al final

 La verdad con todo lo que he leido, el manejo de interrucciones Pizero con raspbian
es complejo, con phyton igual

Despues de mucho estudiar, porque no hay informacion en BASIC de riscos,  y muchos experimentos llegue a este ejemplo funcional que con la int timer programada para interrumpir cada 1 ms, puede determinar cuantos pulsos se han recibido en 3 pines, 2 ,3, 4, pulsos que deben durar mas de 45 ms

Es mucho muy facil hacerlo mejor con BASIC, que viene integrado en RISC OS, a parte se pueden usar
los sprites, los fonts, y graficas, que en raspbian no se que tan facil sea programar.

Este ejemplo crea un modulo que queda en memoria, claro debes darle doble click o cargarlo con programacion en el mismo basic, checando los pines cada 1ms, cuando hay pulsos de mas de 45 ms, los cuenta y los pone en variables(memorias pues), y con un programa (interfase) en basic puedo leer estos valores.

En realidad quiza te cueste trabajo entender el uso, pero el assembler es buenisimo y funcional, quiza puedas entenderlo y usarlo para tus propositos, yo la verdad lo pongo aqui porque la NETA NETA me costo muchisimo usar las ints en basic, ya que NO HAY INFORMACION de PROGRAMACION DE INTERRUPCIONES USANDO EL RISC OS,o muy poca (solo pistas) por eso comparto este codigo.


4470 REM ===================================================================
      REM ESTRUCTURA DE MODULO
      REM CREACION DE MODULO
      REM MANEJO DE INTERRUPCION
      REM ESTE PROGRAMA CREA ARCHIVO Modulo QUE ES UN MODULO
      REM QUE SE EJECUTA CON DOBLE CLICK Y SE HACE RESIDENTE
      
      ON ERROR PRINT REPORT$+" at "+STR$(ERL) : END
      DIM code% 4096
      FOR pass% = 4 TO 7 STEP 3
        P%=0:O%=code%
        
        [ OPT pass%
        EQUD    0               ; Start-up code
        EQUD    initialise      ; Initialisation
        EQUD    finalise        ; Finalisation
        EQUD    0               ; Service call handler
        EQUD    module_title    ; 5 Module title
        EQUD    0               ; Module help
        EQUD    0               ; Help and command decoding table
        EQUD    0               ; SWI chunk base number
        EQUD    0               ; SWI handling code
        EQUD    0               ; 10 SWI decoding code
        EQUD    0               ; SWI decoding code
        EQUD    0               ; Messages file name
        EQUD    module_flags    ; 13 Module Flags
        
        .module_flags
        EQUD 1                 ;14
        
        .module_title
        EQUS    "Modulo"
        EQUB    0
        ALIGN                  ;len nombre mod
        ; ============================================================
        ;VARIABLES DE SALIDA BASIC, es como una tabla

        
        .ComprobarPin02 EQUD &00000004 ; 0100
        .ComprobarPin03 EQUD &00000008 ; 1000
        .ComprobarPin04 EQUD &00000010 ;10000
        
        .ConteoUnosPin02 EQUD &00000000 ;0*4+C Cuantas Eventos en Pin9 12
        .ConteoUnosPin03 EQUD &00000000 ;1*4+C Cuenta Cuantos pin10
        .ConteoUnosPin04 EQUD &00000000 ;2*4+C Cuenta Cuantos pin11
        
        .ConteoCerosPin02 EQUD &00000000 ;0*4+18 Cuantas Eventos en Pin9 24
        .ConteoCerosPin03 EQUD &00000000 ;1*4+18 Cuenta Cuantos pin10
        .ConteoCerosPin04 EQUD &00000000 ;2*4+18 Cuenta Cuantos pin11
        
        .ConteoPulsosPin02 EQUD &00000000 ;0*4+24 Cuantas Eventos en Pin9 36
        .ConteoPulsosPin03 EQUD &00000000 ;1*4+24 Cuenta Cuantos pin10
        .ConteoPulsosPin04 EQUD &00000000 ;2*4+24 Cuenta Cuantos pin11
        
        .DireLogBCM EQUD  &00000000  ;3*4+24 Direccion Base Logica ya en SO
        
        ;-----------------------------------------------------------------
        ;direccion ya calculada del registro de eventos
        ; para ir directo a el sin sumar
        .DireGplev0BCM EQUD &00000000 ;4*4+24 BCMbase gpio+gpLEV0
        
        ; ============================================================
        
        ;BCM 2835 PIZERO QUE TENGO ACTUALMENTE
        ;direccio base Fisica BCM2835 en raspberry pi
        .DireBaseBCM  EQUD  &20000000  ;0 base bcm
        .PosGPIOBCM   EQUD  &00200000  ;1 base gpio
        
        ;DIRECION DE LECTURA ESTADO DE PINES GPLEV0
        .gplev0  EQUD &00000034 ;dir donde se encuentra estado de pines
        
        .DevicedelTimer EQUD &00000000
        ; ============================================================
        
        .iniGPIO
        LDR R0, DireBaseBCM ;RiscOS dame dir base de GPIO en memoria logica
        MOV R1,R0
        MOV R0,#13
        MOV R2,#&100     ;256 bytes
        PUSH {R14}
        SWI &68
        POP {R14}
        
        LDR R1, PosGPIOBCM
        ORR R3, R3, R1
        STR R3, DireLogBCM      ;guarda en DireLogBCM
        
        LDR R1,gplev0 ;Calcula dir Logica gplev
        ORR R1,R3,R1 ; es como  un add por el tipo de dir
        STR R1,DireGplev0BCM  ; guardalo completo para acelerar INT
        
        MOV PC,R14
        
        ; ===============================================================
        ;INT TIMER TICK 1 MILI SEC
        ; ===============================================================
        .irqTIMER
        STMFD SP!,{R0-R12,R14}
        MRS R10,CPSR
        ORR R0, R10, #3
        MSR CPSR_C, R0
        
        STMFD SP!,{R0-R12,R14}
        
        LDR R2,DireGplev0BCM  ;DIREC Nivel de PIN
        LDR R1,[R2]   ;LEE NIVELES DE PINES
        
        ADR R3, ComprobarPin02
        BL ChecaPin
        ADR R3, ComprobarPin03
        BL ChecaPin
        ADR R3, ComprobarPin04
        BL ChecaPin
        
        MOV R0, #1   ;hal timer 1 irq CLEAR
        MOV R8, #0
        MOV R9,#113
        SWI &7A
        
        MOV R8, #0
        MOV R9, #3
        SWI &7A
        
        LDMFD   SP!, {R0 - R12, R14}
        MSR CPSR_C, R10
        
        LDMFD   SP!, {R0 - R12, PC}
        ;===============================================
        .ChecaPin
        LDR R0,[R3]
        AND R0,R0,R1
        CMP R0,#0   ; Pin Apagado 0?
        BNE Checa1s ; Brinca a Checa1s, si Pin en 1 Alto
        
        MOV R6,#&18
        MOV R4,#&C
        B Actualiza
        
        .Checa1s
        MOV R6,#&C
        MOV R4,#&18
        
        .Actualiza
        LDR R5,[R3,R6] ;Incrementa 0s
        CMP R5,#45
        BEQ finChecaPin
        ADD R5,R5,#1
        STR R5,[R3,R6]
        CMP R5,#45   ;si contamos 45 ms de 0
        BLT finChecaPin
        MOV R2,#0
        STR R2,[R3,R4] ;si el contador de 1 es 0
        
        CMP R6,#&C    ; estoy en control de 1s?
        BNE finChecaPin ; Brinca a fin si no estoy en control de unos
        
        MOV R6,#&24 ;Incrementa Contador de Pulsos
        LDR R5,[R3,R6] ;Incrementa 0s
        ADD R5,R5,#1
        STR R5,[R3,R6]
        
        .finChecaPin
        MOV PC, R14
        
        ;-------------------------------------
        ;SETUP INT TIMER
        
        .TIMER
        STMFD SP!,{R0-R12,R14}
        
        ;Programa Timer
        MOV R0,#1
        MOV R8,#0
        MOV R9,#14  ;Pide Ticks x Segundo
        SWI &7A
        ;Salida en R0, ticks x segundo
        
        MOV R1,#1000 ;Cada miliseg, 1000 veces en 1 seg
        
        ;MOV R1,R0
        MOV R9,#16 ;Set Cada Cuantos Ticks Hay INT
        MOV R0,#1
        MOV R8,#0
        SWI &7A
        
        MOV R0,#1 ;cual es el device del timer 1
        MOV R8,#0
        MOV R9,#13
        SWI &7A
        
        MOV R7,R0 ;el device q resulto anterior
        STR R7, DevicedelTimer
        STMFD SP!,{R0-R12,R14}
        
        ADR R1, irqTIMER     ;solo se usa para cargar la dir
        MOV R2,#0
        MOV R3,#0
        MOV R4,#0
        SWI &4B ;Asigna Interrpcion Timer a Mi Rutina
        
        LDMFD SP!,{R0-R12,R14}
        SWI &13 ;Activa las INT
        
        MOV R8,#0
        MOV R9,#1 ;hal irq enable del device en r0
        MOV R0,R7
        SWI &7A
        
        LDMFD SP!,{R0-R12,PC}
        
        .initialise
        STMDB SP!,{R0-R12,R14}
        
        BL iniGPIO
        BL TIMER
        
        .SALIDA
        LDMFD  SP!, {R0 - R12, PC}
        
        .finalise
        STMFD  SP!, {R0 - R12, R14}
        ;APAGA LIBERA  INT TIMER
        LDR R7, DevicedelTimer
        MOV R8,#0
        MOV R9,#2
        MOV R0, R7
        SWI &7A
        LDMFD  SP!, {R0 - R12, R14}
        
        STMFD  SP!, {R0 - R12, R14}
        LDR R7, DevicedelTimer
        MOV R0, R7
        ADR R1, irqTIMER
        MOV R2, #0
        SWI "OS_ReleaseDeviceVector"
        
        LDMFD  SP!, {R0 - R12, PC}
        ; ================================================================
        ]
      NEXT pass%
      OSCLI("Save Modulo "+STR$~code%+" +"+STR$~P%)
      OSCLI("SetType Modulo FFA")
      RETURN
      

No hay comentarios.:

Publicar un comentario