⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 caminterfaceasm.s

📁 The AVRcam source files were built using the WinAVR distribution (version 3.3.1 of GCC). I haven t
💻 S
📖 第 1 页 / 共 2 页
字号:
;       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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -