firmware  v0.1.2
Chromation Spectrometer Dev-Kit
test_Usb.c
1 #include "unity.h" // unit test framework
2 #include "Mock.h" // function faking framework
3 #include "test_Usb.h"
4 #include "Usb.h"
5 #include "ReadWriteBits.h"
6 
7 /* =====[ Test Helpers ]===== */
8 static void _AssertCall(uint16_t num, char const * name)
9 {
11  // Put num and name in the message displayed if test fails
12  GString *message = g_string_new(NULL);
13  g_string_append_printf(message, "`%s` is not call %d", name, num);
14  // Perform the test
15  TEST_ASSERT_TRUE_MESSAGE(
16  AssertCall(mock, num, name),
17  message->str
18  );
19  // Free memory used by GString
20  g_string_free(message, true);
21 }
22 static void _AssertArg(uint16_t call_n, uint8_t arg_n, void *pval)
23 {
25 
62  GString *msg = g_string_new(NULL);
63  g_string_printf(msg, "Expect different value for call %d arg %d.", call_n, arg_n);
64  // I cannot print the expected value without asking the
65  // caller to include the type as a string. Better to keep the
66  // arg list short. Call and arg number are good enough.
67  TEST_ASSERT_TRUE_MESSAGE(
68  AssertArg(mock, call_n, arg_n, pval),
69  msg->str
70  );
71  g_string_free(msg, true);
72 }
73 /* =====[ setup_bit_val ]===== */
74 enum bit_val {LOW, HIGH}; typedef enum bit_val bit_val;
75 static void setup_bit_val( usb_reg reg, usb_pin bit, bit_val v )
76 {
78 
88  GString *msg = g_string_new(NULL);
89  g_string_printf(msg, "Bit must be %s when the test starts", v ? "HIGH" : "LOW");
90  if (HIGH == v)
91  {
92  SetBit(reg, bit);
93  TEST_ASSERT_BIT_HIGH_MESSAGE(bit, *reg, msg->str);
94  }
95  else if (LOW == v)
96  {
97  ClearBit(reg, bit);
98  TEST_ASSERT_BIT_LOW_MESSAGE(bit, *reg, msg->str);
99  }
100  else
101  {
102  g_string_printf(msg, "Test setup with invalid bit value: %d? ", v);
103  g_string_append_printf(msg, "Bit value must be LOW or HIGH.");
104  TEST_FAIL_MESSAGE(msg->str);
105  }
106  g_string_free(msg, true);
107 }
108 /* =====[ test_bit_val_msg ]===== */
109 static void test_bit_val_msg(
110  usb_reg reg,
111  usb_pin bit,
112  bit_val v,
113  char * bit_name )
114 {
116  // Put bit_name in the message displayed if test fails
117  GString *msg = g_string_new(NULL);
118  // Fail test if v is not HIGH or LOW
119  if ((HIGH != v) && (LOW != v))
120  {
121  // Invalid test fail message
122  g_string_printf(
123  msg, "Invalid bit value `%s` = %d", bit_name, v
124  );
125  g_string_append_printf(msg, "Bit value must be LOW or HIGH.");
126  TEST_FAIL_MESSAGE(msg->str);
127  }
128  else
129  {
130  // Test fail message
131  g_string_printf(msg, "Expect `%s` (bit %d) ", bit_name, bit);
132  g_string_append_printf(
133  msg, "%s, was %s",
134  v ? "HIGH" : "LOW",
135  v ? "LOW" : "HIGH"
136  );
137  if ((HIGH == v) && BitIsSet(reg, bit)) TEST_PASS();
138  else if ((LOW == v) && BitIsClear(reg, bit)) TEST_PASS();
139  else TEST_FAIL_MESSAGE(msg->str);
140  }
141  g_string_free(msg, true);
142 }
143 
144 // ---Run_Usb_Private_Ft_tests---
145 
146 /* =====[ _FtClockDatabus ]===== */
147 void FtClockDatabus_drives_FtClock_HIGH_if_direction_is_FtDrive(void)
148 {
149  /* =====[ Setup ]===== */
150  setup_bit_val(FtCtrl_port, FtClock, LOW);
151  /* =====[ Operate ]===== */
152  _FtClockDatabus(FtDrive);
153  /* =====[ Test ]===== */
154  test_bit_val_msg(FtCtrl_port, FtClock, HIGH, "FtClock");
155 }
156 void FtClockDatabus_drives_FtClock_LOW_if_direction_is_FtSample(void)
157 {
158  /* =====[ Setup ]===== */
159  setup_bit_val(FtCtrl_port, FtClock, HIGH);
160  /* =====[ Operate ]===== */
161  _FtClockDatabus(FtSample);
162  /* =====[ Test ]===== */
163  test_bit_val_msg(FtCtrl_port, FtClock, LOW, "FtClock");
164 }
165 
166 /* =====[ _FtReadDatabus ]===== */
167 void FtReadDatabus_copies_databus_pin_values_to_address_pbyte(void)
168 {
169  /* =====[ Setup ]===== */
170  *FtData_pin = 0xab;
171  /* =====[ Operate ]===== */
172  uint8_t byte = 0; uint8_t * pbyte = &byte;
173  _FtReadDatabus(pbyte);
174  /* =====[ Test ]===== */
175  TEST_ASSERT_EQUAL_HEX8(*FtData_pin, byte);
176 }
177 
178 /* =====[ _FtWriteDatabus ]===== */
179 void FtWriteDatabus_outputs_byte_on_databus_pins(void)
180 {
181  /* =====[ Setup ]===== */
182  *FtData_port = 0x00;
183  /* =====[ Operate ]===== */
184  uint8_t byte = 0xab;
185  _FtWriteDatabus(byte);
186  /* =====[ Test ]===== */
187  TEST_ASSERT_EQUAL_HEX8(byte, *FtData_port);
188 }
189 
190 /* =====[ _FtDatabusPinDirection ]===== */
191 void FtDatabusPinDirection_makes_databus_pins_outputs_if_direction_is_FtOut(void)
192 {
193  /* =====[ Setup ]===== */
194  *FtData_ddr = 0x00; // start with pins as inputs
195  /* =====[ Operate ]===== */
196  _FtDatabusPinDirection(FtOut);
197  /* =====[ Test ]===== */
198  TEST_ASSERT_EQUAL_HEX8(0xFF, *FtData_ddr);
199 }
200 void FtDatabusPinDirection_makes_databus_pins_inputs_if_direction_is_FtIn(void)
201 {
202  /* =====[ Setup ]===== */
203  *FtData_ddr = 0xFF; // start with pins as outputs
204  /* =====[ Operate ]===== */
206  /* =====[ Test ]===== */
207  TEST_ASSERT_EQUAL_HEX8(0x00, *FtData_ddr);
208 }
209 
210 // ---Run_Usb_Ft_tests---
211 
212 /* =====[ FtSelectFT221X ]===== */
213 void FtSelectFT221X_drives_FtChipSelect_LOW(void)
214 {
215  /* =====[ Setup ]===== */
216  setup_bit_val(FtCtrl_port, FtChipSelect, HIGH);
217  /* =====[ Operate ]===== */
218  FtSelectFT221X();
219  /* =====[ Test ]===== */
220  test_bit_val_msg(FtCtrl_port, FtChipSelect, LOW, "FtChipSelect");
221 }
222 
223 /* =====[ FtUnselectFT221X ]===== */
224 void FtUnselectFT221X_drives_FtChipSelect_HIGH(void)
225 {
226  /* =====[ Setup ]===== */
227  setup_bit_val(FtCtrl_port, FtChipSelect, LOW);
228  /* =====[ Operate ]===== */
230  /* =====[ Test ]===== */
231  test_bit_val_msg(FtCtrl_port, FtChipSelect, HIGH, "FtChipSelect");
232 }
233 
234 /* =====[ FtBusTurnaround ]===== */
235 void FtBusTurnaround_clocks_one_cycle_to_signal_data_drive_then_data_sample(void)
236 {
237  puts("Drive clock to signal Data-Drive then Data-Sample:\n");
238  puts("- FtDrive: rising edge");
239  puts("- FtSample: falling edge");
240  /* =====[ Operate ]===== */
241  FtBusTurnaround();
242  /* PrintAllCalls(mock); */
243  /* =====[ Test ]===== */
244  uint16_t call_n; uint8_t direction;
245  //
246  call_n = 1;
247  SilentAssertCall(mock, call_n, "_FtClockDatabus");
248  //
249  direction = FtDrive;
250  _AssertArg(call_n, 1, &direction);
251  //
252  call_n++;
253  SilentAssertCall(mock, call_n, "_FtClockDatabus");
254  //
255  direction = FtSample;
256  _AssertArg(call_n, 1, &direction);
257 }
258 
259 /* =====[ FtIsOk ]===== */
260 void FtIsOk_returns_true_if_FtMiso_is_LOW(void)
261 {
262  setup_bit_val(FtCtrl_pin, FtMiso, LOW);
263  TEST_ASSERT_TRUE(FtIsOk());
264 }
265 void FtIsOk_returns_false_if_FtMiso_is_HIGH(void)
266 {
267  setup_bit_val(FtCtrl_pin, FtMiso, HIGH);
268  TEST_ASSERT_FALSE(FtIsOk());
269 }
270 
271 /* =====[ FtRead ]===== */
272 void FtRead_clocks_one_byte_out_of_the_FT221X(void)
273 {
274  /* =====[ Operate ]===== */
275  uint8_t byte = 0; uint8_t *pbyte = &byte;
276  FtRead(pbyte);
277  /* PrintAllCalls(mock); */
278  /* =====[ Test ]===== */
279  uint16_t call_n; uint8_t direction;
280  //
281  call_n = 1;
282  SilentAssertCall(mock, call_n, "_FtClockDatabus");
283  //
284  direction = FtDrive;
285  _AssertArg(call_n, 1, &direction);
286  //
287  call_n = 2;
288  SilentAssertCall(mock, call_n, "_FtClockDatabus");
289  //
290  direction = FtSample;
291  _AssertArg(call_n, 1, &direction);
292  //
293 }
294 void FtRead_stores_the_byte_at_address_pbyte(void)
295 {
296  /* =====[ Operate ]===== */
297  uint8_t byte = 0xcd; uint8_t *pbyte = &byte;
298  FtRead(pbyte);
299  /* =====[ Test ]===== */
300  uint16_t call_n = 3;
301  SilentAssertCall(mock, call_n, "_FtReadDatabus");
302  //
303  _AssertArg(call_n, 1, &pbyte);
304  // See test of _FtReadDatabus to confirm byte==*FtData_pin.
305  // Cannot test this here because _FtReadDatabus is faked.
306 }
307 
308 /* =====[ FtWrite ]===== */
309 void FtWrite_signals_to_drive_data_onto_the_databus(void)
310 {
311  /* =====[ Operate ]===== */
312  FtWrite(0xab);
313  /* =====[ Test ]===== */
314  uint16_t call_n; uint8_t direction;
315  //
316  call_n = 1;
317  SilentAssertCall(mock, call_n, "_FtClockDatabus");
318  //
319  direction = FtDrive;
320  _AssertArg(call_n, 1, &direction);
321 }
322 void FtWrite_sets_microcontroller_databus_pins_as_outputs(void)
323 {
324  /* =====[ Operate ]===== */
325  FtWrite(0xab);
326  /* =====[ Test ]===== */
327  uint16_t call_n = 2;
328  SilentAssertCall(mock, call_n, "_FtDatabusPinDirection");
329  uint8_t pin_direction = FtOut;
330  _AssertArg(call_n, 1, &pin_direction);
331 }
332 void FtWrite_outputs_byte_on_databus_pins(void)
333 {
334  /* =====[ Operate ]===== */
335  uint8_t byte = 0xab;
336  FtWrite(byte);
337  /* =====[ Test ]===== */
338  uint16_t call_n = 3;
339  SilentAssertCall(mock, call_n, "_FtWriteDatabus");
340  _AssertArg(call_n, 1, &byte);
341 }
342 void FtWrite_signals_FT221X_to_sample_the_databus(void)
343 {
344  /* =====[ Operate ]===== */
345  FtWrite(0xab);
346  /* =====[ Test ]===== */
347  uint16_t call_n; uint8_t direction;
348  //
349  call_n = 4;
350  SilentAssertCall(mock, call_n, "_FtClockDatabus");
351  //
352  direction = FtSample;
353  _AssertArg(call_n, 1, &direction);
354 }
355 void FtWrite_sets_microcontroller_databus_pins_as_inputs(void)
356 {
357  /* =====[ Operate ]===== */
358  FtWrite(0xab);
359  /* =====[ Test ]===== */
360  uint16_t call_n = 5;
361  SilentAssertCall(mock, call_n, "_FtDatabusPinDirection");
362  uint8_t pin_direction = FtIn;
363  _AssertArg(call_n, 1, &pin_direction);
364 }
365 
366 // ---Run_Usb_API_tests---
367 
368 /* =====[ UsbRxbufferIsEmpty ]===== */
369 void UsbRxbufferIsEmpty_returns_true_if_pin_FT1248_MISO_is_HIGH(void)
370 {
371  /* =====[ Setup ]===== */
372  SetBit(FtCtrl_pin, FtMiso);
373  /* =====[ Operate and Test ]===== */
374  TEST_ASSERT_TRUE(UsbRxbufferIsEmpty());
375 }
376 void UsbRxbufferIsEmpty_returns_false_if_pin_FT1248_MISO_is_LOW(void)
377 {
378  /* =====[ Setup ]===== */
379  ClearBit(FtCtrl_pin, FtMiso);
380  /* =====[ Operate and Test ]===== */
381  TEST_ASSERT_FALSE(UsbRxbufferIsEmpty());
382 }
383 
384 /* =====[ UsbTxbufferIsFull ]===== */
385 void UsbTxbufferIsFull_returns_true_if_pin_MIOSIO0_is_HIGH(void)
386 {
387  /* =====[ Setup ]===== */
388  SetBit(FtData_pin, FtMiosio0);
389  /* =====[ Operate and Test ]===== */
390  TEST_ASSERT_TRUE(UsbTxbufferIsFull());
391 }
392 void UsbTxbufferIsFull_returns_false_if_pin_MIOSIO0_is_LOW(void)
393 {
394  /* =====[ Setup ]===== */
395  ClearBit(FtData_pin, FtMiosio0);
396  /* =====[ Operate and Test ]===== */
397  TEST_ASSERT_FALSE(UsbTxbufferIsFull());
398 }
399 
400 /* =====[ UsbReadByte ]===== */
401 void UsbReadByte_selects_the_FT221X(void)
402 {
403  /* =====[ Operate ]===== */
404  uint8_t byte = 0; uint8_t * pbyte = &byte;
405  UsbReadByte(pbyte);
406  /* =====[ Test ]===== */
407  uint16_t call_n = 0;
408  _AssertCall(++call_n, "FtSelectFT221X");
409 }
410 void UsbReadByte_drives_databus_with_read_command(void)
411 {
412  puts("\n*Read command is* `0xc6`");
413  /* =====[ Operate ]===== */
414  uint8_t byte = 0; uint8_t * pbyte = &byte;
415  UsbReadByte(pbyte);
416  /* =====[ Test ]===== */
417  uint16_t call_n = 0;
418  SilentAssertCall(mock, ++call_n, "FtSelectFT221X");
419  SilentAssertCall(mock, ++call_n, "FtWrite");
420  uint8_t read_cmd = FtReadCmd;
421  _AssertArg(call_n, 1, &read_cmd);
422 }
423 void UsbReadByte_signals_FT221X_to_sample_the_databus(void)
424 {
425  /* =====[ Operate ]===== */
426  uint8_t byte = 0; uint8_t * pbyte = &byte;
427  UsbReadByte(pbyte);
428  /* =====[ Test ]===== */
429  uint16_t call_n = 0;
430  SilentAssertCall(mock, ++call_n, "FtSelectFT221X");
431  SilentAssertCall(mock, ++call_n, "FtWrite");
432  _AssertCall(++call_n, "FtBusTurnaround");
433 }
434 void UsbReadByte_reads_the_byte_if_data_transfer_status_is_OK(void)
435 {
436  /* =====[ Operate ]===== */
437  uint8_t byte = 0; uint8_t * pbyte = &byte;
438  UsbReadByte(pbyte);
439  /* =====[ Test ]===== */
440  uint16_t call_n = 0;
441  SilentAssertCall(mock, ++call_n, "FtSelectFT221X");
442  SilentAssertCall(mock, ++call_n, "FtWrite");
443  SilentAssertCall(mock, ++call_n, "FtBusTurnaround");
444  _AssertCall(++call_n, "FtIsOk");
445  TEST_FAIL_MESSAGE("Implement Test");
446  // TODO(sustainablelab): Test read is called only if FtIsOk() returns OK
447 }
448 void UsbReadByte_unselects_the_FT221X(void)
449 {
450  /* =====[ Operate ]===== */
451  uint8_t byte = 0; uint8_t * pbyte = &byte;
452  UsbReadByte(pbyte);
453  /* =====[ Test ]===== */
454  uint16_t call_n = 0;
455  SilentAssertCall(mock, ++call_n, "FtSelectFT221X");
456  SilentAssertCall(mock, ++call_n, "FtWrite");
457  SilentAssertCall(mock, ++call_n, "FtBusTurnaround");
458  SilentAssertCall(mock, ++call_n, "FtIsOk");
459  _AssertCall(++call_n, "FtUnselectFT221X");
460 }
461 void UsbReadByte_returns_either_FtOK_if_pbyte_has_the_read_data_or_FtError_if_Usb_receive_buffer_was_empty(void)
462 {
463  TEST_FAIL_MESSAGE("Implement Test");
464 }
465 
466 /* =====[ UsbWriteByte ]===== */
467 
468 
usb-bridge communicates over USB via FTDI USB Bridge IC FT221X
bool FtIsOk(void)
Definition: Usb.h:149
void _FtClockDatabus(uint8_t direction)
Definition: Usb.h:84
bool UsbRxbufferIsEmpty(void)
Definition: Usb.h:237
bool UsbTxbufferIsFull(void)
Definition: Usb.h:245
void FtSelectFT221X(void)
Definition: Usb.h:118
uint8_t UsbReadByte(uint8_t *pbyte)
Definition: Usb.h:262
void _FtWriteDatabus(uint8_t byte)
Definition: Usb.h:101
void FtUnselectFT221X(void)
Definition: Usb.h:125
void _FtReadDatabus(uint8_t *pbyte)
Definition: Usb.h:94
void FtWrite(uint8_t byte)
Definition: Usb.h:209
void FtRead(uint8_t *pbyte)
Definition: Usb.h:197
void FtBusTurnaround(void)
Definition: Usb.h:136
void _FtDatabusPinDirection(uint8_t pin_direction)
Definition: Usb.h:108