?? caminterfaceasm.s
字號(hào):
; Module Name: CanInterfaceAsm.S
; Module Date: 04/14/2004
; Module Auth: John Orlando
; Copyright (c) 2004 John Orlando All Rights Reserved
;
; 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 0x80
#define HREF_INTERRUPT_DISABLE_MASK 0x7F
#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(PINB)
#define PIXEL_RUN_START_INITIAL 0x50 ; This value causes our pixel counter (TCNT1)
; to overflow after 176 (horizontal) pixels
#define RED_MEM_OFFSET 0x00
#define GREEN_MEM_OFFSET 0x10
#define BLUE_MEM_OFFSET 0x20
; 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
; As pixel blocks are sampled, the red, green, and blue values are
; used to index into their respective color maps. The color maps
; return values that can be logically ANDed together so that a
; particular RGB triplet will result in a single bit being set
; after the AND operation. This single bit indicates which color
; the RGB triplet represents. It is also possible for no bits to
; be set after the AND process, indicating that the RGB triplet
; does not map to any of the colors configured in the color map.
; This isn't quite as fast as a pure RGB lookup table, but
; it then again it doesn't require 2^12 (4-bits for each color
; channel) bytes to store the lookup table. It takes just a few
; more cycles, and only requires 48 bytes of precious RAM (16
; per color channel, since our resolution on each color channel
; is only 4-bits). Not bad....for more information, see:
; http://www.cs.cmu.edu/~trb/papers/wirevision00.pdf for more
; information on this color segmentation technique.
; 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
greenData = 20
blueData = 21
colorMapLow = 22
colorMapHigh = 23
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_waitForNewTrackingFrame
.global CamIntAsm_waitForNewDumpFrame
.global CamIntAsm_acquireDumpLine
.global CamIntAsm_acquireTrackingLine
.global SIG_INTERRUPT0
.global SIG_INTERRUPT1
.global SIG_OVERFLOW0
.global SIG_OVERFLOW1
;*****************************************************************
; Function Name: CamIntAsm_waitForNewTrackingFrame
; 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
; the acquireLine function, where the system waits for
; an "HREF sleep" that we use to synchronize with the
; data.
; Inputs: r25 - MSB of currentLineBuffer
; r24 - LSB of currentLineBuffer
; r23 - MSB of colorMap
; r22 - LSB of colorMap
; Outputs: none
; NOTES: This function doesn't really return...it sorta just
; floats into the acquireLine function after the "VSYNC sleep"
; is awoken, then begins processing the line data. Once
; 176 pixels are sampled (and the counter overflows), then
; an interrupt will occur, the 'T' bit in the SREG will be
; set, and the function will return.
;*****************************************************************
CamIntAsm_waitForNewTrackingFrame:
sbi _SFR_IO_ADDR(PORTD),PD6 ; For testing...
cbi _SFR_IO_ADDR(PORTD),PD6
sleep
;*****************************************************************
; REMEMBER...everything from here on out is critically timed to be
; synchronized with the flow of pixel data from the camera...
;*****************************************************************
CamIntAsm_acquireTrackingLine:
brts _cleanUp
sbi _SFR_IO_ADDR(PORTD),PD6 ; For testing...
cbi _SFR_IO_ADDR(PORTD),PD6
; The line is about to start...
ldi pixelCount,0 ; Initialize the RLE stats...
ldi pixelRunStart,PIXEL_RUN_START_INITIAL ; Remember, we always calculate
; the pixel run length as
; TCNT1L - pixelRunStart
ldi lastColor,0x00 ; clear out the last color before we start
mov XH,currLineBuffHigh ; Load the pointer to the current line
mov XL,currLineBuffLow ; buffer into the X pointer regs
mov ZH,colorMapHigh ; Load the pointers to the membership
mov ZL,colorMapLow ; lookup tables (ZL and YL will be overwritten
mov YH,colorMapHigh ; as soon as we start reading data) to Z and Y
in tmp1, _SFR_IO_ADDR(TIMSK) ; enable TIMER1 to start counting
ori tmp1, ENABLE_PCLK_TIMER1_OVERFLOW_BITMASK ; external PCLK pulses and interrupt on
out _SFR_IO_ADDR(TIMSK),tmp1 ; overflow
ldi tmp1,PIXEL_RUN_START_INITIAL ; set up the TCNT1 to overflow (and
ldi tmp2,0xFF ; interrupts) after 176 pixels
out _SFR_IO_ADDR(TCNT1H),tmp2
out _SFR_IO_ADDR(TCNT1L),tmp1
mov YL,colorMapLow
in tmp1, _SFR_IO_ADDR(GICR) ; enable the HREF interrupt...remember, we
; only use this interrupt to synchronize
; the beginning of the line
ori tmp1, HREF_INTERRUPT_ENABLE_MASK
out _SFR_IO_ADDR(GICR), tmp1
;*******************************************************************************************
; Track Frame handler
;*******************************************************************************************
_trackFrame:
sbi _SFR_IO_ADDR(PORTD),PD6
sleep ; ...And we wait...
; Returning from the interrupt/sleep wakeup will consume
; 14 clock cycles (7 to wakeup from idle sleep, 3 to vector, and 4 to return)
; Disable the HREF interrupt
cbi _SFR_IO_ADDR(PORTD),PD6
in tmp1, _SFR_IO_ADDR(GICR)
andi tmp1, HREF_INTERRUPT_DISABLE_MASK
out _SFR_IO_ADDR(GICR), tmp1
; A couple of NOPs are needed here to sync up the pixel data...the number (2)
; of NOPs was determined emperically by trial and error.
nop
nop
_acquirePixelBlock: ; Clock Cycle Count
in ZL,RB_PORT ; sample the red value (PINB) (1)
in YL,G_PORT ; sample the green value (PINC) (1)
andi YL,0x0F ; clear the high nibble (1)
ldd color,Z+RED_MEM_OFFSET ; lookup the red membership (2)
in ZL,RB_PORT ; sample the blue value (PINB) (1)
ldd greenData,Y+GREEN_MEM_OFFSET ; lookup the green membership (2)
ldd blueData,Z+BLUE_MEM_OFFSET ; lookup the blue membership (2)
and color,greenData ; mask memberships together (1)
and color,blueData ; to produce the final color (1)
brts _cleanUpTrackingLine ; if some interrupt routine has (1...not set)
; come in and set our T flag in
; SREG, then we need to hop out
; and blow away this frames data (common cleanup)
cp color,lastColor ; check to see if the run continues (1)
breq _acquirePixelBlock ; (2...equal)
; ___________
; 16 clock cycles
; (16 clock cycles = 1 uS = 1 pixelBlock time)
; Toggle the debug line to indicate a color change
sbi _SFR_IO_ADDR(PORTD),PD6
nop
cbi _SFR_IO_ADDR(PORTD),PD6
mov tmp2,pixelRunStart ; get the count value of the
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -