ECE4760 - Laser Projector (ipb7, jcc384, pfc38)  1
Raster Laser Projection
projector.c File Reference
#include "projector.h"

Go to the source code of this file.

Macros

#define DAC_A   (0b0 << 15)
 
#define DAC_B   (0b1 << 15)
 
#define DAC_GAIN_VREF   (0b1 << 13)
 
#define DAC_GAIN_2VREF   (0b0 << 13)
 
#define DAC_ACTIVE   (0b1 << 12)
 
#define DAC_INACTIVE   (0b0 << 12)
 
#define PIXEL_DMA_CHN   (0)
 
#define Y_MIRROR_SPI_CHN   (1)
 
#define Y_MIRROR_SPI_CONFIG   (DAC_A | DAC_GAIN_2VREF | DAC_ACTIVE)
 
#define PIXEL_ON_TIME   (400)
 How many clock ticks the pixel is on. More...
 

Functions

void projector_init ()
 Initialize projector peripherals, variables etc. MUST be called before calling any other projector functions! More...
 
void projector_set_pixel (struct color const color, unsigned int x, unsigned int y)
 Set the color of a pixel at the specified location. More...
 
void __ISR (_DMA0_VECTOR, IPL5SOFT)
 
void __ISR (_CHANGE_NOTICE_VECTOR, IPL5SOFT)
 

Variables

struct color projector_framebuffer [IMAGE_HEIGHT][IMAGE_WIDTH+PHASE_SHIFT_PADDING] = {0}
 

Macro Definition Documentation

§ DAC_A

#define DAC_A   (0b0 << 15)

Definition at line 34 of file projector.c.

§ DAC_ACTIVE

#define DAC_ACTIVE   (0b1 << 12)

Definition at line 38 of file projector.c.

§ DAC_B

#define DAC_B   (0b1 << 15)

Definition at line 35 of file projector.c.

§ DAC_GAIN_2VREF

#define DAC_GAIN_2VREF   (0b0 << 13)

Definition at line 37 of file projector.c.

§ DAC_GAIN_VREF

#define DAC_GAIN_VREF   (0b1 << 13)

Definition at line 36 of file projector.c.

§ DAC_INACTIVE

#define DAC_INACTIVE   (0b0 << 12)

Definition at line 39 of file projector.c.

§ PIXEL_DMA_CHN

#define PIXEL_DMA_CHN   (0)

Definition at line 41 of file projector.c.

§ PIXEL_ON_TIME

#define PIXEL_ON_TIME   (400)

How many clock ticks the pixel is on.

Definition at line 48 of file projector.c.

§ Y_MIRROR_SPI_CHN

#define Y_MIRROR_SPI_CHN   (1)

Definition at line 42 of file projector.c.

§ Y_MIRROR_SPI_CONFIG

#define Y_MIRROR_SPI_CONFIG   (DAC_A | DAC_GAIN_2VREF | DAC_ACTIVE)

Definition at line 43 of file projector.c.

Function Documentation

§ __ISR() [1/2]

void __ISR ( _DMA0_VECTOR  ,
IPL5SOFT   
)

This interrupt is called when all of the pixels from a row have been displayed. The mirror should be moved to the next line, the Timer Gate latch reset, timer reset, and DMA configured for the next row.

We also turn off the lasers clearing the last pixel. This could also be achieved by adding an always-black pixel to the end of the row and having DMA output it, an option that should be considered based on the performance of this solution.

Definition at line 229 of file projector.c.

229  {
230  // acknowledge the INT controller, we're servicing int
231  INTClearFlag(INT_SOURCE_DMA(DMA_CHANNEL0));
232 
233  // turn off the lasers
234  write_pixel(color_blank);
235 
236  current_row = (current_row + 1) % IMAGE_HEIGHT;
237 
238  // move the y-axis mirror to the next row
239  update_y_axis_position(current_row);
240 
241  // reset the Timer Gate Latch
242  mPORTAClearBits(BIT_3); // set the active low reset signal
243  Nop(); Nop(); Nop(); Nop(); // wait for reset to occur - 4 nops is 100ns, an
244  // upper bound on the time the signal has to be
245  // low for the latch to be happy
246  mPORTASetBits(BIT_3); // unset the active low reset signal
247 
248  // prepare the DMA to output the next row
249  configure_dma_for_row(current_row);
250 }
#define IMAGE_HEIGHT
Definition: parameters.h:18
struct color const color_blank
Definition: color.c:30

§ __ISR() [2/2]

void __ISR ( _CHANGE_NOTICE_VECTOR  ,
IPL5SOFT   
)

Definition at line 252 of file projector.c.

252  {
253  if ((PORTA & BIT_4) == BIT_4) {
254  // if the bit is high, the light just went off. The light disappearing is a
255  // low-to-high edge.
256  trigger_row();
257  }
258 
259  // clear the interrupt flag
260  IFS1CLR = BIT_13;
261 }

§ projector_init()

void projector_init ( void  )

Initialize projector peripherals, variables etc. MUST be called before calling any other projector functions!

Definition at line 123 of file projector.c.

123  {
125  /* Set Up Pixel CLock */
127 
128  // Open Timer1 with the following configuration:
129  // - T1_ON :: Timer is turned on
130  // - T1_SOURCE_INT :: Clock source is internal
131  // - T1_PS_1_1 :: Prescalar is 1 to 1 (timer sees PBCLK)
132  //
133  // The timer's period is used to fine-tune how long each pixel lasts;
134  // one pixel displayed every time the timer wraps around.
135  OpenTimer1(T1_ON | T1_SOURCE_INT | T1_PS_1_1, PIXEL_ON_TIME);
136 
137  // set up the pin to reset the Gate Latch, set initially high
138  // (the signal is active low)
139  PORTSetPinsDigitalOut(IOPORT_A, BIT_3);
140  mPORTASetBits(BIT_3);
141 
143  /* Set Up CN */
145 
146  // see reference manual 12.3.3.1
147  CNCONASET = BIT_15; // enable CN on Port A (set bit 15 of CNCON to 1)
148  PORTSetPinsDigitalIn(IOPORT_A, BIT_4); // RA4 is input
149  unsigned int ignore = PORTA; // clear interrupt
150  IPC8SET = ((unsigned int) 5) << 18; // set CN interrupt priority
151  // (IPC6<20:18>=5, defaults to 0 at POR)
152  IFS1CLR = BIT_13; // clear CN interrupt flag (set bit 0 of IFS1 to 0)
153  CNENASET = BIT_4; // enable for RA4 (set bit 4 of CNENA to 1)
154  // see family data sheet 11.1.4
155  IEC1SET = BIT_13; // enable CN interrupt (set bit 0 of IEC1 to 1)
156 
158  /* Set Up DMA */
160 
161  // Set up the pins as an output
162  PORTSetPinsDigitalOut(IOPORT_B, BIT_0 | BIT_1 // red
163  | BIT_2 | BIT_3 // blue
164  | BIT_4 | BIT_5); // green
165 
166  // Configure DMA interrupt vector and enable DMA interrupts on CPU
167  INTSetVectorPriority(INT_VECTOR_DMA(PIXEL_DMA_CHN), INT_PRIORITY_LEVEL_5);
168  INTSetVectorSubPriority(INT_VECTOR_DMA(PIXEL_DMA_CHN),
169  INT_SUB_PRIORITY_LEVEL_3);
170  INTEnable(INT_SOURCE_DMA(PIXEL_DMA_CHN), INT_ENABLED);
171 
172  configure_dma_for_row(0);
173 
175  /* Set Up SPI */
177 
178  // SPI Slave Sync output on pin 26
179  PPSOutput(1, RPB15, SS1);
180 
181  // SPI1 data output on pin 17
182  PPSOutput(2, RPB8, SDO1);
183 
184  // SPI channel 1 channel A drives the y axis control mirror.
185  // The messages we send are 16 bits long (4 control bits, 12 signal bits).
186  // The config flags do the following:
187  // - SPICON_MSTEN :: Set to master mode
188  // - SPICON_MODE16 :: Sets the word size to 16 bits
189  // - SPICON_ON :: Module ON Control
190  // - SPICON_FRMPOL :: Polarity of frame signal
191  // - SPICON_CKP :: Reverse clock edges
192  // - SPICON_FRMEN :: Use automatic framing: Serial clock is always on
193  // even when no data is being sent and Slave Select/CS
194  // pulses before each word
195  // The fpbDiv = 2 sets baud rate to Fpb / fpbDiv.
196  SpiChnOpen(Y_MIRROR_SPI_CHN, SPICON_MSTEN | SPICON_MODE16 | SPICON_ON
197  | SPICON_FRMPOL | SPICON_CKP | SPICON_FRMEN, 2);
198 }
#define PIXEL_ON_TIME
How many clock ticks the pixel is on.
Definition: projector.c:48
#define Y_MIRROR_SPI_CHN
Definition: projector.c:42
#define PIXEL_DMA_CHN
Definition: projector.c:41

§ projector_set_pixel()

void projector_set_pixel ( struct color const  color,
unsigned int  x,
unsigned int  y 
)

Set the color of a pixel at the specified location.

Once a pixels value is changed, the new value will be projected the next time the pixel is output (there is no v-sync).

Parameters
colorColor to be displayed
xNumber of pixels from left side
yNumber of pixels from the top

Definition at line 205 of file projector.c.

206  {
210 }
#define BLUE_PHASE_SHIFT
Shift to the right of the blue laser.
Definition: parameters.h:51
char blue
Definition: color.h:43
char red
Definition: color.h:42
Definition: color.h:41
int16_t y
Definition: joystick.h:42
struct color projector_framebuffer[IMAGE_HEIGHT][IMAGE_WIDTH+PHASE_SHIFT_PADDING]
Definition: projector.c:114
char green
Definition: color.h:44
int16_t x
Definition: joystick.h:41
#define GREEN_PHASE_SHIFT
Shift to the right of the green laser.
Definition: parameters.h:43
#define RED_PHASE_SHIFT
Shift to the right of the red laser.
Definition: parameters.h:35

Variable Documentation

§ projector_framebuffer

struct color projector_framebuffer[IMAGE_HEIGHT][IMAGE_WIDTH+PHASE_SHIFT_PADDING] = {0}

Definition at line 114 of file projector.c.