GadgetSeed  0.9.6
stm32f4xx_nucleo_mmc.c
[詳解]
1 /** @file
2  @brief MMC ドライバ STM32F4xx Nucleo 依存部分
3 
4  SPIドライバ使用
5 
6  @date 2015.08.11
7  @author Takashi SHUDO
8 
9  @info
10 
11  CS PB6
12  WP N/A
13  POWER N/A
14 */
15 
16 #include "sysconfig.h"
17 #include "tkprintf.h"
18 #include "device.h"
19 #include "device/spi_ioctl.h"
20 
21 
22 /*
23  GPIOレジスタ
24 */
25 #define RCC_AHB1ENR (*(volatile unsigned long *)0x40023830)
26 #define RCC_AHB1LPENR (*(volatile unsigned long *)0x40023850)
27 #define RCC_AHB1_BIT_GPIOB (1UL<<1)
28 
29 #define GPIOB_MODER (*(volatile unsigned long *)0x40020400)
30 #define GPIO_MODE_BIT_IN 0x00 // Input Mode
31 #define GPIO_MODE_BIT_OUT 0x01 // Output Mode
32 #define GPIO_MODE_BIT_AF 0x02 // Alternate functions Mode
33 #define GPIO_MODE_BIT_AN 0x03 // Analog Mode
34 #define GPIO_MODE_BIT_ALL 0x03
35 
36 #define GPIOB_OTYPE (*(volatile unsigned long *)0x40020404)
37 #define GPIO_OTYPE_BIT_PP 0x00 // push-pull
38 #define GPIO_OTYPE_BIT_OD 0x01 // open-drain
39 
40 #define GPIOB_OSPEEDR (*(volatile unsigned long *)0x40020408)
41 #define GPIO_OSPEED_BIT_ALL 0x03
42 #define GPIO_OSPEED_BIT_50MHz 0x02
43 #define GPIO_OSPEED_BIT_100MHz 0x03
44 
45 #define GPIOB_PUPDR (*(volatile unsigned long *)0x4002040C)
46 #define GPIO_PUPDR_BIT_NOPULL 0x00 // No pull-up, pull-down
47 #define GPIO_PUPDR_BIT_PUP 0x01 // pull-up
48 #define GPIO_PUPDR_BIT_PDOWN 0x02 // pull-down
49 #define GPIO_PUPDR_BIT_ALL 0x03
50 
51 #define GPIOB_IDR (*(volatile unsigned long *)0x40020410)
52 #define GPIOB_ODR (*(volatile unsigned long *)0x40020414)
53 #define GPIOB_BSRRL (*(volatile unsigned short *)0x40020418)
54 #define GPIOB_BSRRH (*(volatile unsigned short *)0x4002041A)
55 #define GPIOB_LCKR (*(volatile unsigned long *)0x4002041C)
56 #define GPIOB_AFRL (*(volatile unsigned long *)0x40020420)
57 #define GPIOB_AFRH (*(volatile unsigned long *)0x40020424)
58 
59 static void init_pin(int pos)
60 {
61  GPIOB_MODER &= ~(((unsigned long)GPIO_MODE_BIT_ALL) << (2*pos));
62  GPIOB_MODER |= (((unsigned long)GPIO_MODE_BIT_OUT) << (2*pos));
63  GPIOB_OSPEEDR &= ~(((unsigned long)GPIO_OSPEED_BIT_ALL) << (2*pos));
64  GPIOB_OSPEEDR |= (((unsigned long)GPIO_OSPEED_BIT_100MHz) << (2*pos));
65  GPIOB_OTYPE &= ~(((unsigned long)1) << pos);
66  GPIOB_OTYPE |= (((unsigned long)GPIO_OTYPE_BIT_PP) << pos);
67  GPIOB_PUPDR &= ~(((unsigned long)GPIO_PUPDR_BIT_ALL) << (2*pos));
68  GPIOB_PUPDR |= (((unsigned long)GPIO_PUPDR_BIT_NOPULL) << (2*pos));
69 }
70 
71 #define CS_PIN 6 // GPIOB 6
72 
73 static void cs_low(void)
74 {
75  GPIOB_BSRRH = (1UL<<CS_PIN);
76 }
77 
78 static void cs_high(void)
79 {
80  GPIOB_BSRRL = (1UL<<CS_PIN);
81 }
82 
83 
84 static struct st_device *mmc_dev;
85 
86 static int mmc_register(struct st_device *dev, char *param)
87 {
88  mmc_dev = open_device(param);
89  if(mmc_dev == 0) {
90  SYSERR_PRINT("Cannot open device \"%s\"\n", param);
91  return -1;
92  }
93 
94  RCC_AHB1ENR |= RCC_AHB1_BIT_GPIOB;
95  init_pin(CS_PIN);
96  cs_high();
97 
98  return 0;
99 }
100 
101 static int mmc_getc(struct st_device *dev, unsigned char *rd)
102 {
103  int rt;
104 
105 // cs_low();
106  rt = getc_device(mmc_dev, rd);
107 // cs_high();
108 
109  return rt;
110 }
111 
112 static int mmc_read(struct st_device *dev, void *data, unsigned int size)
113 {
114  int rt;
115 
116 // cs_low();
117  rt = read_device(mmc_dev, data, size);
118 // cs_high();
119 
120  return rt;
121 }
122 
123 static int mmc_putc(struct st_device *dev, unsigned char ch)
124 {
125  int rt;
126 
127 // cs_low();
128  rt = putc_device(mmc_dev, ch);
129 // cs_high();
130 
131  return rt;
132 }
133 
134 static int mmc_write(struct st_device *dev, const void *data, unsigned int size)
135 {
136  int rt;
137 
138 // cs_low();
139  rt = write_device(mmc_dev, data, size);
140 // cs_high();
141 
142  return rt;
143 }
144 
145 static int mmc_ioctl(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
146 {
147  int rt = 0;
148 
149  switch(com) {
150  case IOCMD_SPI_CS0ASSERT:
151  cs_low();
152  break;
153 
154  case IOCMD_SPI_CS0NEGATE:
155  cs_high();
156  break;
157 
158  default:
159  rt = ioctl_device(mmc_dev, com, arg, param);
160  break;
161  }
162 
163  return rt;
164 }
165 
166 static int mmc_suspend(struct st_device *dev)
167 {
168  int rt;
169 
170 // cs_low();
171  rt = suspend_device(mmc_dev);
172 // cs_high();
173 
174  return rt;
175 }
176 
177 static int mmc_resume(struct st_device *dev)
178 {
179  int rt;
180 
181 // cs_low();
182  rt = resume_device(mmc_dev);
183 // cs_high();
184 
185  return rt;
186 }
187 
188 
189 const struct st_device stm_mmc_device = {
190  .name = "mmc_spi",
191  .explan = "STM32F4xx Nucleo SPI MMC",
192  .register_dev = mmc_register,
193  .read = mmc_read,
194  .getc = mmc_getc,
195  .write = mmc_write,
196  .putc = mmc_putc,
197  .ioctl = mmc_ioctl,
198  .suspend = mmc_suspend,
199  .resume = mmc_resume,
200 };
#define IOCMD_SPI_CS0NEGATE
CS0をネゲートする
Definition: spi_ioctl.h:22
struct st_device * open_device(char *name)
デバイスをオープンする
Definition: device.c:262
SPIドライバ ioctl 用マクロ定義
int write_device(struct st_device *dev, const void *buf, unsigned int count)
デバイスにデータを書き込む
Definition: device.c:451
int read_device(struct st_device *dev, void *buf, unsigned int count)
デバイスよりデータを読み出す
Definition: device.c:378
int resume_device(struct st_device *dev)
デバイスを活性化する
Definition: device.c:618
カーネル用機能限定printf
int getc_device(struct st_device *dev, unsigned char *data)
デバイスよりデータを1バイト読み出す
Definition: device.c:429
#define IOCMD_SPI_CS0ASSERT
CS0をアサートしたままにする
Definition: spi_ioctl.h:21
int putc_device(struct st_device *dev, unsigned char data)
デバイスにデータを1バイト書き込む
Definition: device.c:502
int suspend_device(struct st_device *dev)
デバイスを休止状態にする
Definition: device.c:600
デバイスドライバAPI
デバイスドライバ構造体
Definition: device.h:25
int ioctl_device(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
デバイスを制御する
Definition: device.c:525
char name[MAX_DEVNAMELRN]
デバイス名文字列
Definition: device.h:26