Overengineered auto on/off

This was made in March 2013. A friend of mine used a Bluetooth aux adaptor („B-Speech RX2 stereo audio receiver“) to connect his phone’s music to his car and had to recognize, that it had to be tuned on and off by hand. The proper way would have been to do this by ignition – or lagged via cigarette lighter socket. This feature was added via PIC10. 🙂

Step 1: Crack case open, search for approach to solution.

Step 2: Connect wired to relevant signals.
This circuit uses it’s own battery and a voltage below the USB 5V – so we need the 5V, the ~3V, the button and GND. I also threw in a connector.

Step 3: Draw and implement circuit, plan firmware.
The PIC10 will sleep until something happens at the 5V line (alternating edge), so a low-to-high as well as a high-to-low transition of the car charger serving the radio will trigger an action.

Step 4: Code in assembler.
As the circuit uses a severe debouncing time the PIC has to spend a lot time waiting busy. If you wonder what the first decision means: this microcontroller forgets it’s program counter when sleeping and always starts at zero – you have to test the wakeup condition and then deciede, if it needs to initialize or jump to the relevant code directly.

;**********************************************************************
; This file is a basic code template for assembly code generation *
; on the PIC10F222. This file contains the basic code *
; building blocks to build upon. *
; *
; Refer to the MPASM User’s Guide for additional information on *
; features of the assembler (Document DS33014). *
; *
; Refer to the respective PIC data sheet for additional *
; information on the instruction set. *
; *
;**********************************************************************
; *
; Filename: xxx.asm *
; Date: *
; File Version: *
; *
; Author: *
; Company: *
; *
; *
;**********************************************************************
; *
; Files Required: P10F222.INC *
; *
;**********************************************************************
; *
; Notes: *
; *
;**********************************************************************
list p=10F222 ; list directive to define processor
#include ; processor specific variable definitions__CONFIG _MCLRE_ON & _CP_OFF & _WDTE_ON & _MCPU_OFF & _IOFSCS_4MHZ; ‚__CONFIG‘ directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

;***** VARIABLE DEFINITIONS
TEMP EQU 0x09 ; Hilfsvariable
PORTBUF EQU 0x0A ; Port-Buffer (R-M-W-Problematik!)
COUNT255 EQU 0x0B ; Zählvariable Verzögerung
COUNT65K EQU 0x0C ; Zählvariable Verzögerung

USB_AKT EQU 0x10 ; Puffer der Abfrage der USB-Versorung
USB_ALT EQU 0x11 ; Letzer Stand zur Flankenerkennung

;***** Konstanten
#define KONSTANTE 0x20 ; Test

;***** Makros
LED_AN MACRO
BSF PORTBUF, GP0 ; Über Portbuffer GP0 einschalten
MOVF PORTBUF, W
MOVWF GPIO
ENDM

LED_AUS MACRO
BCF PORTBUF, GP0 ; Über Portbuffer GP0 ausschalten
MOVF PORTBUF, W
MOVWF GPIO
ENDM

TA_AN MACRO
BSF PORTBUF, GP1 ; Über Portbuffer GP1 einschalten
MOVF PORTBUF, W
MOVWF GPIO
MOVLW B’11111100′ ; GP1 auf Ausgang
TRIS GPIO
ENDM

TA_AUS MACRO
BCF PORTBUF, GP1 ; Über Portbuffer GP0 einschalten
MOVF PORTBUF, W
MOVWF GPIO
MOVLW B’11111110′ ; GP1 auf Eingang
TRIS GPIO
ENDM

;**********************************************************************
ORG 0x1FF ; processor reset vector
; Internal RC calibration value is placed at location 0x1FF by Microchip
; as a movlw k, where the k is a literal value.
ORG 0x000 ; coding begins here
movwf OSCCAL ; update register with factory cal value
TEST_STATUS
; Was war los? Zyklischer Wakeup => MAIN!
BTFSC STATUS, GPWUF
GOTO START
BTFSC STATUS, NOT_TO
GOTO START
BTFSC STATUS, NOT_PD
GOTO START
GOTO MAIN

START ; Kaltstart
NOP

;***** Init
INIT ; Konfiguration:
MOVLW B’11111111′
MOVWF GPIO ; IO-Pins definieren:
MOVLW B’11111110′ ; GP0 = LED, GP1 = Taster, GP2 = VDD-USB
TRIS GPIO
MOVLW B’11001111′ ; Set OPTION register
; ||||||||
; |||||||+———————-> \
; ||||||+———————–> | PS: Prescaler Rate Select bits [Timer0: 1…256, WDT: 1…128]
; |||||+————————> / INTOSC/4 = 1 MHz => 1000…3,9 kHz
; ||||+————————-> PSA: Prescaler Assignment bit [1 = Prescaler assigned to the WDT]
; |||+————————–> T0SE: Timer0 Source Edge Select bit [0 = low => high]
; ||+—————————> T0CS: Timer0 Clock Source Select bit [0 = FOSC / 4]
; |+—————————-> /GPPU: Enable Weak Pull-ups bit (GP0, GP1, GP3) [1 = Disabled]
; +—————————–> /GPWU: Enable Wake-up on Pin Change bit (GP0, GP1, GP3) [1 = Disabled]
OPTION
MOVLW B’00000000′
; ||||||||
; |||||||+———————-> ADON: 0 = Off
; ||||||+———————–> Go! (0 = Done)
; |||||+————————> \
; ||||+————————-> / CHS: 00 = Channel 00 (GP0/AN0)
; |||+————————–> –
; ||+—————————> –
; |+—————————-> ANS0: 0 = GP0/AN0 configured as digital I/O
; +—————————–> ANS1: 0 = GP1/AN1 configured as digital I/O
MOVWF ADCON0
; Variablen:
MOVF GPIO, W
MOVWF PORTBUF
MOVWF USB_AKT
MOVWF USB_ALT
; LED_AN
CALL WAIT255
LED_AUS
CALL WAIT255
LED_AN
CALL WAIT255
LED_AUS

;***** Main
MAIN ; Versorgung über USB angeschlossen?
MOVF GPIO, W
MOVWF PORTBUF
MOVWF USB_AKT

; Re-Initialisierung:
MOVLW B’11111110′
TRIS GPIO
MOVLW B’01001111′
OPTION
MOVLW B’00000000′
MOVWF ADCON0

LED_AN
BTFSS USB_AKT, GP2
GOTO USB_LOW
; USB an: Steigende Flanke?
USB_HIGH
TA_AN
TA_AUS
BTFSC USB_ALT, GP2
GOTO DONE
GOTO TASTENDRUCK
; USB aus: Fallende Flanke?
USB_LOW
TA_AN
TA_AUS
TA_AN
TA_AUS
BTFSS USB_ALT, GP2
GOTO DONE
GOTO TASTENDRUCK
; Ein- oder ausschalten:
TASTENDRUCK
TA_AN
CALL WAIT65K
CALL WAIT65K
CLRWDT
CALL WAIT65K
CALL WAIT65K
CLRWDT
CALL WAIT65K
CALL WAIT65K
CLRWDT
CALL WAIT65K
CALL WAIT65K
CLRWDT
CALL WAIT65K
CALL WAIT65K
CLRWDT
CALL WAIT65K
CALL WAIT65K
CLRWDT
CALL WAIT65K
CALL WAIT65K
CLRWDT
CALL WAIT65K
CALL WAIT65K
TA_AUS
GOTO INIT
; Zustände merken, Sleep-Modus bis WDT wieder auslöst
DONE
MOVF USB_AKT, W
MOVWF USB_ALT
LED_AUS
MOVF GPIO, W
SLEEP

GOTO MAIN
NOP
NOP
GOTO MAIN

; TEST
; MOVLW B’11001111′ ; Set OPTION register
; OPTION
; CALL WAIT255
; MOVLW B’11111111′
; MOVWF GPIO ; IO-Pins definieren:
; MOVLW B’11111110′ ; GP0 = LED, GP1 = Taster, GP2 = VDD-USB
; TRIS GPIO
; CALL WAIT255
; CALL WAIT255
; MOVLW B’11111110′
; MOVWF GPIO
; TEST

;***** Unterprogramme

; Verzoegerung: ~255 Zyklen
WAIT255
; CLRWDT
MOVLW B’1111111′
MOVWF COUNT255
CNT255
DECFSZ COUNT255, 1
GOTO CNT255
RETLW B’00000000′

; Verzoegerung: ~65600 Zyklen (~256*256)
WAIT65K
MOVLW B’11111111′
MOVWF COUNT255
MOVWF COUNT65K
CNT65K
; CLRWDT
DECFSZ COUNT255, 1
GOTO CNT65K
MOVLW B’11111111′
MOVWF COUNT255
DECFSZ COUNT65K, 1
GOTO CNT65K
RETLW B’00000000′

FILL (GOTO TEST_STATUS), 0x160 ; force known data into unused memory
END ; directive ‚end of program‘

 

Step 5: Test everything, secure botchery (wired soldered to pads) with more botchery (hot melt).

IMG_20130524_123911

Step 6: There it is! (Sorry for the quality – I still had a Motorola Milestone / Droid in 2013 😛 )

 

P.S.: Also sorry for the German comments – if ANYONE REALLY wants me to translate them, tell me in the comment section below. (Until then I am too lazy for that. ^^)

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.