firmware  v0.1.2
Chromation Spectrometer Dev-Kit
test_SpiMaster.c
1 #include <glib.h> // GString, GList
2 #include "unity.h" // unit test framework
3 #include "Mock.h" // function faking framework
4 #include "test_SpiMaster.h"
5 #include "SpiMaster.h"
6 #include "ReadWriteBits.h"
7 #include "StatusCode.h"
8 
9 /* =====[ Test Helpers ]===== */
10 static void _AssertCall(uint16_t num, char const * name)
11 {
13  // Put num and name in the message displayed if test fails
14  GString *message = g_string_new(NULL);
15  g_string_append_printf(message, "`%s` is not call %d", name, num);
16  // Perform the test
17  TEST_ASSERT_TRUE_MESSAGE(
18  AssertCall(mock, num, name),
19  message->str
20  );
21  // Free memory used by GString
22  g_string_free(message, true);
23 }
24 
25 /* =====[ setup_bit_val ]===== */
26 enum bit_val {LOW, HIGH}; typedef enum bit_val bit_val;
27 static void setup_bit_val( spi_reg reg, spi_bit bit, bit_val v )
28 {
30 
40  GString *msg = g_string_new(NULL);
41  g_string_printf(msg, "Bit must be %s when the test starts", v ? "HIGH" : "LOW");
42  if (HIGH == v)
43  {
44  SetBit(reg, bit);
45  TEST_ASSERT_BIT_HIGH_MESSAGE(bit, *reg, msg->str);
46  }
47  else if (LOW == v)
48  {
49  ClearBit(reg, bit);
50  TEST_ASSERT_BIT_LOW_MESSAGE(bit, *reg, msg->str);
51  }
52  else
53  {
54  g_string_printf(msg, "Test setup with invalid bit value: %d? ", v);
55  g_string_append_printf(msg, "Bit value must be LOW or HIGH.");
56  TEST_FAIL_MESSAGE(msg->str);
57  }
58  g_string_free(msg, true);
59 }
60 
61 /* =====[ test_bit_val_msg ]===== */
62 static void test_bit_val_msg( spi_reg reg, spi_bit bit, bit_val v, char * bit_name )
63 {
65  // Put bit_name in the message displayed if test fails
66  GString *msg = g_string_new(NULL);
67  // Fail test if v is not HIGH or LOW
68  if ((HIGH != v) && (LOW != v))
69  {
70  // Invalid test fail message
71  g_string_printf(
72  msg, "Invalid bit value `%s` = %d", bit_name, v
73  );
74  g_string_append_printf(msg, "Bit value must be LOW or HIGH.");
75  TEST_FAIL_MESSAGE(msg->str);
76  }
77  else
78  {
79  // Test fail message
80  g_string_printf(msg, "Expect `%s` (bit %d) ", bit_name, bit);
81  g_string_append_printf(
82  msg, "%s, was %s",
83  v ? "HIGH" : "LOW",
84  v ? "LOW" : "HIGH"
85  );
86  if ((HIGH == v) && BitIsSet(reg, bit)) TEST_PASS();
87  else if ((LOW == v) && BitIsClear(reg, bit)) TEST_PASS();
88  else TEST_FAIL_MESSAGE(msg->str);
89  }
90  g_string_free(msg, true);
91 }
92 
93 /* =====[ SpiMasterInit ]===== */
94 void SpiMasterInit_idles_SlaveSelect_high(void)
95 {
96  /* =====[ Setup ]===== */
97  setup_bit_val( Spi_PortOutput, Spi_Ss, LOW );
98  /* =====[ Operate ]===== */
99  SpiMasterInit();
100  /* =====[ Test ]===== */
101  test_bit_val_msg(Spi_PortOutput, Spi_Ss, HIGH, "Spi_Ss");
102 }
103 void SpiMasterInit_makes_SlaveSelect_an_output(void)
104 {
105  /* =====[ Setup ]===== */
106  setup_bit_val( Spi_PortDirection, Spi_Ss, LOW );
107  /* =====[ Operate ]===== */
108  SpiMasterInit();
109  /* =====[ Test ]===== */
110  test_bit_val_msg(Spi_PortDirection, Spi_Ss, HIGH, "Spi_Ss");
111 }
112 void SpiMasterInit_makes_Miso_an_input(void)
113 {
114  /* =====[ Setup ]===== */
115  setup_bit_val( Spi_PortDirection, Spi_Miso, HIGH );
116  /* =====[ Operate ]===== */
117  SpiMasterInit();
118  /* =====[ Test ]===== */
119  test_bit_val_msg(Spi_PortDirection, Spi_Miso, LOW, "Spi_Miso");
120 }
121 void SpiMasterInit_enables_pullup_on_Miso(void)
122 {
123  /* =====[ Setup ]===== */
124  setup_bit_val( Spi_PortOutput, Spi_Miso, LOW );
125  /* =====[ Operate ]===== */
126  SpiMasterInit();
127  /* =====[ Test ]===== */
128  test_bit_val_msg(Spi_PortOutput, Spi_Miso, HIGH, "Spi_Miso");
129 }
130 void SpiMasterInit_makes_DataReady_an_input(void)
131 {
132  /* =====[ Setup ]===== */
133  setup_bit_val( Spi_PortDirection, Spi_DataReady, HIGH );
134  /* =====[ Operate ]===== */
135  SpiMasterInit();
136  /* =====[ Test ]===== */
137  test_bit_val_msg(Spi_PortDirection, Spi_DataReady, LOW, "Spi_DataReady");
138 }
139 void SpiMasterInit_enables_pullup_on_DataReady(void)
140 {
141  /* =====[ Setup ]===== */
142  setup_bit_val(Spi_PortOutput, Spi_DataReady, LOW);
143  /* =====[ Operate ]===== */
144  SpiMasterInit();
145  /* =====[ Test ]===== */
146  test_bit_val_msg(Spi_PortOutput, Spi_DataReady, HIGH, "Spi_DataReady");
147 }
148 void SpiMasterInit_makes_Mosi_an_output(void)
149 {
150  /* =====[ Setup ]===== */
151  setup_bit_val(Spi_PortDirection, Spi_Mosi, LOW);
152  /* =====[ Operate ]===== */
153  SpiMasterInit();
154  /* =====[ Test ]===== */
155  test_bit_val_msg(Spi_PortDirection, Spi_Mosi, HIGH, "Spi_Mosi");
156 }
157 void SpiMasterInit_makes_Sck_an_output(void)
158 {
159  /* =====[ Setup ]===== */
160  setup_bit_val(Spi_PortDirection, Spi_Sck, LOW);
161  /* =====[ Operate ]===== */
162  SpiMasterInit();
163  /* =====[ Test ]===== */
164  test_bit_val_msg(Spi_PortDirection, Spi_Sck, HIGH, "Spi_Sck");
165 }
166 void SpiMasterInit_makes_this_MCU_the_SPI_Master(void)
167 {
168  /* =====[ Setup ]===== */
169  setup_bit_val(Spi_SPCR, Spi_MasterSlaveSelect, LOW);
170  /* =====[ Operate ]===== */
171  SpiMasterInit();
172  /* =====[ Test ]===== */
173  test_bit_val_msg(Spi_SPCR, Spi_MasterSlaveSelect, HIGH, "Spi_MasterSlaveSelect");
174 }
175 void SpiMasterInit_sets_SPI_Clock_to_10MHz_ext_osc_divided_by_8(void)
176 {
177  /* =====[ Setup ]===== */
178  setup_bit_val(Spi_SPCR, Spi_ClockBit0, LOW);
179  setup_bit_val(Spi_SPCR, Spi_ClockBit1, HIGH);
180  setup_bit_val(Spi_SPSR, Spi_DoubleClock, LOW);
181  /* =====[ Operate ]===== */
182  SpiMasterInit();
183  /* =====[ Test ]===== */
184  TEST_ASSERT_TRUE(BitIsSet(Spi_SPCR, Spi_ClockBit0));
185  TEST_ASSERT_TRUE(BitIsClear(Spi_SPCR, Spi_ClockBit1));
186  TEST_ASSERT_TRUE(BitIsSet(Spi_SPSR, Spi_DoubleClock));
187 }
188 void SpiMasterInit_enables_the_SPI_hardware_module(void)
189 {
190  /* =====[ Setup ]===== */
191  setup_bit_val(Spi_SPCR, Spi_Enable, LOW);
192  /* =====[ Operate ]===== */
193  SpiMasterInit();
194  /* =====[ Test ]===== */
195  test_bit_val_msg(Spi_SPCR, Spi_Enable, HIGH, "Spi_Enable");
196 }
197 void SpiMasterInit_clears_SPI_interrupt_flag(void)
198 {
199  /* =====[ Operate ]===== */
200  SpiMasterInit();
201  /* =====[ Test ]===== */
202  uint16_t call_n = 1;
203  _AssertCall(call_n, "ClearSpiInterruptFlag");
204 }
205 
206 /* =====[ SpiMasterXfrByte ]===== */
207 void SpiMasterXfrByte_selects_the_SPI_slave(void)
208 {
209  TEST_PASS();
210 }
211 void SpiMasterXfrByte_loads_SPI_data_reg_with_the_byte_to_send(void)
212 {
213  /* =====[ Setup ]===== */
214  *Spi_SPDR = 0x00; // initialize the SPI data register
215  TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00, *Spi_SPDR, "Initialize SPDR = 0 before running test.");
216  uint8_t cmd = 0x03; // command 3 is GetSensorLED
217  /* =====[ Operate ]===== */
218  SpiMasterXfrByte(cmd);
219  /* =====[ Test ]===== */
220  TEST_ASSERT_EQUAL_HEX8(cmd, *Spi_SPDR);
221 }
222 void SpiMasterXfrByte_waits_until_the_transfer_is_done_by_reading_the_SPI_Interrupt_Flag(void)
223 {
224  TEST_PASS();
225 }
226 void SpiMasterXfrByte_unselects_the_SPI_slave(void)
227 {
228  /* =====[ Setup ]===== */
229  setup_bit_val(Spi_PortOutput, Spi_Ss, LOW);
230  /* =====[ Operate ]===== */
231  SpiMasterXfrByte(OK);
232  /* =====[ Test ]===== */
233  test_bit_val_msg(Spi_PortOutput, Spi_Ss, HIGH, "Spi_Ss");
234 }
235 void SpiMasterXfrByte_clears_the_SPI_Interrupt_Flag_by_reading_the_SPI_data_reg(void)
236 {
237  TEST_PASS();
238 }
239 void SpiMasterXfrByte_returns_the_byte_in_the_SPI_data_reg(void)
240 {
241  /* =====[ Setup ]===== */
242  *Spi_SPDR = 0x00; // initialize the SPI data register
243  TEST_ASSERT_EQUAL_HEX8_MESSAGE(0x00, *Spi_SPDR, "Initialize SPDR = 0 before running test.");
244  uint8_t cmd = 0x03; // command 3 is GetSensorLED
245  /* =====[ Operate ]===== */
246  uint8_t byte_in = SpiMasterXfrByte(cmd);
247  /* =====[ Test ]===== */
248  // Expect byte_in == cmd:
249  // - byte_in equals SPDR
250  // - SpiMasterXfrByte loads SPDR with cmd
251  // - SPDR does not change because this is only a unit test
252  // In a real system, SPDR contains the byte shifted in from
253  // the slave when the transfer is done.
254  TEST_ASSERT_EQUAL_HEX8(cmd, byte_in);
255 }
256 
void SpiMasterInit(void)
Definition: SpiMaster.h:55
uint8_t SpiMasterXfrByte(uint8_t byte)
Definition: SpiMaster.h:21
spi_ptr Spi_SPSR
SPI Status Register.
spi_ptr Spi_SPCR
SPI Control Register.
spi_ptr Spi_SPDR
SPI Data Register.
spi_reg Spi_PortOutput
Atmel PORT.
spi_reg Spi_PortDirection
Atmel DDR.
See cfg/microspec.json in the Python API repository.