firmware  v0.1.2
Chromation Spectrometer Dev-Kit
test_SpiSlave.c
Go to the documentation of this file.
1 
5 #include "unity.h"
6 #include "Mock.h" // record call history in "mock"
7 #include "test_SpiSlave.h"
8 #include "Spi.h"
9 #include "SpiSlave.h"
10 #include "ReadWriteBits.h"
11 
12 /* =====[ Check_SpiSlave_plumbing_for_fakes ]===== */
13 void SpiSlave_faked_calls_are_still_available_for_testing(void)
14 {
15  printf("SpiSlave_faked_calls_are_still_available_for_testing:\n");
16  /* =====[ Operate and Test]===== */
18  printf(
19  "1. Tests are able to call "
20  "real version of `EnableSpiInterrupt` "
21  "(compiler successfully outputs `test_SpiSlave.o`).\n"
22  );
23  /* =====[ Operate and Test ]===== */
24  SpiSlaveInit();
25  printf(
26  "2. When tests call `SpiSlaveInit`, it calls "
27  "`EnableSpiInterrupt_fake` (the fake records the call):\n"
28  );
29  uint16_t call_n = 2;
30  TEST_ASSERT_TRUE_MESSAGE(
31  AssertCall(mock, call_n, "EnableSpiInterrupt"),
32  "Expect SpiSlaveInit calls fake which records call name."
33  );
34 }
35 
36 /* =====[ _SignalDataReady ]===== */
37 void SignalDataReady_drives_DataReady_LOW(void)
38 {
39  /* =====[ Setup ]===== */
40  SetBit(Spi_PortOutput, Spi_DataReady);
41  TEST_ASSERT_BIT_HIGH_MESSAGE(
42  Spi_DataReady,
44  "Cannot run test: must start with DataReady HIGH!"
45  );
46  /* =====[ Operate ]===== */
48  /* =====[ Test ]===== */
49  TEST_ASSERT_BIT_LOW(Spi_DataReady, *Spi_PortOutput);
50 }
51 
52 /* =====[ DisableSpiInterrupt ]===== */
53 void DisableSpiInterrupt_clears_the_SPI_Interrupt_Enable_bit(void)
54 {
55  /* =====[ Setup ]===== */
56  SetBit(Spi_SPCR, Spi_InterruptEnable);
57  TEST_ASSERT_BIT_HIGH_MESSAGE(
58  Spi_InterruptEnable,
59  *Spi_SPCR,
60  "Cannot run test: must start with bit HIGH!"
61  );
62  /* =====[ Operate ]===== */
64  /* =====[ Test ]===== */
65  TEST_ASSERT_BIT_LOW(Spi_InterruptEnable, *Spi_SPCR);
66 }
67 
68 /* =====[ EnableSpiInterrupt ]===== */
69 void EnableSpiInterrupt_clears_SPI_interrupt_flag(void)
70 {
71  /* =====[ Operate ]===== */
73  /* =====[ Test ]===== */
74  uint16_t call_n = 1;
75  TEST_ASSERT_TRUE(
76  AssertCall(mock, call_n, "ClearSpiInterruptFlag")
77  );
78 }
79 void EnableSpiInterrupt_enables_interrupt_SPI_Transfer_Complete(void)
80 {
81  /* =====[ Setup ]===== */
82  ClearBit(Spi_SPCR, Spi_InterruptEnable);
83  /* =====[ Operate ]===== */
85  /* =====[ Test ]===== */
86  TEST_ASSERT_BIT_HIGH(Spi_InterruptEnable, *Spi_SPCR);
87 }
88 void EnableSpiInterrupt_consumes_6_cycles(void)
89 {
90  TEST_PASS();
91  // ---Expected Assembly---
92  // cli
93  // in r24, 0x2d ; 45
94  // in r24, 0x2e ; 46
95  // in r24, 0x2c ; 44
96  // ori r24, 0x80 ; 128
97  // out 0x2c, r24 ; 44
98  // Total number of cycles: 6
99  // Total number of instructions: 6
100 }
101 
102 /* =====[ SpiSlaveInit ]===== */
103 void SpiSlaveInit_makes_DataReady_an_output_pin(void)
104 {
105  /* =====[ Setup ]===== */
106  *Spi_PortDirection = 0x00;
107  TEST_ASSERT_BIT_LOW_MESSAGE(
108  Spi_DataReady,
110  "Cannot run test: must start with ddr bit clear!"
111  );
112  /* =====[ Operate ]===== */
113  SpiSlaveInit();
114  /* =====[ Test ]===== */
115  TEST_ASSERT_BIT_HIGH_MESSAGE(
116  Spi_DataReady,
118  "Expect DataReady to be an output."
119  );
120 }
121 void SpiSlaveInit_idles_DataReady_high(void)
122 {
123  /* =====[ Setup ]===== */
124  *Spi_PortOutput = 0x00;
125  TEST_ASSERT_BIT_LOW_MESSAGE(
126  Spi_DataReady,
128  "Cannot run test: must start with port bit clear!"
129  );
130  /* =====[ Operate ]===== */
131  /* printf("Value of Spi_PortOutput before is 0x%02x\n", *Spi_PortOutput); */
132  SpiSlaveInit();
133  /* =====[ Test ]===== */
134  /* printf("Value of Spi_DataReady is pin %d\n", Spi_DataReady); */
135  /* printf("Value of Spi_PortOutput after is 0x%02x\n", *Spi_PortOutput); */
136  TEST_ASSERT_BIT_HIGH_MESSAGE(
137  Spi_DataReady,
139  "Expect DataReady to idle high."
140  );
141 }
142 void SpiSlaveInit_makes_Miso_an_output_pin(void)
143 {
144  /* =====[ Setup ]===== */
145  *Spi_PortDirection = 0x00;
146  TEST_ASSERT_BIT_LOW_MESSAGE(
147  Spi_Miso,
149  "Cannot run test: must start with ddr bit clear!"
150  );
151  /* =====[ Operate ]===== */
152  SpiSlaveInit();
153  /* =====[ Test ]===== */
154  TEST_ASSERT_BIT_HIGH_MESSAGE(
155  Spi_Miso,
157  "Expect Miso to be an output."
158  );
159 }
160 void SpiSlaveInit_enables_SPI(void)
161 {
162  /* =====[ Setup ]===== */
163  *Spi_SPCR = 0x00;
164  TEST_ASSERT_BIT_LOW_MESSAGE(
165  Spi_Enable,
166  *Spi_SPCR,
167  "Cannot run test: must start with bit clear!"
168  );
169  /* =====[ Operate ]===== */
170  SpiSlaveInit();
171  /* =====[ Test ]===== */
172  TEST_ASSERT_BIT_HIGH_MESSAGE(
173  Spi_Enable,
174  *Spi_SPCR,
175  "Expect bit 6 HIGH to enable SPI module."
176  );
177 }
178 void SpiSlaveInit_enables_SPI_interrupt(void)
179 {
180  /* =====[ Operate ]===== */
181  SpiSlaveInit();
182  /* =====[ Test ]===== */
183  /* PrintAllCalls(mock); */
184  // check SpiSlaveInit calls `EnableSpiInterrupt`
185  uint16_t call_n = 1;
186  TEST_ASSERT_TRUE_MESSAGE(
187  AssertCall(mock, call_n, "EnableSpiInterrupt"),
188  "Expect SpiSlaveInit enables the SPI interrupt."
189  );
190 }
191 
192 /* =====[ SpiSlaveTx ]===== */
193 void SpiSlaveTx_sends_nbytes_of_input_buffer_to_SpiMaster(void)
194 {
195  /* =====[ Setup ]===== */
196  uint8_t input_buffer[] = {0xa0, 0xb1, 0xc2};
197  puts("Transmit these bytes: {0xa0, 0xb1, 0xc2}");
198  uint16_t nbytes = (uint16_t)sizeof(input_buffer);
199  /* printf("sizeof(input_buffer)=%zu\n",sizeof(input_buffer)); */
200  /* printf("nbytes=%d\n",nbytes); */
201  /* =====[ Operate ]===== */
202  SpiSlaveTx(input_buffer, nbytes);
203  /* =====[ Test ]===== */
204  /* PrintAllCalls(mock); */
205  uint16_t arg_n = 1; uint8_t *p_argval = input_buffer;
206  uint16_t call_n = 1;
207  while (call_n <= nbytes)
208  {
209  TEST_ASSERT_TRUE(
210  SilentAssertCall(mock, call_n, "SpiSlaveTxByte")
211  );
212  TEST_ASSERT_TRUE(
213  AssertArg(mock, call_n++, arg_n, p_argval++)
214  );
215  }
216 }
217 
218 /* =====[ SpiSlaveTxByte ]===== */
219 void SpiSlaveTxByte_loads_SPI_data_register_with_input_byte(void)
220 {
221  /* =====[ Setup ]===== */
222  uint8_t input_byte = 0xAB;
223  /* =====[ Operate ]===== */
224  SpiSlaveTxByte(input_byte);
225  /* =====[ Test ]===== */
226  TEST_ASSERT_EQUAL_UINT8(input_byte, *Spi_SPDR);
227 }
228 void SpiSlaveTxByte_disables_SPI_ISR_before_signaling_data_ready(void)
229 {
230  /* =====[ Operate ]===== */
231  SpiSlaveTxByte(0xFF);
232  /* =====[ Test ]===== */
233  uint16_t call_n = 1;
234  TEST_ASSERT_TRUE(AssertCall(mock, call_n++, "DisableSpiInterrupt"));
235  TEST_ASSERT_TRUE(AssertCall(mock, call_n, "_SignalDataReady"));
236 }
237 void SpiSlaveTxByte_drives_DataReady_LOW_to_signal_data_is_ready(void)
238 {
239  /* =====[ Setup ]===== */
240  *Spi_PortOutput = 0xFF;
241  TEST_ASSERT_BIT_HIGH_MESSAGE(
242  Spi_DataReady,
244  "Cannot run test: must start with DataReady HIGH!"
245  );
246  /* =====[ Operate ]===== */
247  SpiSlaveTxByte(0xFF);
248  /* =====[ Test ]===== */
249  /* TEST_ASSERT_BIT_LOW(Spi_DataReady, *Spi_PortOutput); */
250  uint16_t call_n = 2;
251  TEST_ASSERT_TRUE(AssertCall(mock, call_n, "_SignalDataReady"));
252 }
253 void SpiSlaveTxByte_waits_until_SPI_transfer_is_done(void)
254 {
255  /* =====[ Setup ]===== */
256  ClearBit(Spi_SPSR, Spi_InterruptFlag);
257  TEST_ASSERT_BIT_LOW_MESSAGE(
258  Spi_InterruptFlag,
259  *Spi_SPSR,
260  "Cannot run test: must start with bit clear!"
261  );
262  /* =====[ Operate ]===== */
263  SpiSlaveTxByte(0xFF);
264  /* =====[ Test ]===== */
265  /* PrintAllCalls(mock); */
266  uint16_t call_n = 3;
267  TEST_ASSERT_TRUE(AssertCall(mock, call_n, "_SpiTransferIsDone"));
268  TEST_ASSERT_BIT_HIGH(Spi_InterruptFlag, *Spi_SPSR);
269 }
270 void SpiSlaveTxByte_drives_DataReady_HIGH_immediately_after_SPI_transfer_finishes(void)
271 {
272  /* =====[ Setup ]===== */
273  *Spi_PortOutput = 0x00;
274  TEST_ASSERT_BIT_LOW_MESSAGE(
275  Spi_DataReady,
277  "Cannot run test: must start with DataReady LOW!"
278  );
279  /* =====[ Operate ]===== */
280  SpiSlaveTxByte(0xFF);
281  /* =====[ Test ]===== */
282  TEST_ASSERT_BIT_HIGH(Spi_DataReady, *Spi_PortOutput);
283 }
284 void SpiSlaveTxByte_enables_SPI_ISR_after_transfer(void)
285 {
286  /* =====[ Setup ]===== */
287  ClearBit(Spi_SPCR, Spi_InterruptEnable);
288  TEST_ASSERT_BIT_LOW_MESSAGE(
289  Spi_InterruptEnable,
290  *Spi_SPCR,
291  "Cannot run test: must start with bit clear!"
292  );
293  /* =====[ Operate ]===== */
294  SpiSlaveTxByte(0xFF);
295  /* =====[ Test ]===== */
296  TEST_ASSERT_BIT_HIGH(Spi_InterruptEnable, *Spi_SPCR);
297 }
spi_ptr Spi_SPSR
SPI Status Register.
spi_ptr Spi_SPCR
SPI Control Register.
spi_ptr Spi_SPDR
SPI Data Register.
void EnableSpiInterrupt(void)
Definition: SpiSlave.h:77
void DisableSpiInterrupt(void)
Definition: SpiSlave.h:48
void SpiSlaveInit(void)
Definition: SpiSlave.h:118
void SpiSlaveTx(uint8_t const *input_buffer, uint16_t nbytes)
Definition: SpiSlave.h:202
void SpiSlaveTxByte(uint8_t input_byte)
Definition: SpiSlave.h:150
void _SignalDataReady(void)
Definition: SpiSlave.h:14
Spi.h declares SPI hardware types and variables common to the SPI Master and SPI Slave.
spi_reg Spi_PortOutput
Atmel PORT.
spi_reg Spi_PortDirection
Atmel DDR.