?? caminterfaceasm.s
字號:
;**********************************************************************
; Module Name: CanInterfaceAsm.S
; Module Date: 04/14/2004
; Module Auth: John Orlando
;
; Description: This module provides the low-level interface
; to the OV6620 camera hardware. It is responsible for
; acquiring each pixel block (R,G,B), performing the mapping
; into an actual color (orange, purple, etc), run-length
; encoding the data, and storing the info off to the appropriate
; line buffer. This routine is synchronized with the pixel data
; so that no polling of the camera data needs to be done (the
; OV6620 is clocked off of the same crystal source as the mega8,
; thus providing inherent synchronization between the two).
#include <avr/io.h>
#include "Events.h"
.extern fastEventBitmask ; This is the flag used to indicate to the rest
; of the system that the line is complete
#define HREF_INTERRUPT_ENABLE_MASK 0x08 ; int3
#define HREF_INTERRUPT_DISABLE_MASK 0xF7
#define ENABLE_PCLK_TIMER1_OVERFLOW_BITMASK 0x04
#define DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK 0xFB
#define G_PORT _SFR_IO_ADDR(PINC)
#define RB_PORT _SFR_IO_ADDR(PINA)
#define PIXEL_RUN_START_INITIAL 0x50 ; This value causes our pixel counter (TCNT1)
; to overflow after 176 (horizontal) pixels
; A pixelBlock is defined as a contiguous group of 4 pixels that are combined
; together to form a specific color. Typically, this is formed by sampling a
; a green value, followed by a red and blue value (since we are dealing
; with Bayer color data). We could optionally sample a second green with
; the red and average the greens, because the eye is more sensitive to
; green, but for speed we don't do this. These three values (RGB) are then
; used as indices into the color membership lookup table (memLookup) to
; determine which color the pixelBlock maps into. The memLookup table is
; manually generated for now (though it will hopefully be modified over
; the serial interface eventually).
;
; Here is a pixel block:
; ...G G G G... (row x)
; ...B R B R... (row x+1)
; | | | |--this is skipped
; | | |--this is skipped
; | |--this is sampled
; |--this is sampled
; These are the registers that will be used throughout this
; module for acquiring each line of pixel data
pixelCount = 16
pixelRunStart = 17
lastColor = 18
tmp1 = 19 ; be sure to not use tmp1 and color simultaneously
tmp2 = 20
color = 19
prevLineBuffLow = 22 ; overlaps with memLookupLow (but orthogonal)
prevLineBuffHigh = 23 ; overlaps with memLookupHigh (but orthogonal)
currLineBuffLow = 24
currLineBuffHigh = 25
.section .text
; These are the global assembly function names that are accessed via other
; C functions
.global CamIntAsm_waitForNewDumpFrame
.global CamIntAsm_acquireDumpLine
.global SIG_INTERRUPT0
.global SIG_INTERRUPT1
.global SIG_OVERFLOW1
_cleanUpDumpLine:
; NOTE: If serial data is received, to interrupt the tracking of a line, we'll
; get a EV_SERIAL_DATA_RECEIVED event, and the T bit set so we will end the
; line's processing...however, the PCLK will keep on ticking for the rest of
; the frame/line, which will cause the TCNT to eventually overflow and
; interrupt us, generating a EV_ACQUIRE_LINE_COMPLETE event. We don't want
; this, so we need to actually turn off the PCLK counting each time we exit
; this loop, and only turn it on when we begin acquiring lines....
; NOT NEEDED FOR NOW...
;in tmp1, _SFR_IO_ADDR(TIMSK) ; disable TIMER1 to stop counting
;andi tmp1, DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK ; external PCLK pulses
;out _SFR_IO_ADDR(TIMSK),tmp1
_cleanUp:
; Disable the external clocking of the Timer1 counter
in tmp1, _SFR_IO_ADDR(TCCR1B)
andi tmp1, 0xF8
out _SFR_IO_ADDR(TCCR1B),tmp1
; Toggle the debug line to indicate the line is complete
sbi _SFR_IO_ADDR(PORTB),PB6
cbi _SFR_IO_ADDR(PORTB),PB6
clt ; clear out the T bit since we have detected
; the interruption and are exiting to handle it
_exit:
ret
;*****************************************************************
; Function Name: CamIntAsm_waitForNewDumpFrame
; Function Description: This function is responsible for
; going to sleep until a new frame begins (indicated by
; VSYNC transitioning from low to high. This will wake
; the "VSYNC sleep" up and allow it to continue with
; acquiring a line of pixel data to dump out to the UI.
; Inputs: r25 - MSB of currentLineBuffer
; r24 - LSB of currentLineBuffer
; r23 - MSB of prevLineBuffer
; r22 - LSB of prevLineBuffer
; Outputs: none
; NOTES: This function doesn't really return...it sorta just
; floats into the acquireDumpLine function after the "VSYNC sleep"
; is awoken.
;*****************************************************************
CamIntAsm_waitForNewDumpFrame:
sbi _SFR_IO_ADDR(PORTB),PB6 ; For testing...
cbi _SFR_IO_ADDR(PORTB),PB6
sleep
;*****************************************************************
; REMEMBER...everything from here on out is critically timed to be
; synchronized with the flow of pixel data from the camera...
;*****************************************************************
CamIntAsm_acquireDumpLine:
brts _cleanUp
;sbi _SFR_IO_ADDR(PORTD),PD6 ; For testing...
;cbi _SFR_IO_ADDR(PORTD),PD6
mov XH,currLineBuffHigh ; Load the pointer to the current line
mov XL,currLineBuffLow ; buffer into the X pointer regs
mov YH,prevLineBuffHigh ; Load the pointer to the previous line
mov YL,prevLineBuffLow ; buffer into the Y pointer regs
ldi tmp1,0xC0 ;PIXEL_RUN_START_INITIAL ;0x50 set up the TCNT1 to overflow (and
ldi tmp2,0xFE ;//0xff interrupts) after 176 pixels 320
out _SFR_IO_ADDR(TCNT1H),tmp2
out _SFR_IO_ADDR(TCNT1L),tmp1
in tmp1, _SFR_IO_ADDR(TCCR1B) ; Enable the PCLK line to actually
ori tmp1, 0x07 ; feed Timer1
out _SFR_IO_ADDR(TCCR1B),tmp1
nop
in tmp1, _SFR_IO_ADDR(TIMSK) ; enable TIMER1 to start counting
ori tmp1, ENABLE_PCLK_TIMER1_OVERFLOW_BITMASK ; external PCLK pulses and interrupt on 0x04
out _SFR_IO_ADDR(TIMSK),tmp1 ; overflow
in tmp1, _SFR_IO_ADDR(EIMSK) ; enable the HREF interrupt...remember, we
; only use this interrupt to synchronize
; the beginning of the line INT3
ori tmp1, HREF_INTERRUPT_ENABLE_MASK ;0x08
out _SFR_IO_ADDR(EIMSK), tmp1
;*******************************************************************************************
; Dump Frame handler
;*******************************************************************************************
_dumpFrame:
sbi _SFR_IO_ADDR(PORTB),PB6
sleep ; ...And we wait...
cbi _SFR_IO_ADDR(PORTB),PB6 ;(2)
in tmp1, _SFR_IO_ADDR(EIMSK) ;(1) disable the HREF interrupt
andi tmp1, HREF_INTERRUPT_DISABLE_MASK ;(1) so we don't get interrupted
out _SFR_IO_ADDR(EIMSK), tmp1 ;(1) while dumping the line
;nop ;改 Remember...if we ever remove the "cbi" instruction above,
; we need to add two more NOPs to cover this
; Ok...the following loop needs to run in 8 clock cycles, so we can get every
; pixel in the line...this shouldn't be a problem, since the PCLK timing was
; reduced by a factor of 2 whenever we go to dump a line (this is to give us
; enough time to do the sampling and storing of the pixel data). In addition,
; it is assumed that we will have to do some minor processing on the data right
; before we send it out, like mask off the top 4-bits of each, and then pack both
; low nibbles into a single byte for transmission...we just don't have time to
; do that here (only 8 instruction cycles :-) )
_sampleDumpPixel:
in tmp1,G_PORT ; sample the G value (1)
in tmp2,RB_PORT ; sample the R/B value (1)
st X+,tmp1 ; store to the currLineBuff and inc ptrs(2)
st Y+,tmp2 ; store to the prevLineBuff and inc ptrs(2)
brtc _sampleDumpPixel ; loop back unless flag is set (2...if not set)
; ___________
; 8 cycles normally
; if we make it here, it means the T flag is set, and we must have been interrupted
; so we need to exit (what if we were interrupted for serial? should we disable it?)
rjmp _cleanUpDumpLine
;***********************************************************
; Function Name: <interrupt handler for External Interrupt0>
; Function Description: This function is responsible
; for handling a rising edge on the Ext Interrupt 0. This
; routine simply returns, since we just want to wake up
; whenever the VSYNC transitions (meaning the start of a new
; frame).
; Inputs: none
; Outputs: none
;***********************************************************
SIG_INTERRUPT2:
; This will wake us up when VSYNC transitions high...we just want to return
reti
;***********************************************************
; Function Name: <interrupt handler for External Interrupt1>
; Function Description: This function is responsible
; for handling a falling edge on the Ext Interrupt 1. This
; routine simply returns, since we just want to wake up
; whenever the HREF transitions (meaning the pixels
; are starting after VSYNC transitioned, and we need to
; start acquiring the pixel blocks
; Inputs: none
; Outputs: none
;***********************************************************
SIG_INTERRUPT3:
; This will wake us up when HREF transitions high...we just want to return
reti ;(4)
;***********************************************************
; Function Name: <interrupt handler for Timer1 overflow>
; Function Description: This function is responsible
; for handling the Timer1 overflow (hooked up to indicate
; when we have reached the end of a line of pixel data,
; since PCLK is hooked up to overflow TCNT1 after 176
; pixels). This routine generates an acquire line complete
; event in the fastEventBitmask, which is streamlined for
; efficiency reasons.
;***********************************************************
SIG_OVERFLOW1:
lds tmp1,fastEventBitmask ; set a flag indicating
ori tmp1,FEV_ACQUIRE_LINE_COMPLETE ; a line is complete
sts fastEventBitmask,tmp1
set ; set the T bit in SREG
reti
; This is the default handler for all interrupts that don't
; have handler routines specified for them.
.global __vector_default
__vector_default:
reti
.end
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -