##// END OF EJS Templates
Fixed one more spi driver bug.
jeandet -
r54:e6f450090662 dev_alexis
parent child
Show More
@@ -1,93 +1,93
1 1 #include <stdio.h>
2 2 #include <fat32.h>
3 3 #include <gpio.h>
4 4 #include <uart.h>
5 5 #include <stm32f4xx.h>
6 6 #include <bsp.h>
7 7 #include <core.h>
8 8 #include <N25Q128.h>
9 9 #include <spi.h>
10 10
11 11 extern streamdevice* __opnfiles__[];
12 12
13 13 /*
14 14 N25Q128 pinout:
15 15 MISO => PB14
16 16 MOSI => PB15
17 17 SCK => PB13
18 18 CS => PB12
19 19 WP => PC1
20 20 RESET/HOLD => PC2
21 21 */
22 22 void cs(int csstate)
23 23 {
24 24 gpiosetval(PB12,csstate);
25 25 }
26 26
27 27 void wp(int wpstate)
28 28 {
29 29 gpiosetval(PC1,wpstate);
30 30 }
31 31
32 32 void resetHold(int rhstate)
33 33 {
34 34 gpiosetval(PC2,rhstate);
35 35 }
36 36
37 37 int main()
38 38 {
39 39 spiopenandconfig(spi2,spiclkfirstedge|spimaster|spimsbfirst|spi8bits,10000,PB15,PB14,PB13,(uint32_t)NULL);
40 40 //spiopenandconfig(spi2,spiclkfirstedge|spimaster|spimsbfirst|spi8bits,10000,PB15,PB14,PB13,PB12);
41 41 gpio_t PC1pin= gpioopen(PC1);
42 42 gpiosetdir(&PC1pin,gpiooutdir);
43 43 gpio_t PC2pin= gpioopen(PC2);
44 44 gpiosetdir(&PC2pin,gpiooutdir);
45 45 gpio_t PB12pin= gpioopen(PB12);
46 46 gpiosetdir(&PB12pin,gpiooutdir);
47 47 gpioset(PC1);
48 48 gpioset(PB12);
49 49 gpioclr(PC2);
50 50 eepromN25Q128Dev eeprom;
51 51 eepromN25Q128open(&eeprom,spi2,&cs,&wp,&resetHold);
52 52 //eepromN25Q128open(&eeprom,spi2,NULL,&wp,&resetHold);
53 53 delay_100us(10);
54 54 gpioset(PC2);
55 55 gpioclr(PB12);
56 56 spiputw(spi2,0x9E);
57 57 char res[22];
58 58 spigetnc(spi2,res,22);
59 59 gpioset(PB12);
60 60 for(int i=0;i<22;i++)
61 61 {
62 62 printf("res[%d] = 0x%x\n\r",i,(int)res[i]);
63 63 }
64 64 eepromN25Q128enablewrite(&eeprom);
65 65 delay_100us(10);
66 66 eepromN25Q128writen(&eeprom,0,"hello World",11);
67 67 delay_100us(10);
68 68 eepromN25Q128readn(&eeprom,0,res,11);
69 69 res[11]='\n';
70 70 res[12]='\r';
71 71 res[13]=0;
72 //printf("read: %s",res);
73 //printf("\n");
72 printf("read: %s",res);
73 printf("\n");
74 74 for(int i=0;i<11;i++)
75 75 {
76 76 printf("res[%d] = 0x%x\n\r",i,(int)res[i]);
77 77 }
78 78 while(1)
79 79 {
80 80 gpioset(LED3);
81 81 delay_100us(10000);
82 82 gpioclr(LED3);
83 83 delay_100us(10000);
84 84 }
85 85 printf("hello world\n\r");
86 86 return 0;
87 87 }
88 88
89 89
90 90
91 91
92 92
93 93
@@ -1,74 +1,75
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the libuc, microcontroler library
3 3 -- Copyright (C) 2013, Alexis Jeandet
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------
19 19 -- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@gmail.com
21 21 -------------------------------------------------------------------------------*/
22 22 #ifndef N25Q128_H
23 23 #define N25Q128_H
24 24
25 25 #include <spi.h>
26 26 #include <uhandle.h>
27 27 #include <stdint.h>
28 28
29 29 typedef struct eepromN25Q128Dev
30 30 {
31 31 spi_t spidev;
32 32 void (*select)(int sel);
33 33 void (*writeprotect)(int wp);
34 34 void (*holdreset)(int hr);
35 35 }eepromN25Q128Dev;
36 36
37 37 #define N25Q128_PAGE_SZ 256
38 #define N25Q128_CAPACITY_IN_BYTES (1024*1024*16) /*16MB*/
38 39
39 40 #define N25Q128_READID 0x9E
40 41 #define N25Q128_READ 0x03
41 42 #define N25Q128_FASTREAD 0x0B
42 43 #define N25Q128_DOFR 0x3B
43 44 #define N25Q128_DIOFR 0xBB
44 45 #define N25Q128_QOFR 0x6B
45 46 #define N25Q128_QIOFR 0xEB
46 47 #define N25Q128_ROTP 0x4B
47 48 #define N25Q128_WREN 0x06
48 49 #define N25Q128_WRDI 0x04
49 50 #define N25Q128_PP 0x02
50 51
51 52
52 53
53 54
54 55
55 56 extern void eepromN25Q128open(eepromN25Q128Dev* dev,spi_t spidev,void (*select)(int sel),void (*writeprotect)(int wp),void (*holdreset)(int hr));
56 57 extern void eepromN25Q128pagewrite(eepromN25Q128Dev* dev,uint32_t address,unsigned char* page);
57 58 extern void eepromN25Q128pageread(eepromN25Q128Dev* dev,uint32_t address,unsigned char* page);
58 59 extern void eepromN25Q128bytewrite(eepromN25Q128Dev* dev,uint32_t address,unsigned char data);
59 60 extern unsigned char eepromN25Q128byteread(eepromN25Q128Dev* dev,uint32_t address);
60 61 extern void eepromN25Q128readn(eepromN25Q128Dev* dev,uint32_t address,unsigned char* data, unsigned int count);
61 62 extern void eepromN25Q128writen(eepromN25Q128Dev* dev,uint32_t address,unsigned char* data, unsigned int count);
62 63 extern void eepromN25Q128enablewrite(eepromN25Q128Dev* dev);
63 64
64 65
65 66
66 67
67 68 #endif
68 69
69 70
70 71
71 72
72 73
73 74
74 75
@@ -1,448 +1,449
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the libuc, microcontroler library
3 3 -- Copyright (C) 2011, Alexis Jeandet
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------
19 19 -- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@gmail.com
21 21 -------------------------------------------------------------------------------*/
22 22
23 23 #include <spi.h>
24 24 #include <stm32f4xx_rcc.h>
25 25 #include <stm32f4xx_gpio.h>
26 26 #include <gpio.h>
27 27 #define GPIOGETPORT(gpio) ((GPIO_TypeDef*)(((((uint32_t)gpio) & (uint32_t)0x0000FF00)*(uint32_t)4) + (uint32_t)GPIOA))
28 28 #define GPIOPORTNUM(gpio) (((uint32_t)(gpio) & (uint32_t)0x0000FF00)>>(uint32_t)8)
29 29
30 30
31 31 SPI_TypeDef* _spi_dev_table[3]={SPI1,SPI2,SPI3};
32 32
33 33 spi_t spiopen(int count)
34 34 {
35 35 #define _INIT_DEV(_RCC_) \
36 36 RCC_APB1PeriphClockCmd(_RCC_, ENABLE); \
37 37 RCC_APB1PeriphResetCmd(_RCC_, ENABLE); \
38 38 RCC_APB1PeriphResetCmd(_RCC_, DISABLE); \
39 39 RCC_APB1PeriphClockCmd(_RCC_, ENABLE);
40 40
41 41 switch(count)
42 42 {
43 43 case spi1:
44 44 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
45 45 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
46 46 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
47 47 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
48 48 return spi1;
49 49 break;
50 50 case spi2:
51 51 _INIT_DEV(RCC_APB1Periph_SPI2);
52 52 return spi2;
53 53 break;
54 54 case spi3:
55 55 _INIT_DEV(RCC_APB1Periph_SPI3);
56 56 return spi3;
57 57 break;
58 58 default:
59 59 break;
60 60 }
61 61 return -1;
62 62 }
63 63
64 64 spi_t spiopenandconfig(int count, uint32_t cfg, uint32_t speed, uint32_t MOSIpin, uint32_t MISOpin, uint32_t SCKpin, uint32_t SCSpin)
65 65 {
66 66 spi_t dev = spiopen(count);
67 67 if(dev!=-1)
68 68 {
69 69 spidisable(dev);
70 70 spisetpins(dev,MOSIpin, MISOpin, SCKpin, SCSpin);
71 71 spienable(dev);
72 72 spisetconfig(dev,cfg,speed);
73 73 }
74 74 return dev;
75 75 }
76 76
77 77
78 78 int spiclose(spi_t spidev)
79 79 {
80 80 if((spidev<3)&&(spidev>=0))
81 81 {
82 82 switch(spidev)
83 83 {
84 84 case spi1:
85 85 RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
86 86 break;
87 87 case spi2:
88 88 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
89 89 break;
90 90 case spi3:
91 91 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);
92 92 break;
93 93 default:
94 94 return -1;
95 95 break;
96 96 }
97 97 return 1;
98 98 }
99 99 return -1;
100 100 }
101 101
102 102 int spisetpins(spi_t spidev,uint32_t MOSIpin,uint32_t MISOpin,uint32_t SCKpin,uint32_t SCSpin)
103 103 {
104 104 if((spidev<3)&&(spidev>=0))
105 105 {
106 106 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
107 107 gpio_t MISO,MOSI,SCK,SCS;
108 108 uint8_t gpioAFspix = GPIO_AF_SPI1;
109 109 switch(spidev)
110 110 {
111 111 case spi1:
112 112 gpioAFspix = GPIO_AF_SPI1;
113 113 break;
114 114 case spi2:
115 115 gpioAFspix = GPIO_AF_SPI2;
116 116 break;
117 117 case spi3:
118 118 gpioAFspix = GPIO_AF_SPI3;
119 119 break;
120 120 default:
121 121 break;
122 122 }
123 123 if(MISOpin!=-1)
124 124 {
125 125 MISO = gpioopen(MISOpin);
126 126 MISO |= gpiohighspeed | gpioaf | gpiopushpulltype | gpionopulltype;
127 127 gpiosetconfig(&MISO);
128 128 GPIO_PinAFConfig(GPIOGETPORT(MISO), (uint8_t)(MISO & 0xF), gpioAFspix);
129 129 }
130 130 if(MOSIpin!=-1)
131 131 {
132 132 MOSI = gpioopen(MOSIpin);
133 133 MOSI |= gpiohighspeed | gpioaf | gpiopushpulltype | gpionopulltype;
134 134 gpiosetconfig(&MOSI);
135 135 GPIO_PinAFConfig(GPIOGETPORT(MOSI), (uint8_t)(MOSI & 0xF), gpioAFspix);
136 136 }
137 137
138 138 if(SCKpin!=-1)
139 139 {
140 140 SCK = gpioopen(SCKpin);
141 141 SCK |= gpiohighspeed | gpioaf | gpiopushpulltype | gpionopulltype;
142 142 gpiosetconfig(&SCK);
143 143 GPIO_PinAFConfig(GPIOGETPORT(SCK), (uint8_t)(SCK & 0xF), gpioAFspix);
144 144 }
145 145
146 146 if(SCSpin!=-1)
147 147 {
148 148 SCS = gpioopen(SCSpin);
149 149 SCS |= gpiohighspeed | gpioaf | gpiopushpulltype | gpionopulltype;
150 150 gpiosetconfig(&SCS);
151 151 GPIO_PinAFConfig(GPIOGETPORT(SCS), (uint8_t)(SCS & 0xF), gpioAFspix);
152 152 _dev_->CR2 |= (1<<2);
153 153 }
154 154 else
155 155 {
156 156 _dev_->CR2 &= ~(1<<2);
157 157 }
158 158 return 1;
159 159 }
160 160 return -1;
161 161 }
162 162
163 163
164 164 int spienable(spi_t spidev)
165 165 {
166 166 if((spidev<3)&&(spidev>=0))
167 167 {
168 168 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
169 169 _dev_->CR1 |= (1<<6);
170 170 return 1;
171 171 }
172 172 return -1;
173 173 }
174 174
175 175
176 176 int spidisable(spi_t spidev)
177 177 {
178 178 if((spidev<3)&&(spidev>=0))
179 179 {
180 180 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
181 181 _dev_->CR1 &= ~(1<<6);
182 182 return 1;
183 183 }
184 184 return -1;
185 185 }
186 186
187 187 int spisetconfig(spi_t spidev, uint32_t config, uint32_t speed)
188 188 {
189 189 if((spidev<3)&&(spidev>=0))
190 190 {
191 191 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
192 192 _dev_->CR2 |= (1<<2);
193 193 _dev_->CR1 |= (1<<2);
194 194 spisetspeed(spidev,speed);
195 195 spisetdatabits(spidev,config & SPIBITSMASK);
196 196 spisetbitorder(spidev,config & SPIBITORDERMASK);
197 197 spisetclkinhlevel(spidev,config & SPICLKINHLVLMASK);
198 198 spisetclkphase(spidev,config & SPICLKPHASEMASK);
199 199 return 0;
200 200 }
201 201 return 1;
202 202 }
203 203
204 204 int spisetspeed(spi_t spidev, uint32_t speed)
205 205 {
206 206 if((spidev<3)&&(spidev>=0))
207 207 {
208 208 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
209 209 uint32_t apbclock = 0x00;
210 210 RCC_ClocksTypeDef RCC_ClocksStatus;
211 211 RCC_GetClocksFreq(&RCC_ClocksStatus);
212 212 if (_dev_ == SPI1)
213 213 {
214 214 apbclock = RCC_ClocksStatus.PCLK2_Frequency;
215 215 }
216 216 else
217 217 {
218 218 apbclock = RCC_ClocksStatus.PCLK1_Frequency;
219 219 }
220 220 int32_t speederror = 0x7FFFFFFF; //max error
221 221 int32_t prev_speederror = 0x7FFFFFFF;
222 222 int32_t realspeed = 0;
223 223 unsigned char divider = 0;
224 224 do
225 225 {
226 226 divider ++;
227 227 prev_speederror = speederror;
228 228 realspeed = apbclock>>(divider);
229 229 speederror = realspeed - speed;
230 230 if(speederror<0)speederror=-speederror;
231 231 if(divider>8)break;
232 232 }while(speederror<prev_speederror);
233 233 speed = apbclock>>(divider-1);
234 234 divider-=2;
235 235 _dev_->CR1 &= 0xFFD7; // clear prescaler bits 3:5
236 236 _dev_->CR1 |= ((0x7 & divider)<<3);
237 237 return 1;
238 238 }
239 239 return -1;
240 240 }
241 241
242 242
243 243 int spisetdatabits(spi_t spidev,spibits_t bitscnt)
244 244 {
245 245 if((spidev<3)&&(spidev>=0))
246 246 {
247 247 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
248 248 int result = 0;
249 249 switch(bitscnt)
250 250 {
251 251 case spi8bits:
252 252 _dev_->CR1 &= ~(1<<11);
253 253 result = 1;
254 254 break;
255 255 case spi16bits:
256 256 _dev_->CR1 |= (1<<11);
257 257 result = 1;
258 258 break;
259 259 default:
260 260 result =-1;
261 261 break;
262 262 }
263 263 return result;
264 264 }
265 265 return -1;
266 266 }
267 267
268 268 int spisetbitorder(spi_t spidev,spibitorder_t order)
269 269 {
270 270 if((spidev<3)&&(spidev>=0))
271 271 {
272 272 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
273 273 if(order==spimsbfirst)
274 274 {
275 275 _dev_->CR1 &= ~(1<<7);
276 276 return 1;
277 277 }
278 278 else
279 279 {
280 280 if(order==spilsbfirst)
281 281 {
282 282 _dev_->CR1 |= (1<<7);
283 283 return 1;
284 284 }
285 285 else return -1;
286 286 }
287 287 }
288 288 return -1;
289 289 }
290 290
291 291 int spisetclkinhlevel(spi_t spidev,spiclkinhlvl_t level)
292 292 {
293 293 if((spidev<3)&&(spidev>=0))
294 294 {
295 295 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
296 296 if(level==spiclkinhlow)
297 297 {
298 298 _dev_->CR1 &= ~(1<<1);
299 299 return 1;
300 300 }
301 301 else
302 302 {
303 303 if(level==spiclkinhhigh)
304 304 {
305 305 _dev_->CR1 |= (1<<1);
306 306 return 1;
307 307 }
308 308 else return -1;
309 309 }
310 310 }
311 311 return -1;
312 312 }
313 313
314 314 int spisetclkphase(spi_t spidev,spiclkphase_t phase)
315 315 {
316 316 if((spidev<3)&&(spidev>=0))
317 317 {
318 318 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
319 319 if(phase==spiclkfirstedge)
320 320 {
321 321 _dev_->CR1 &= ~1;
322 322 return 1;
323 323 }
324 324 else
325 325 {
326 326 if(phase==spiclksecondedge)
327 327 {
328 328 _dev_->CR1 |= 1;
329 329 return 1;
330 330 }
331 331 else return -1;
332 332 }
333 333 }
334 334 return -1;
335 335 }
336 336
337 337 int spiputw(spi_t spidev,uint16_t data)
338 338 {
339 339 if((spidev<3)&&(spidev>=0))
340 340 {
341 341 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
342 while(((_dev_->SR & (1<<1)) == 0) );
342 343 _dev_->DR = data;
343 while((_dev_->SR & (1<<7)) == (1<<7));
344 return 1;
344 while(((_dev_->SR & (1<<0)) == 0) );
345 return _dev_->DR;
345 346 }
346 347 return -1;
347 348 }
348 349 uint16_t spigetw(spi_t spidev)
349 350 {
350 351 if((spidev<3)&&(spidev>=0))
351 352 {
352 353 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
353 while((_dev_->SR & (1<<7)) == (1<<7));
354 while(((_dev_->SR & (1<<1)) == 0) );
354 355 _dev_->DR = 0xFFFF;
355 while(((_dev_->SR & (1<<0)) == 0) || (_dev_->SR & (1<<7)) == (1<<7));
356 while(((_dev_->SR & (1<<0)) == 0) );
356 357 return _dev_->DR;
357 358 }
358 359 return -1;
359 360 }
360 361
361 362 int spiputs(spi_t spidev,char* s)
362 363 {
363 364 while (*s) spiputw(spidev,*s++);
364 365 return 1;
365 366 }
366 367
367 368 int spigets(spi_t spidev,char* s)
368 369 {
369 370 do
370 371 {
371 372 (*s) = spigetw(spidev);
372 373 }
373 374 while(*s++);
374 375 return 1;
375 376 }
376 377
377 378 int spiputnw(spi_t spidev,uint16_t* w,int n)
378 379 {
379 380 while(n!=0)
380 381 {
381 382 spiputw(spidev,*w++);
382 383 n--;
383 384 }
384 385 return 1;
385 386 }
386 387
387 388 int spigetnw(spi_t spidev,uint16_t* w,int n)
388 389 {
389 390 while(n!=0)
390 391 {
391 392 *w++=spigetw(spidev);
392 393 n--;
393 394 }
394 395 return 1;
395 396 }
396 397
397 398 int spiputnc(spi_t spidev,char* c,int n)
398 399 {
399 400 while(n!=0)
400 401 {
401 402 spiputw(spidev,*c++);
402 403 n--;
403 404 }
404 405 return 1;
405 406 }
406 407
407 408 int spigetnc(spi_t spidev,char* c,int n)
408 409 {
409 410 while(n!=0)
410 411 {
411 412 *c++=spigetw(spidev);
412 413 n--;
413 414 }
414 415 return 1;
415 416 }
416 417
417 418 int spiavailiabledata(spi_t spidev)
418 419 {
419 420 return 0;
420 421 }
421 422
422 423
423 424 int spitransactionfinished(spi_t spidev)
424 425 {
425 426 SPI_TypeDef* _dev_ = _spi_dev_table[(int)spidev];
426 427 if((spidev<3)&&(spidev>=0))
427 428 {
428 429 if((_dev_->SR & (1<<7)) == (1<<7))return 1;
429 430 }
430 431 return 0;
431 432 }
432 433
433 434
434 435
435 436
436 437
437 438
438 439
439 440
440 441
441 442
442 443
443 444
444 445
445 446
446 447
447 448
448 449
General Comments 0
You need to be logged in to leave comments. Login now