mercoledì 20 giugno 2018

Laser control e raycaster su Aframe

Per poter interagire con gli oggetti su Aframe si puo' utilizzare il laser-control, un componente che mostra un raggio laser che viene emesso dal controller (sia questo DayDream od Oculus)  e che puo' interagire con gli oggetti della scena




Il laser-control puo' essere aggiunto con la semplice riga

      <a-entity id="rightHand" laser-controls="hand: right" raycaster="objects:#cube"></a-entity>

e' importante inserire la entity in un rig che contenga anche l'oggetto camera in modo che il raggio laser parta sempre come origine dalla camera. E' inoltre importante indicare quali sono gli oggetti con cui il raggio interagira' mediante il comando raycaster

Nell'esempio viene creata una scena con un cubo ed un piano con una texture trasparente. Dopo che l'utente clicca sul cubo con in controller Daydream la texture del piano perde la trasparenza



-------------------------------------------------------------------------------
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Laser Controls</title>
    <meta name="description" content="Laser Controls - A-Frame">
    <script src="aframe-master.js"></script>

  </head>
  <body>

<script>
    AFRAME.registerComponent('laser-listener', {
  init: function () {

    var self = this;
    var el = this.el;

    this.el.addEventListener('mousedown', function (evt) {

      document.querySelector('#cube').setAttribute('material', 'color', '#EF2D5E');
      document.querySelector('#piano').setAttribute('material','opacity',1.0);
    });
    this,el.addEventListener('mouseup', function (evt) {
      el.setAttribute('material', 'color', self.isMouseEnter ? '#24CAFF' : initialColor);
            document.querySelector('#piano').setAttribute('material','opacity',1.0);
    });
   

  }
});

</script>

    <a-scene auto-enter-vr background="color: #212" antialias="true">
 <a-entity id="rig" movement-controls="fly: true; speed: 30" position="300 50 140" rotation="0 45 0">
      <a-entity position="50 30 410" camera look-controls wasd-controls></a-entity>
      <a-entity id="rightHand" laser-controls="hand: right" raycaster="objects:#cube"></a-entity>
</a-entity>


       <a-assets>
<img id="grafico" src="./sposta.jpg">
<img id="trasparente" src="./trasparente.png">
        </a-assets>
    
<a-plane id="piano" src="#grafico" material="opacity:0.0" position="270 40 -10" rotation="0 20 0" width="100" height="60" scale="" visible="" geometry=""></a-plane>
<a-entity laser-listener position="230 7 15" id="cube" geometry="primitive: box; width: 5.5; height: 5.5; depth:5.5" material="color: red"></a-entity>

    </a-scene>
  </body>
</html>

venerdì 15 giugno 2018

Simple FPV con Android

Esistono gia' applicazioni che trasformano un telefono Android in un visore FPV per droni ma volevo qualcosa di semplice da poter personalizzare

Il progetto e' basato sul usbCameraTest6 con alcune modifiche per permettono di avviare l'applicazione appena viene inserito nel telefono il connettore USB della camera

per compilare il repository Github si deve avere anche montato NDK. Durante le prove ho fare il downgrade del progetto rispetto all'NDK attualmente installato con Android Studio (ver. 16) ed ho utilizzato la versione 14b. Per fare cio' si scarica il pacchetto del vecchio SDK (circa 800 Mb) e lo si decomprime in una directory esterna a Android Studio....a questo punto si deve modificare il file local.properties del progetto Android per esempio

ndk.dir=/home/lucainnocenti/Downloads/android-ndk-r14b

File manifest con le modifche per mettere in ascolto su USB 
---------------------------------------------------------

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.serenegiant.usbcameratest6" >

   

    <uses-feature android:glEsVersion="0x00020000" android:required="true" />
    <uses-feature android:name="android.hardware.usb.host" />

    <application        android:launchMode="singleTask"        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
        <activity            android:name="com.serenegiant.usbcameratest6.MainActivity"            android:label="@string/app_name"            android:screenOrientation="sensorLandscape" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
            </intent-filter>
            <meta-data                android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"                android:resource="@xml/device_filter" />


        </activity>
    </application>

</manifest>

---------------------------------------------------------
il file @xml/device_filter seleziona che l'apertura della app avviene solo quando viene inserito un dispositivo UVC
<usb>
   <usb-device class="239" subclass="2" />    <!-- all device of UVC --></usb>
 

giovedì 14 giugno 2018

SetPixel su C64

Questo e' solo un promemoria....il codice e' stato preso su Internet...ho provato solo a capirci qualcosa senza neanche molto successo


Debug di VICE


Per accendere un pixel di posizione X,Y nella modalita' in alta risoluzione (320x200x2colori) del C64 la formula e' la seguente

indirizzo_pixel = base_mem_video +( int(y/8) *320) +(y AND 7) + (int(x/8)*8)

il motivo di questa curiosa formula deriva da come e' gestita la modalita' grafica. Al contrario di come si potrebbe fare con VGA (con un flusso continuo di bit a descrivere la pagina) in C64 lo schermo e' diviso in porzioni di 8x8 pixels.

Ho trovato su GitHub questo codice che funziona decisamente bene e si compila con ACME (per lanciarlo SYS 32768) ed ho provato a commentarlo con risultati decisamente alterni

------------------------------------------------------
!cpu 6502
!to "plot-asm.prg",cbm

base = $2000
SCROLY = $D011
VMCSB = $D018
colmap = $0400
C2DDRA = $DD02
CI2PRA = $DD00

scrlen = 8000
maplen = 1000

xcoord = $fb
ycoord = $fd

tabptr = xcoord
tabsiz = $9000
filval = tabsiz+2

; queste sono variabili in pagina zero
bmpage = $ff
mask = $59
loc = $5a
store = $5c

* = $8000 ; start address for 6502 code
; sys 32768


jmp start


; address = base + int(y/8) * 320 + (y and 7) + int(x/8) * 8
plotbit lda xcoord  ; mette il valore della coordinata X in accumulatore
        ; questa e' il primo pezzo ovvero (X AND 7)
and #7      ; 7 = 111
tax         ; mette (xcoord and 7) in X
                    ; questo serve per il numero di cicli di SHIFT
sec         ; setta il carry questo dovrebbe servire per il ror successivo
                           
lda #0      ; azzera l'accumulatore
sta loc     ; mette la locazione $5c di x and 7
       
shift ror         ; ruota right bits dell'accumulatore
                    ; (divide per 2 l'accumulatore)
dex         ; decrementa x
bpl shift   ; salta se x e' positivo o zero
                    ; ror e' come dividere per 2 ogni ciclo
sta mask    ; salva il valore in  $59
       
lda xcoord  ; carica l'accumulatore di xcoord
and #$f8    ; $f8=248 = 11111000
sta store   ; metti in valore in store = $5c = 92 = 1011100
       
       
lda ycoord  ; carica il valore di y
lsr         ; shift left divide y/2
        ; nel carry c'e' il resto della divisione
lsr         ; shift left divide y/4
lsr         ; shift left divide y/8
sta loc+1   ;salva il $5a+1=$5b
lsr         ; shift left
ror loc     ; moltiplica * 320 ?????
  lsr
ror loc
adc loc+1   ; salva la parte alta
sta loc+1
       
lda ycoord ; carica il valore di y
and #7     ; Y AND 7
                   ; somma gli addendi
adc loc    ; aggiungi LOC
adc store  ; aggiungi STORE
sta loc    ; salva tutto in STORE
lda loc+1 
adc xcoord+1
adc bmpage ; aggiunge la base della memoria (ovvero base + .....)
sta loc+1
ldy #0
lda (loc),y
ora mask,y
sta (loc),y
rts

:--------------------------------------------------------------------------------
; fill routine
blkfil lda filval  ; metti nell'accumulatore il valore della cella $9002 ovvero $10
ldx tabsiz + 1  ; carica in x $9001  ovvero
beq partpg  ; salta alla label partpg se la flag di zero e' clear
ldy #0  ; carica Y con zero
fullpg sta (tabptr),y ; carica la cella puntata da $fb $400 con il valore zero inizialmente, poi cicla su fullpg su per $20
                       ; indirect-indexed carica il valore zero dalla memoria puntata da $tabptr
                       ; e' un modo che e' comune per realizzare array con y come indice ed il puntatore alla zona di memoria
iny            ; incrementa Y
bne fullpg      ; salta alla label fullpg
inc tabptr+1    ; incrementa la locazione $FC
dex             ; decrementa X
bne fullpg       ; ritorna a
partpg         ldx tabsiz
beq fini
ldy #0
partlp sta (tabptr),y
iny
dex
bne partlp
fini rts


;---------------------------------------------------------------------------------
; main routine
; define bit map and enable high-res
start lda #$20
sta bmpage ; mette il valore $20 nella pagina zero a $FF
lda #$18
sta VMCSB  ; seleziona lo screen mode $d018=53272
lda SCROLY ;
ora #32    ; attiva la risuoluzione 320x200 con OR 32 la locazione $d011=53265
sta SCROLY ;

; select graphics bank 1
lda C2DDRA ; $DD02
ora #$03   ; seleziona i banco VIC 1
sta C2DDRA ; ; $DD02

lda CI2PRA ; $DD00
ora #$03   ; $DD00 = %xxxxxx10 -> bank1: $4000-$7fff
sta CI2PRA


; clear bit map
lda #0 ; carica accumulatore con zero
sta filval ; tabsiz+2=$9002
lda #<base ; $2000 base della memoria schermo
sta tabptr ; metti il valore dell'accumulatore in $fb; locazione non usata di pagina zero
                   ; qui e nella locazione successiva c'e' il puntatore alla zona di memoria tabptr
lda #>base ; mette $20
sta tabptr+1 ; carica il valore alto in $fc locazione pagina alta non utilizzata

lda #<scrlen ; mette la parte bassa basso $40 scrlen = 8000 byte
sta tabsiz  ; mettilo alla locazione 9000
lda #>scrlen ; mette la parte alta $1F
sta tabsiz+1 ; dentro a $9001
jsr blkfil ; vai alla subroutune


; set bg and line colors
lda #$10      ; carica accumulatore $10
sta filval    ; lo mette in $9002
lda #<colmap  ; lda #$00
sta tabptr    ; lo mette in $FB
lda #>colmap  ; lda $04
sta tabptr+1  ; mette if $FC
lda #<maplen  ;
sta tabsiz
lda #>maplen
sta tabsiz+1
jsr blkfil ; vai alla subroutine


; set horizontal and vertical position
lda #<160   ; visto che x puo' essere> 255 prende sia la parte bassa che alta
sta xcoord  ; mette il valore 160 in xcoord
lda #>160
sta xcoord+1
lda #100    ; mette il valore di 100 in ycoord
sta ycoord 
jsr plotbit  ; vai alla routine di stampa bit per stampare il punto 160,100

inf jmp inf  ; cicla qui all'infinito

------------------------------------------------------

Una cosa interessante che ho scoperto mentre cercavo di capire qualcosa del codice e' che VICE, l'emulatore di C64, e' dotato di un fantastico monitor in cui si puo' fare debug passo passo.
Si apre VICE e ci si trascina sopra il programma compilato in PRG. Poi si apre la finestra di monitor (ALT+H od ALT+M dipende dal sistema operativo)....si apre una consolle in cui si devono digitare comandi (per un elenco completo digitare help)

Dato che so che il codice inizia a $8000 e' stato sufficiente settare un breakpoint (BREAK $8000...tutti gli indirizzi devono essere messi in esadecimale) e poi lanciare il programma con SYS 32768. A questo punto si possono aprire le varie sottofinestre (per esempio dei registri...si puo' visualizzare lo stato anche con REGISTERS) e si pu' fare fare debug passo passo con STEP (oppure il tasto Z)


Un altro esempio per stampare punti in alta risoluzione puo' essere estratto da questo esempio in BASIC (e' un semplice PAINT che funziona con il joystick) (questa la fonte)
Il programma in Assembler funziona ... questo non lo ho testato
--------------------------------------------------------
0       POKE 56, 32 : POKE 52, 32 : CLR : REM PROTECT SCREEN FROM BASIC   :rem 108
1 POKE 53280, 1 : PRINT "{CLR}{WHT}" : GOTO 100      :rem 102
2 GOSUB 26 : BASE = 2 * 4096 : REM START ADDRESS OF HIRES SCREEN   :rem 93
3 POKE 53272, PEEK(53272) OR 8 : REM BIT MAP AT 8192     :rem 39
4 POKE 53265, PEEK(53265)OR 32 : REM BIT MAP ON      :rem 141
5 SYS 49152 : REM CLR HIRES SCREEN        :rem 115
6 SYS 49173 : REM SET SCREEN COLOR (BITS THAT ARE OFF)    :rem 237
7 X = 160 : Y = 100 : REM X & Y START POSITIONS      :rem 15
8 GO SUB 13 : REM READ JOYSTICK        :rem 198
9 REM UPDATE SCREEN           :rem 160
10 CH = INT(X/8) : RO = INT(Y/8) : LN = YAND7 : BY = BA SE + RO * 320 + 8 * CH + LN : BI = 7 - (X AND 7) :rem 90
11 POKE BY, PEEK(BY) OR (2↑BI) : GOTO 8       :rem 33
12 REM READ JOYSTICK           :rem 211
13 JV = PEEK(56320) : FR = JV AND 16        :rem 160
15 X = X + ((JV AND 4) = 0) - ((JV AND 8) = 0)      :rem 27
16 Y = Y + ((JV AND 1) = 0) - ((JV AND 2) = 0)      :rem 21
19 IF FR = 0 THEN 5           :rem 98
20 IF X > 319 THEN X = 319          :rem 133
21 IF Y > 199 THEN Y = 199          :rem 148
22 IF X < 0 THEN X = 0          :rem 171
23 IF Y < 0 THEN Y = 0          :rem 174
24 GET A$ : IF A$ < > "Q" THEN RETURN        :rem 247
25 POKE 56, 160 : POKE 52, 160 : POKE 53272, 21 : POKE 53265, 27 : PRINT "{CLR}" : END    :rem 4
26 PRINT "{CLR}" TAB(18)"{DOWN}MENU{DOWN}{4 LEFT}[<4 Y>]"    :rem 72
27 PRINT "{DOWN}" TAB(16) "Q{2 SPACES} - QUIT"      :rem 223
28 PRINT "{DOWN}" TAB(9) "FIRE BUTTON - CLR SCREEN"     :rem 193
29 PRINT "{DOWN}" TAB(10) "JOYSTICK MOVES LINE."      :rem 106
30 PRINT "{3 DOWN}{7 RIGHT} ENTER BORDER COLOR (0 TO 15)." : PRINT SPC(18); :rem 71
31 INPUT BC : POKE 53280, BC AND 15        :rem 206
32 PRINT"{3 DOWN}{7 RIGHT} ENTER SCREEN COLOR (0 TO 15)." : PRINT SPC(18); :rem 75
33 INPUT SC : POKE 49174, SC AND 15 : RETURN      :rem 19
94 END : REM ELECTRIC ERASER         :rem 111
95 A = PEEK(61) + 256 * PEEK(62) + 3 : POKE 786, INT(A/256) : POKE 785,A - 256 * PEEK(786)   :rem 3
96 POKE A - 2, 0 : POKE A - 1,0 : POKE 45, PEEK(785) : POKE 46, PEEK(786) : CLR : GOTO95   :rem 44
100 FOR I = 0 TO 42 : READ J : POKE 49152 + I, J : NEXT I : GOTO 2       :rem 150
101 DATA 169, 0, 162, 32, 160, 0, 132, 33, 134, 34, 145, 33, 200, 208, 251, 232, 224, 64, 208, 244 :rem 17
102 DATA 96, 169, 1, 162, 4, 160, 0, 132, 33, 134, 34, 145, 33, 200, 208, 251, 232, 224, 8, 208, 244 :rem 75
103 DATA 96, 0 

lunedì 11 giugno 2018

Floating point numbers in C64

Continua l'esplorazione di tutto quanto mi sono perso su C64

Quando ho iniziato a studiare l'assembler avevo Olivetti M24 su processore 8086 e sul C64 usavo solo BASIC (al limite integrato con Simon Basic per qualche routine grafica). L'assembler 8086 non e' banalissimo ma la cosa che piu' mi infastidiva era quella di non poter gestire in modo nativo la matematica dei numeri float ....a meno che di non possedere un costosissimo coprocessore matematico (che e' stato integrato solo dalla serie x486)

Con sorpresa ho scoperto che usare i numeri a virgola mobile e fare conti su C64 e' incredibilmente banale anche in assembler.

Per prima cosa i numeri float hanno una struttura di 5 byte e sono nel formato esponenziale base 2 ...quindi qualcosa del tipo x.xxx 2^y

byte 1 : esponente : il valore dell'esponente e' nel formato exp-129 (quindi 2^0 avra' il valore 81, valore piu' bassi indicano esponenti negativi)

byte 2-5 : mantissa

Convertire da formato float decimale a float C64

per fare poca fatica conviene usare direttamente la conversione di C64

Per esempio si digiti da BASIC
NEW
X = 3.14159

IND = PEEK(71)+256*PEEK(72)

PRINT PEEK(IND)
PRINT PEEK(IND+2)
PRINT PEEK(IND+3)
PRINT PEEK(IND+4)
PRINT PEEK(IND+5)

quale e' il significato. Diciamo al BASIC di salvare il valore di float di pi greco in una variabile. Nelle locazioni a pagina zero 71 e 72 c'e' il puntato alla zona di memoria dove viene inserito effettivanemente il numero (gia' decodificato in formato C64). Nel mio caso l'indirizzo e' $805 (esadecimale) se sei aggiungono altre variabile si vedra' che il puntatore si aggiorna

La risposta al comando e'
$82 $49 $0F $CF $82

ovvero la traduzione in formato float C64
Per fare la riprova si puo' usare questo programma assembler in ACME
in pratica si popola la'accumulatore di float FAC con il valore di pi greco, si chiama il kernal per la conversione del valore in una stringa ($BDDD) e poi si mostra la stringa a schermo
-----------------------------------------------
Float

!source "./std.a"
!to "float.prg", cbm
!sl "float.map"
!cpu 6510

*=$1000

LDFAC = $bba2


!macro LoadFAC .addr {
lda #<.addr
ldy #>.addr
jsr LDFAC
}

+LoadFAC pi

MOVFA ; sposta FAC in ARG


;JSR $E264 ;COSENO NON UTILIZZATA

JSR $BDDD ;Convert FAC to zero-terminated string representation at memory addresses $0100-$010A.

 LDY   #0

loop:   LDA   $100,Y
        BEQ   done
        JSR   $FFD2        
        INY
        BNE   loop          
done:

RTS

pi !by $82, $49, $0F, $CF, $82
-----------------------------------------------

Per la riconversione l'algoritmo (preso da qui) e' il seguente

  • Exponent: exp-128
  • Mantissa: (m4 >= 128 ? -1 : +1) * ((m4 | 0x80) >> 8 + m3 >> 16 + m2 >> 24 + m1 >> 32) 

La cosa interessante e' che da Assembler si possono chiamare anche le funzioni trigonometriche, le stesse condivise con BASIC, ma che risultano decisamente piu' veloci (vedi la chiama alla subroutine in $E264 corrispondente al coseno)

c'e' da osservare che la precisione dell'arrotondamento delle routine non e' ottimale (vedi questo link)

sabato 9 giugno 2018

EACHINE R051

Mi e' stato dato il ricevitore EACHINE R051 (utlizzato per le camere FPV a 5 GHz dei droni) per vedere se riuscivo a creare una applicazione Android alternativa a quella originale della ditta....e sono iniziati i problemi


Il dispositivo si dichiara come segue su Linux

--------------------------------------------------
Jun  7 15:47:31 localhost kernel: usb 3-1: new high-speed USB device number 39 using xhci_hcd
Jun  7 15:47:31 localhost kernel: usb 3-1: New USB device found, idVendor=2537, idProduct=1081
Jun  7 15:47:31 localhost kernel: usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jun  7 15:47:31 localhost kernel: usb 3-1: Product: EACHINE
Jun  7 15:47:31 localhost kernel: usb 3-1: SerialNumber: 0123456789ABCDE
Jun  7 15:47:31 localhost kernel: usb-storage 3-1:1.0: USB Mass Storage device detected
Jun  7 15:47:31 localhost kernel: scsi host12: usb-storage 3-1:1.0
Jun  7 15:47:31 localhost mtp-probe: checking bus 3, device 39: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-1"
Jun  7 15:47:31 localhost mtp-probe: bus: 3, device: 39 was not an MTP device
Jun  7 15:47:32 localhost kernel: usb 3-1: USB disconnect, device number 39
Jun  7 15:47:36 localhost kernel: usb 3-1: new high-speed USB device number 40 using xhci_hcd
Jun  7 15:47:36 localhost kernel: usb 3-1: New USB device found, idVendor=2537, idProduct=1081
Jun  7 15:47:36 localhost kernel: usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jun  7 15:47:36 localhost kernel: usb 3-1: Product: EACHINE
Jun  7 15:47:36 localhost kernel: usb 3-1: SerialNumber: 0123456789ABCDE
Jun  7 15:47:36 localhost kernel: usb-storage 3-1:1.0: USB Mass Storage device detected
Jun  7 15:47:36 localhost kernel: scsi host13: usb-storage 3-1:1.0
Jun  7 15:47:36 localhost mtp-probe: checking bus 3, device 40: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-1"
Jun  7 15:47:36 localhost mtp-probe: bus: 3, device: 40 was not an MTP device
Jun  7 15:47:37 localhost kernel: scsi 13:0:0:0: Direct-Access     JKH Tech Fly Video             PQ: 0 ANSI: 6
Jun  7 15:47:37 localhost kernel: sd 13:0:0:0: [sdb] 2 512-byte logical blocks: (1.02 kB/1.00 KiB)
Jun  7 15:47:37 localhost kernel: sd 13:0:0:0: Attached scsi generic sg1 type 0
Jun  7 15:47:37 localhost kernel: sd 13:0:0:0: [sdb] Write Protect is on
Jun  7 15:47:37 localhost kernel: sd 13:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
Jun  7 15:47:37 localhost kernel: Dev sdb: unable to read RDB block 2
Jun  7 15:47:37 localhost kernel: sdb: unable to read partition table
Jun  7 15:47:37 localhost kernel: sdb: partition table beyond EOD, enabling native capacity
Jun  7 15:47:37 localhost kernel: Dev sdb: unable to read RDB block 2
Jun  7 15:47:37 localhost kernel: sdb: unable to read partition table
Jun  7 15:47:37 localhost kernel: sdb: partition table beyond EOD, truncated
Jun  7 15:47:37 localhost kernel: sd 13:0:0:0: [sdb] Attached SCSI removable disk
--------------------------------------------------

Come si vede c'e' una memoria interna (che pero' non sono mai riuscito a montare su Linux perche' il filesystem risultava sempre corrotto) mentre per la sigla  JKH Tech Fly Video non si trovano informazioni.
La cosa da notare e' che su Linux non viene montata una /dev/video* e la camera non e' vista ne' su Windows 10 ne' su Mac....eppure il prodotto viene venduto come UVC (Universal Video Camera) USB Video Class

Non era possibile trovare l'R051 nemmeno in /dev/input/by-path

Montando WireShark per sniffare il traffico USB non ha dato informazioni perche' una volta connessa
la ricevente non era presente nessuno stream (di nessun tipo) sui canali USB

Il preda allo scoraggiamento ho decompilato la applicazione.



All'interno e' presente la libVLC per Android e ci sono chiare chiamate ad stream video conosciuti...quindi non si tratta di un formato video proprietario e ci sono a chiamate ad UVC quindi i dati tecnici sembrano corretti. Ci sono inoltre funzioni che gestiscono l'enumerazione di dispositivi USB e controlli apparentemente su firmware, serial number

Mi viene da pensare che lo stream video non si attivi quando si connette il dispositivo ma solo con un comando software ...questo giustificherebbe perche' non viene montato /dev/video (nel codice puo' essere interessante la funzione UsbConnection

Frugando nella cartella lib, oltre al gia' citato VLC, si trova libns1081-lib che e' relativa al firmware di un controller USB 3.0 Norelsys NS1081. Quindi l'interfaccia con la USB non sembra standard

Una particolarita che ho scoperto dopo un bel po' di prove: il cavo USB non ha la corrente necessaria per tenere acceso il dispositivo. L'EACHINE sembra avere una batteria tampone interna che si ricarica (fino a quando il led rosso smette di pulsare). Se a batteria scarica si connette il dispositivo e si cerca di usarlo nel giro di pochi secondi si spenge. Mi sa che questo aspetto possa essere dovuto al fatto che il dispositivo e' internamente USB 3.0 mentre io lo ho attaccato sempre ad USB 2.0 (quindi a porte di potenza piu' bassa)

venerdì 8 giugno 2018

Serie di Fibonacci in Assembler C64

Il Commodore 64 e' stato il mio primo calcolatore e non sono mai riuscito ad imparare a programmare in Assembler...anche perche' all'epoca non esisteva Internet e se non avevi un amico "istruito" non andavi da nessuna parte....sto cercando di colmare la lacuna adesso a distanza di oltre trenta anni

Inizio con una cosa facile...ovvero la serie di Fibonacci limitata ai numeri sotto a 255 (la bellezza dei calcolatori 8bit)



il codice e' molto semplice
----------------------------------------------------
processor 6502
org $1000
       ; clear carry flag...leggendo in alcuni posti sembra che non sia obbligatorio
       ; settare a zero il flag di carry perche' viene fatto in automatico da adc
clc
torna
         ; mette nell'accumulatore il valore della variabile byte uno
         lda uno
         ; somma l'accumulatore con la variabile due
         adc due
         ; metti il risultato in somma
         sta somma
         ; se si ha un overflow la flag di carry e' a 1 ed esce
         bcs esci
        ; altrimenti scambia il contenuto delle variabili  per il prossimo calcolo
         lda due
         sta uno
         lda somma
         sta due

        ; qui chiama una funzione che stampa a video il valore di un numero a 16 bit
        ; nell'accumulatore viene messo il byte piu' significativo ,ma qui e' sempre a zero
lda #$00
ldx somma
JSR $BDCD
       
        ; funzione che stampa uno spazio a video
JSR $AB3F

         jmp torna
esci
         rts
uno
         .byte $01
due
         .byte $01
somma
         .byte $00

------------------------------------------------------

Per compilare il codice ho usato Dasm

/dasm.Linux.x86 fib2.asm -ofib2.prg

per eseguire il codice si compila Vice e si lancia

x64 fib2.prg

digitando poi

SYS 4096



martedì 5 giugno 2018

Pebble Time tearing

PS dopo una decina di giorni mi sono accorto che il problema persiste (meno di prima ma persiste) e non sembra legato alla flat del cavo. Lo schermo infatti si aggiorna solo premendo il pulsante in basso a destra...forse un problema software??? non e' possibile saperlo perche' non posso aggiornare il firmware

Livello di difficolta' : 1/5

Io amo Pebble Time per i seguenti motivi

1) la batteria dura ben oltre una settimana ed il cavo di ricarica ad aggancio magnetico e' comodissimo

2) Oramai su Ebay si trovano in offerta a circa 10 euro (basta aspettare)

3) Esiste GadgetBridge


Il problema e' che ogni tanto lo schermo si corrompe fino a che viene fatto il refresh manualmente premendo i tasti...negli ultimi tempi il fenomeno stava diventando molto frequente e fastidioso


Ho scoperto su internet che e' un problema comuni ai Pebble (indipendentemente dal modello) ed e' legato alla flat di connessione tra la scheda madre e lo schermo..fortunatamente si puo' facilmente riparare. Aprire il Pebble e' semplice...basta avere il giusto cacciavite. Dopo di cio' si deve rimuovere il coperchio con calma perche il sistema di vibrazione e' incollata alla cover e deve essere staccato prima di alzare completamente il coperchio..Meglio spengere il Pebble prima di operare



Dopo di cio' si puo' inserire uno spessore di carta per schiacciare in sede la flat (vedi la differenza tra le due foto)


Ricomposto il tutto lo schermo e' tornato a funzionare


questo invece un video non di mia produzione