firmware  v0.1.2
Chromation Spectrometer Dev-Kit
vis-spi-out.c
Go to the documentation of this file.
1 
2 // Pick a sensor
3 #ifdef LIS // <------------- $ make sensor=LIS
4 #include "LisConfigs.h"
5 #endif
6 #ifdef S13131 // <---------- $ make sensor=S13131
7 #endif
8 
9 #include "Hardware.h" // Hardware i/o definitions
10 #include "StatusCodes.h" // Python-to-Firmware communication status codes
11 #include "BiColorLed.h"
12 #include "Spi.h"
13 #include "SpiSlave.h"
14 #include "UartSpi.h"
15 #ifdef LIS
16 #include "Lis.h"
17 #endif
18 #ifdef S13131
19 #include "S13131.h"
20 #endif
21 #include <stdlib.h> // defines NULL
22 #include "Queue.h" // SPI communication queue
23 
24 #include "VisCmd.h"
25 
27 volatile Queue_s * SpiFifo;
29 #define max_length_of_queue 24 // bytes
31 volatile uint8_t spi_rx_buffer[max_length_of_queue];
32 
33 static void setup(void);
34 static void loop(void);
35 static void setup_IndicatorLEDs(void);
36 static void setup_SpiCommunication(void);
37 static void setup_DetectorReadout(void);
38 int main()
39 {
40  setup();
41  while(1) loop();
42 }
43 void setup(void)
44 {
48 }
49 void loop(void)
50 {
51  // Catch errors
52  if (QueueIsFull(SpiFifo)) // 7 cycles
53  {
54  // TODO: replace with an error handler
55  BiColorLedRed(led_0);
56  }
57  // Idle until a command is received
58  while (QueueIsEmpty(SpiFifo)); // 5 cycles
59  // Execute the command.
60  // BUSY
61  BiColorLedOff(led_0);
62  switch(QueuePop(SpiFifo))
63  {
64  default: SpiSlaveTxByte(ERROR); break;
65  case 0: NullCommand(); break;
66  case 3: GetSensorLED(); break;
67  case 4: SetSensorLED(); break;
68 #ifdef LIS
69  case 7: GetSensorConfig(); break;
70  case 8: SetSensorConfig(); break;
71 #endif
72  case 9: GetExposure(); break;
73  case 10: SetExposure(); break;
74  case 11: CaptureFrame(); break;
75  case 12: AutoExposure(); break;
76  case 13: GetAutoExposeConfig(); break;
77  case 14: SetAutoExposeConfig(); break;
78  case 15: GetSensorHash(); break;
79  /* default: ReplyCommandInvalid(); break; */
80  // ---Expected Assembly---
81  // Context:
82  // 1. 0x19e is the start of loop()
83  // 2. QueuePop puts `cmd` byte in r24
84  // Handle case 0:
85  // 1de: and r24, r24; `cmd` is in r24
86  // 1e0: breq .-68 ; 0x19e <main+0xf8>
87  // Handle case 8:
88  // 1e2: cpi r24, 0x08 ; 8
89  // 1e4: breq .+34 ; 0x208 <main+0x162>
90  // Default case:
91  // 1e6: out 0x2e, r19 ; 46
92  // Total number of cycles: 7
93  // Total number of instructions: 5
94  }
95  // DONE
96  BiColorLedOn(led_0);
97 }
98 ISR(SPI_STC_vect) // Serial Transfer Complete
99 {
108 }
110 {
112  BiColorLedOn(led_0); // sbi 0x07, 0
113  BiColorLedOn(led_1); // sbi 0x07, 1
114  BiColorLedGreen(led_0); // cbi 0x08, 0
115  BiColorLedGreen(led_1); // cbi 0x08, 1
116 }
118 {
132  // Configure as SPI slave, interrupts run `ISR(SPI_STC_vect)`
133  SpiSlaveInit();
134  // Queue incoming SPI bytes in a FIFO buffer.
136 }
138 {
157  // Talk to ADC with SPI interface using UART SPIM
158  UartSpiInit();
159 #ifdef LIS
160  // Power up the LIS-770i and drive with a 50kHz clock
161  LisInit();
162 #endif
163 #ifdef S13131
164  S13131PinSetup();
165  S13131StartClocking();
166 #endif
167  // Initialize exposure time to 1 millisecond
168  exposure_ticks = 50; // 50 ticks = (1.0e-3 s)/(20.0e-6 s/tick)
169  // ---Expected Assembly---
170  // ldi r24, 0x32 ; 50
171  // ldi r25, 0x00 ; 0
172  // sts 0x011D, r25 ; 0x80011d <exposure_ticks+0x1>
173  // 1c8: sts 0x011C, r24 ; 0x80011c <exposure_ticks>
174 
175 #ifdef LIS
176  // Initialize LIS-770i configuration globals
177  binning = BINNING_ON;
178  gain = GAIN_1X;
179  active_rows = ALL_ROWS_ACTIVE;
180  // ---Expected Assembly---
181  // ldi r24, 0x01 ; 1
182  // sts 0x011E, r24 ; 0x80011e <binning>
183  // sts 0x0140, r24 ; 0x800140 <gain>
184  // ldi r24, 0x1F ; 31
185  // sts 0x013B, r24 ; 0x80013b <active_rows>
186 
187  // Program LIS-770i with above configuration
188  LisWriteConfig();
189 #endif
190 #ifdef S13131
191  // No configuration
192 #endif
193  /* ------------------------------- */
194  /* | Initialize AutoExposeConfig | */
195  /* ------------------------------- */
196  // Initialize default auto-expose maximum number of tries
197  max_tries = 12;
198 #ifdef LIS
199  // Initialize default auto-expose pixel range to all 392 pixels.
200  // Recommend user application trims pixel range to match wavelength map.
201  start_pixel = 7; // first 6 pixels are optically meaningless
202  stop_pixel = 392;
203 #endif
204 #ifdef S13131
205  start_pixel = 1;
206  stop_pixel = 512;
207 #endif
208  // Initialize default auto-expose target peak range to 46420 ± 3277 counts
209  target = 46420;
210  target_tolerance = 3277;
211  // Hard-code conservative estimate on dark offset
212  // AutoExpose calculates gain ONLY when signal is above max_dark.
213  // SetAutoExposeConfig guarantees target is not below max_dark.
214  max_dark = 4500;
215  // Hard-code minimum exposure time used by auto-expose.
216 #ifdef LIS
217  // keep lower limit well-away from 1 cycle
218  min_exposure = 5; // cycles
219 #endif
220 #ifdef S13131
221  // 9 is the minimum set by the internal S13131-512 logic
222  min_exposure = 9; // cycles
223 #endif
224  // Initialize default auto-expose maximum exposure time to try.
225  // upper limit is 1.3s, but 200ms is a practical default limit
226  max_exposure = 10000; // cycles
227 }
uint16_t max_exposure
max_exposure is 1.31 seconds (65535 20µs-cycles) This is the 16-bit limit, UINT16_MAX,...
Definition: AutoExpose.c:12
uint16_t start_pixel
AutoExpose() ignores pixels below start_pixel.
Definition: AutoExpose.c:6
uint8_t max_tries
maximum number of tries before AutoExpose() gives up
Definition: AutoExpose.c:5
uint16_t stop_pixel
AutoExpose() ignores pixels above stop_pixel.
Definition: AutoExpose.c:7
uint16_t target_tolerance
target ± target_tolerance is the target peak counts range for AutoExpose().
Definition: AutoExpose.c:9
uint16_t max_dark
max_dark is a conservative estimate on the largest dark offset
Definition: AutoExpose.c:10
uint16_t target
target peak counts for AutoExpose().
Definition: AutoExpose.c:8
uint16_t min_exposure
min_exposure is 100 microseconds (five 20µs-cycles) This is a safe lower limit to avoid dead frames.
Definition: AutoExpose.c:11
void BiColorLedOff(bicolorled_num led)
Definition: BiColorLed.h:28
void BiColorLedGreen(bicolorled_num led)
Definition: BiColorLed.h:35
void BiColorLedRed(bicolorled_num led)
Definition: BiColorLed.h:42
void BiColorLedOn(bicolorled_num led)
Definition: BiColorLed.h:21
See LisConfig.h for context.
void LisWriteConfig(void)
Definition: Lis.h:475
uint16_t exposure_ticks
LIS-770i exposure time.
Definition: Lis.c:32
void LisInit(void)
Definition: Lis.h:416
uint8_t QueuePop(volatile Queue_s *SpiFifo)
Definition: Queue.h:139
bool QueueIsFull(volatile Queue_s *SpiFifo)
Definition: Queue.h:86
void QueuePush(volatile Queue_s *SpiFifo, uint8_t data_to_push)
Definition: Queue.h:122
volatile Queue_s * QueueInit(volatile uint8_t *buffer, uint16_t const buffer_size_in_bytes)
Definition: Queue.h:51
bool QueueIsEmpty(volatile Queue_s *SpiFifo)
Definition: Queue.h:95
spi_ptr Spi_SPDR
SPI Data Register.
void SpiSlaveInit(void)
Definition: SpiSlave.h:118
void SpiSlaveTxByte(uint8_t input_byte)
Definition: SpiSlave.h:150
Spi.h declares SPI hardware types and variables common to the SPI Master and SPI Slave.
See StatusCode.h for context.
void UartSpiInit(void)
Definition: UartSpi.h:164
void CaptureFrame(void)
Definition: UsbCmd.h:514
void GetSensorConfig(void)
Definition: UsbCmd.h:229
void GetSensorLED(void)
Definition: UsbCmd.h:124
void SetExposure(void)
Definition: UsbCmd.h:466
void SetSensorLED(void)
Definition: UsbCmd.h:175
void NullCommand(void)
Definition: UsbCmd.h:50
void SetSensorConfig(void)
Definition: UsbCmd.h:307
void GetExposure(void)
Definition: UsbCmd.h:422
Queue uses a byte array as a circular buffer.
Definition: Queue.h:27
vis-spi-out.c includes this file to pick up the -Hardware.h headers and AVR macros.
volatile Queue_s * SpiFifo
Allocate static memory for the SPI Rx Queue.
Definition: vis-spi-out.c:27
#define max_length_of_queue
Maximum size of the Queue's FIFO buffer is 24 bytes.
Definition: vis-spi-out.c:29
static void setup_DetectorReadout(void)
Definition: vis-spi-out.c:137
static void setup_SpiCommunication(void)
Definition: vis-spi-out.c:117
volatile uint8_t spi_rx_buffer[max_length_of_queue]
Allocate static memory for the Queue's FIFO buffer.
Definition: vis-spi-out.c:31
ISR(SPI_STC_vect)
Definition: vis-spi-out.c:98
static void setup_IndicatorLEDs(void)
Definition: vis-spi-out.c:109