Contiki-NG
mmc-arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, Benoît Thébaudeau <benoit@wsystem.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 /**
32  * \addtogroup mmc-arch
33  * \ingroup zoul
34  * @{
35  *
36  * \file
37  * Implementation of the SD/MMC device driver RE-Mote-specific definitions.
38  */
39 #include <stddef.h>
40 #include <stdbool.h>
41 #include <stdint.h>
42 #include "dev/spi-arch-legacy.h"
43 #include "dev/ioc.h"
44 #include "dev/gpio.h"
45 #include "dev/spi-legacy.h"
47 
48 #define USD_SEL_PORT_BASE GPIO_PORT_TO_BASE(USD_SEL_PORT)
49 #define USD_SEL_PIN_MASK GPIO_PIN_MASK(USD_SEL_PIN)
50 
51 /*----------------------------------------------------------------------------*/
52 static void
53 mmc_arch_init(void)
54 {
55  static uint8_t init_done;
56 
57  if(init_done) {
58  return;
59  }
60 
61  GPIO_SET_INPUT(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK);
62  GPIO_SOFTWARE_CONTROL(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK);
63  ioc_set_over(USD_SEL_PORT, USD_SEL_PIN, IOC_OVERRIDE_DIS);
64 
65  spix_cs_init(USD_CSN_PORT, USD_CSN_PIN);
66  spix_init(USD_SPI_INSTANCE);
67  spix_set_mode(USD_SPI_INSTANCE, SSI_CR0_FRF_MOTOROLA, 0, 0, 8);
68 
69  init_done = 1;
70 }
71 /*----------------------------------------------------------------------------*/
72 bool
73 mmc_arch_get_cd(uint8_t dev)
74 {
75  mmc_arch_init();
76 
77  if(GPIO_IS_OUTPUT(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK)) {
78  /* Card previously detected and powered */
79  return true;
80  } else if(GPIO_READ_PIN(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK)) {
81  /* Card inserted -> power it */
82  GPIO_SET_OUTPUT(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK);
83  GPIO_CLR_PIN(USD_SEL_PORT_BASE, USD_SEL_PIN_MASK);
84  return true;
85  } else {
86  /* No card detected */
87  return false;
88  }
89 }
90 /*----------------------------------------------------------------------------*/
91 bool
92 mmc_arch_get_wp(uint8_t dev)
93 {
94  return false;
95 }
96 /*----------------------------------------------------------------------------*/
97 void
98 mmc_arch_spi_select(uint8_t dev, bool sel)
99 {
100  if(sel) {
101  SPIX_CS_CLR(USD_CSN_PORT, USD_CSN_PIN);
102  } else {
103  SPIX_CS_SET(USD_CSN_PORT, USD_CSN_PIN);
104  }
105 }
106 /*----------------------------------------------------------------------------*/
107 void
108 mmc_arch_spi_set_clock_freq(uint8_t dev, uint32_t freq)
109 {
110  spix_set_clock_freq(USD_SPI_INSTANCE, freq);
111 }
112 /*----------------------------------------------------------------------------*/
113 void
114 mmc_arch_spi_xfer(uint8_t dev, const void *tx_buf, size_t tx_cnt,
115  void *rx_buf, size_t rx_cnt)
116 {
117  const uint8_t *tx_buf_u8 = tx_buf;
118  uint8_t *rx_buf_u8 = rx_buf;
119 
120  while(tx_cnt || rx_cnt) {
121  SPIX_WAITFORTxREADY(USD_SPI_INSTANCE);
122  if(tx_cnt) {
123  SPIX_BUF(USD_SPI_INSTANCE) = *tx_buf_u8++;
124  tx_cnt--;
125  } else {
126  SPIX_BUF(USD_SPI_INSTANCE) = 0xff;
127  }
128  SPIX_WAITFOREOTx(USD_SPI_INSTANCE);
129  SPIX_WAITFOREORx(USD_SPI_INSTANCE);
130  if(rx_cnt) {
131  *rx_buf_u8++ = SPIX_BUF(USD_SPI_INSTANCE);
132  rx_cnt--;
133  } else {
134  SPIX_BUF(USD_SPI_INSTANCE);
135  }
136  }
137 }
138 /*----------------------------------------------------------------------------*/
139 
140 /** @} */
bool mmc_arch_get_wp(uint8_t dev)
Gets the state of the write-protection signal.
Definition: mmc-arch.c:92
void spix_init(uint8_t spi)
Initialize the SPI bus for the instance given.
Definition: spi-legacy.c:213
bool mmc_arch_get_cd(uint8_t dev)
Gets the state of the card-detection signal.
Definition: mmc-arch.c:73
#define GPIO_IS_OUTPUT(PORT_BASE, PIN_MASK)
Return whether pins with PIN_MASK of port with PORT_BASE are set to output.
Definition: gpio.h:99
Header file with register and macro declarations for the cc2538 GPIO module.
#define GPIO_CLR_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE low.
Definition: gpio.h:113
Header file with declarations for the I/O Control module.
void mmc_arch_spi_select(uint8_t dev, bool sel)
Sets the SPI /CS signal as indicated.
Definition: mmc-arch.c:98
Header file for the SD/MMC device driver architecture-specific definitions.
void mmc_arch_spi_set_clock_freq(uint8_t dev, uint32_t freq)
Sets the SPI clock frequency.
Definition: mmc-arch.c:108
#define IOC_OVERRIDE_DIS
Override Disabled.
Definition: ioc.h:226
void spix_set_mode(uint8_t spi, uint32_t frame_format, uint32_t clock_polarity, uint32_t clock_phase, uint32_t data_size)
Configure the SPI data and clock polarity and the data size for the instance given.
Definition: spi-legacy.c:295
#define GPIO_READ_PIN(PORT_BASE, PIN_MASK)
Read pins with PIN_MASK of port with PORT_BASE.
Definition: gpio.h:147
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK)
Configure the pin to be software controlled with PIN_MASK of port with PORT_BASE. ...
Definition: gpio.h:258
void mmc_arch_spi_xfer(uint8_t dev, const void *tx_buf, size_t tx_cnt, void *rx_buf, size_t rx_cnt)
Performs an SPI transfer.
Definition: mmc-arch.c:114
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
Set Port:Pin override function.
Definition: ioc.c:54
void spix_set_clock_freq(uint8_t spi, uint32_t freq)
Sets the SPI clock frequency of the given SSI instance.
Definition: spi-legacy.c:323
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to input.
Definition: gpio.h:78
#define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to output.
Definition: gpio.h:85
Basic SPI macros
void spix_cs_init(uint8_t port, uint8_t pin)
Configure a GPIO to be the chip select pin.
Definition: spi-legacy.c:354
#define SSI_CR0_FRF_MOTOROLA
Motorola frame format.
Definition: ssi.h:156
Header file for the cc2538 SPI driver, including macros for the implementation of the low-level SPI p...