Contiki 3.x
cc1120-mkl25z-rf-arch.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (c) 2014, University of Southampton, Electronics and Computer Science
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the Institute nor the names of its contributors
15  * may be used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  */
31 
32  /**
33  * \file
34  * Architecture specific CC1120 functions for the FRDM-KL25Z-RF
35  * \author
36  * Graeme Bragg <g.bragg@ecs.soton.ac.uk>
37  * Phil Basford <pjb@ecs.soton.ac.uk>
38  */
39 
40 #include "derivative.h"
41 #include "cc1120.h"
42 #include "cc1120-arch.h"
43 #include "cc1120-const.h"
44 
45 #include "cpu.h"
46 #include "spi.h"
47 #include "nvic.h"
48 #include "gpio.h"
49 
50 #include <stdio.h>
51 #include <watchdog.h>
52 
53 #define READ_BIT 0x80
54 #define TEST_VALUE 0xA5
55 
56 
57 #if DEBUG
58 #include <stdio.h>
59 #define PRINTF(...) printf(__VA_ARGS__)
60 #else
61 #define PRINTF(...)
62 #endif
63 
64 static uint8_t enabled;
65 
66 /* Busy Wait for time-outable waiting. */
67 #define BUSYWAIT_UNTIL(cond, max_time) \
68  do { \
69  rtimer_clock_t t0; \
70  t0 = RTIMER_NOW(); \
71  while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \
72  } while(0)
73 
74 
75 /* ---------------------------- Init Functions ----------------------------- */
76 /*---------------------------------------------------------------------------*/
77 
78 void
79 cc1120_arch_init(void)
80 {
81  PRINTF("\n\rConfigure CC1120 (arch)...\n\r");
82  /* Configure pins. This may have already been done but func is repeat-execution safe. */
83  PRINTF("\tRadio Control Pins\n\r");
84  cc1120_arch_pin_init();
85 
86  /* Init SPI. May have already done but we need to ensure SPI is configured.*/
87  PRINTF("\tSPI...\n\r");
88  SPI0_init(); /* Configure SPI with CSn. */
89 
90 
91  /* Configure GPIO Input pins */
92  PRINTF("\tGPIO Pins...\n\r");
93  gpio_set_input(CC1120_GPIO2_GPIO, port_pin_to_mask(CC1120_GPIO2_PIN)); /* Set Pin A12 as input for GPIO2 */
94  port_conf_pin(CC1120_GPIO2_PORT, CC1120_GPIO2_PIN, (PORT_PCR_MUX_GPIO | PORT_PCR_ISF_MASK));/* Set Pin A12 to be GPIO. */
95 
96  gpio_set_input(CC1120_GPIO3_GPIO, port_pin_to_mask(CC1120_GPIO3_PIN)); /* Set Pin A13 as input for GPIO3 */
97  port_conf_pin(CC1120_GPIO3_PORT, CC1120_GPIO3_PIN, (PORT_PCR_MUX_GPIO | PORT_PCR_ISF_MASK));/* Set Pin A13 to be GPIO. */
98 
99 
100  PRINTF("\tRadio Interrupt...\n\r");
101 
102  gpio_set_input(CC1120_INT_GPIO, port_pin_to_mask(CC1120_INT_PIN)); /* Set Pin A5 as input for GPIO0 */
103  port_conf_pin(CC1120_INT_PORT, CC1120_INT_PIN, (PORT_PCR_MUX_GPIO | PORT_PCR_ISF_MASK)); /* Set Pin A5 to be GPIO. */
104 
105  port_register_callback(&cc1120_interrupt_handler, CC1120_INT_PORT, CC1120_INT_PIN); /* Register callback. */
106  port_conf_pin_int_disable(CC1120_GPIO0_PORT, CC1120_GPIO0_PIN); /* Disable interrupt for now. */
107 
108  PRINTF("\tOK!\n\r");
109 
110 }
111 
112 /*---------------------------------------------------------------------------*/
113 
114 void
115 cc1120_arch_pin_init(void)
116 {
117  /* Configure CSn pin on Port D, Pin 0 */
118  gpio_set_output(CC1120_CSn_GPIO, port_pin_to_mask(CC1120_CSn_PIN)); /* Set pin as Output.*/
119  port_conf_pin(CC1120_CSn_PORT, CC1120_CSn_PIN, (PORT_PCR_MUX_GPIO | PORT_PCR_ISF_MASK));/* Clear ISF & set MUX to be basic pin. */
120  enabled = 0;
121 
122  /* Configure CC1120 Reset pin on Port B, Pin 8. */
123  gpio_set_output(CC1120_RST_GPIO, port_pin_to_mask(CC1120_RST_PIN)); /* Set pin as Output.*/
124  port_conf_pin(CC1120_RST_PORT, CC1120_RST_PIN, (PORT_PCR_MUX_GPIO | PORT_PCR_ISF_MASK));/* Clear ISF & set MUX to be basic pin. */
125 
126  /* Configure C17 to read MISO. */
127  gpio_set_input(CC1120_CSnCHK_GPIO, port_pin_to_mask(CC1120_CSnCHK_PIN)); /* Set pin C17 as Input.*/
128  port_conf_pin(CC1120_CSnCHK_PORT, CC1120_CSnCHK_PIN, (PORT_PCR_MUX_GPIO | PORT_PCR_ISF_MASK)); /* Clear ISF & set MUX to be basic pin. */
129 
130  gpio_set_pin(CC1120_CSn_GPIO, port_pin_to_mask(CC1120_CSn_PIN)); /* Make sure that the CSn is set HIGH. */
131  gpio_set_pin(CC1120_RST_GPIO, port_pin_to_mask(CC1120_RST_PIN)); /* Make sure that the Reset is set HIGH. */
132 }
133 
134 
135 /* ---------------------------- Reset Functions ---------------------------- */
136 void
137 cc1120_arch_reset(void)
138 {
139  cc1120_arch_spi_disable();
140  gpio_set_pin(CC1120_CSn_GPIO, port_pin_to_mask(CC1120_CSn_PIN)); /* Assert CSn to de-select CC1120. */
141  gpio_clr_pin(CC1120_RST_GPIO, port_pin_to_mask(CC1120_RST_PIN)); /* Clear !Reset pin. */
142  clock_delay(CC1120_RESET_DELAY_USEC/100); /* Delay for a little. */
143  gpio_set_pin(CC1120_RST_GPIO, port_pin_to_mask(CC1120_RST_PIN)); /* Assert !Reset pin. */
144  enabled = 0;
145 }
146 
147 
148 /* ----------------------------- SPI Functions ----------------------------- */
149 uint8_t
150 cc1120_arch_spi_enabled(void)
151 {
152  return enabled;
153 }
154 
155 void
156 cc1120_arch_spi_enable(void)
157 {
158  if(!enabled)
159  {
160  rtimer_clock_t t0 = RTIMER_NOW();
161  int i = 0;
162 
163  gpio_clr_pin(CC1120_CSn_GPIO, port_pin_to_mask(CC1120_CSn_PIN)); /* Set CSn to low to select CC1120 */
164 
166 
167  /* The MISO pin should go LOW before chip is fully enabled. */
168  while(gpio_read_pin(CC1120_CSnCHK_GPIO, port_pin_to_mask(CC1120_CSnCHK_PIN)))
169  {
170  if(RTIMER_CLOCK_LT((t0 + CC1120_EN_TIMEOUT), RTIMER_NOW()) )
171  {
173  if(i == 0)
174  {
175  /* Timeout. Try a SNOP and a re-enable once. */
176  (void) cc1120_arch_spi_rw_byte(CC1120_STROBE_SNOP); /* SNOP. */
177  gpio_set_pin(CC1120_CSn_GPIO, port_pin_to_mask(CC1120_CSn_PIN)); /* Disable. */
178  clock_wait(50); /* Wait. */
179  gpio_clr_pin(CC1120_CSn_GPIO, port_pin_to_mask(CC1120_CSn_PIN)); /* Enable. */
180 
181  i++;
182  }
183  else
184  {
185  printf("Radio Barf");
186  break;
187  }
188 
189  t0 = RTIMER_NOW(); /* Reset timeout. */
190  }
191  }
192 
193  enabled = 1;
194  }
195 }
196 
197 /*---------------------------------------------------------------------------*/
198 void
199 cc1120_arch_spi_disable(void)
200 {
201  /* Set CSn to high (1) */
202  gpio_set_pin(CC1120_CSn_GPIO, port_pin_to_mask(CC1120_CSn_PIN));
203  enabled = 0;
204 }
205 
206 /*---------------------------------------------------------------------------*/
207 uint8_t
208 cc1120_arch_spi_rw_byte(uint8_t val)
209 {
210  return SPI_single_tx_rx(val, 0);
211 }
212 
213 /*---------------------------------------------------------------------------*/
214 uint8_t
215 cc1120_arch_txfifo_load(uint8_t *packet, uint8_t packet_length)
216 {
217  uint8_t status, i;
218  //status = cc1120_arch_spi_rw_byte(CC1120_FIFO_ACCESS | CC1120_STANDARD_BIT | CC1120_WRITE_BIT);
219  status = cc1120_arch_spi_rw_byte(CC1120_FIFO_ACCESS | CC1120_BURST_BIT | CC1120_WRITE_BIT);
220  cc1120_arch_spi_rw_byte(packet_length);
221 
222  for(i = 0; i < packet_length; i++)
223  {
224  cc1120_arch_spi_rw_byte(packet[i]);
225  }
226 
227  return status;
228 }
229 
230 
231 /*---------------------------------------------------------------------------*/
232 void
233 cc1120_arch_rxfifo_read(uint8_t *packet, uint8_t packet_length)
234 {
235  uint8_t i;
236 
237  (void) cc1120_arch_spi_rw_byte(CC1120_FIFO_ACCESS | CC1120_BURST_BIT | CC1120_READ_BIT);
238 
239  for(i = 0; i < packet_length; i++)
240  {
241  packet[i] = cc1120_arch_spi_rw_byte(0);
242  }
244 }
245 
246 
247 /*---------------------------------------------------------------------------*/
248 uint8_t
249 cc1120_arch_read_cca(void)
250 {
251  /*if(CC1120_GDO3_PORT(IN) & BV(CC1120_GDO3_PIN))
252  {
253  return 1;
254  }
255  else
256  {*/
257  return 0;
258  //}
259 }
260 
261 
262 uint8_t
263 cc1120_arch_read_gpio2(void)
264 {
265  return 0;
266 }
267 
268 /*---------------------------------------------------------------------------*/
269 uint8_t
270 cc1120_arch_read_gpio3(void)
271 {
272  if(gpio_read_pin(CC1120_GPIO3_GPIO,port_pin_to_mask(CC1120_GPIO3_PIN)))
273  {
274  return 1;
275  }
276  else
277  {
278  return 0;
279  }
280 }
281 
282 /* -------------------------- Interrupt Functions -------------------------- */
283 
284 void
285 cc1120_arch_interrupt_enable(void)
286 {
287  /* Reset interrupt trigger */
288  port_pin_clr_isf(CC1120_INT_PORT, CC1120_INT_PIN);
289 
290  port_conf_pin_int_rise(CC1120_INT_PORT, CC1120_INT_PIN);
291 
292 }
293 
294 /*---------------------------------------------------------------------------*/
295 void
296 cc1120_arch_interrupt_disable(void)
297 {
298  /* Disable interrupt on the GDO0 pin */
300 }
301 /*---------------------------------------------------------------------------*/
302 void
303 cc1120_arch_interrupt_acknowledge(void)
304 {
305  /* Reset interrupt trigger */
306  port_pin_clr_isf(CC1120_INT_PORT, CC1120_INT_PIN);
307 
308  if(SPI0_S & SPI_S_SPRF_MASK) { /* If there is stray data in the SPI data register, discard it. */
309  (void)SPI0_D;
310  }
311 }
void port_conf_pin_int_rise(PORT_Type *Port, uint8_t Pin)
Configure rising-edge interrupt on the specified Pin of the port with PORTx_BASE_PTR.
Definition: gpio.c:66
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:135
void gpio_set_output(GPIO_Type *Port, uint32_t Pin_Mask)
Set pins with Pin_Mask of port with GPIOn_BASE_PTR to output.
Definition: gpio.c:135
uint32_t gpio_read_pin(GPIO_Type *Port, uint32_t Pin_Mask)
Read pins with Pin_Mask of port with GPIOn_BASE_PTR.
Definition: gpio.c:159
#define PORTA
Peripheral PORTA base pointer.
Definition: MKL25Z4.h:4435
void port_register_callback(void *f, PORT_Type *port, uint8_t pin)
Register Port interrupt callback function.
Definition: gpio.c:27
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:64
void gpio_clr_pin(GPIO_Type *Port, uint32_t Pin_Mask)
Clear pins with Pin_Mask of port with GPIOn_BASE_PTR low.
Definition: gpio.c:147
void port_conf_pin(PORT_Type *Port, uint8_t Pin, uint32_t PCR)
Configure the specified Pin of the port with PORTx_BASE_PTR with PCR.
Definition: gpio.c:40
void clock_delay(unsigned int delay)
Obsolete delay function but we implement it here since some code still uses it.
Definition: clock.c:60
void gpio_set_input(GPIO_Type *Port, uint32_t Pin_Mask)
Set pins with Pin_Mask of port with GPIOn_BASE_PTR to input.
Definition: gpio.c:129
void port_conf_pin_int_disable(PORT_Type *Port, uint8_t Pin)
Disable interrupt on the specified Pin of the port with PORTx_BASE_PTR.
Definition: gpio.c:51
void clock_wait(clock_time_t t)
Wait for a given number of ticks.
Definition: clock.c:162
void port_pin_clr_isf(PORT_Type *Port, uint8_t Pin)
Clear the Interrupt Status Flag of Pin in port with PORTx_BASE_PTR.
Definition: gpio.c:120
void gpio_set_pin(GPIO_Type *Port, uint32_t Pin_Mask)
Set pins with Pin_Mask of port with GPIOn_BASE_PTR high.
Definition: gpio.c:141
uint32_t port_pin_to_mask(uint8_t pin)
Convert a pin number (0 to 31) to a pin mask.
Definition: gpio.c:46