source: azure_iot_hub_riscv/trunk/asp_baseplatform/gdic/spi_driver/spi_driver.c@ 453

Last change on this file since 453 was 453, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 22.8 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 * Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
11 *
12 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * と.
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * 報告すること.
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
32 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
33 * 免責すること.
34 *
35 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
36 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
37 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
38 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
39 * の責任を負わない.
40 *
41 * $Id$
42 */
43
44/*
45 * SPI用デバイスドライバ
46 */
47
48#include <kernel.h>
49#include <t_syslog.h>
50#include <t_stdlib.h>
51#include <string.h>
52#include <target_syssvc.h>
53#include "syssvc/serial.h"
54#include "syssvc/syslog.h"
55#include "device.h"
56#include "spi.h"
57#include "pinmode.h"
58#include "spi_driver.h"
59
60#define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
61#define sil_andw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
62#define sil_modw_mem(a, b, c) sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
63
64#define INIT_RETRY_COUNT 32
65
66#define CRC16POLY 0x1021
67
68static const uint8_t CMD0[5] = {0x40, 0x00, 0x00, 0x00, 0x00};
69static const uint8_t CMD8[5] = {0x48, 0x00, 0x00, 0x01, 0xAA};
70static const uint8_t CMD9[5] = {0x49, 0x00, 0x00, 0x00, 0x00};
71static const uint8_t CMD10[5] = {0x4A, 0x00, 0x00, 0x00, 0x00};
72static const uint8_t CMD16[5] = {0x50, 0x00, 0x00, 0x02, 0x00};
73static const uint8_t CMD55[5] = {0x77, 0x00, 0x00, 0x00, 0x00};
74static const uint8_t ACMD41[5] = {0x69, 0x40, 0x00, 0x00, 0x00};
75static const uint8_t CMD58[5] = {0x7A, 0x00, 0x00, 0x00, 0x00};
76
77static bool_t sdcard_sense = true;
78static SDCARD_Handler_t SdHandle;
79
80/* Buffer used for transmission */
81uint8_t aTxBuffer[BUFFERSIZE];
82
83/* Buffer used for reception */
84uint8_t aRxBuffer[BUFFERSIZE];
85
86#ifndef SPI_DRIVER_NOSTART
87/*
88 * GPIO設定関数
89 */
90static void
91pinMode(uint8_t no, uint32_t otype, uint32_t pullmode)
92{
93 Arduino_PortControlBlock *pgcb = getGpioTable(DIGITAL_PIN, no);
94 GPIO_Init_t GPIO_Init_Data;
95
96 if(pgcb == NULL)
97 return;
98 pinClock(no);
99 GPIO_Init_Data.mode = GPIO_MODE_OUTPUT;
100 GPIO_Init_Data.pull = pullmode;
101 GPIO_Init_Data.otype = otype;
102 GPIO_Init_Data.speed = GPIO_SPEED_FAST;
103 gpio_setup(pgcb->giobase, &GPIO_Init_Data, pgcb->giopin);
104}
105
106/*
107 * SPI初期化関数
108 */
109SPI_Handle_t *
110spi_start(SPI_Setup_t *psps)
111{
112 SPI_Init_t spi_initd;
113 SPI_Handle_t *hspi;
114
115 /*
116 * CS PORT(D10-PB6)
117 */
118 pinMode(psps->cs_pin, psps->otype, psps->pullmode);
119 /*
120 * RS PORT(D8-PA9)
121 */
122 pinMode(psps->rs_pin, psps->otype, psps->pullmode);
123 /*
124 * RST PORT(D9-PC7)
125 */
126 pinMode(psps->rst_pin, psps->otype, psps->pullmode);
127 /*
128 * CS2 PORT(D4-PB5)
129 */
130 pinMode(psps->cs2_pin, psps->otype, psps->pullmode);
131 SdHandle.cs2_port = psps->cs2_pin;
132
133 memset(&spi_initd, 0, sizeof(SPI_Init_t));
134 spi_initd.Prescaler = psps->baud;
135 spi_initd.Direction = SPI_DIRECTION_2LINES;
136 spi_initd.CLKPhase = SPI_PHASE_1EDGE;
137 spi_initd.CLKPolarity = SPI_POLARITY_LOW;
138 spi_initd.CRC = SPI_CRC_DISABLE;
139 spi_initd.CRCPolynomial = 7;
140 spi_initd.DataSize = SPI_DATASIZE_8BIT;
141 spi_initd.SignBit = SPI_DATA_MSB;
142 spi_initd.NSS = SPI_NSS_SOFT;
143 spi_initd.TIMode = SPI_TIMODE_DISABLE;
144 spi_initd.Mode = SPI_MODE_MASTER;
145 spi_initd.semid = psps->spi_sem;
146 spi_initd.semlock = 0;
147
148 if((hspi = spi_init(psps->port, &spi_initd)) == NULL){
149 syslog_0(LOG_ERROR, "spi_start initialize error !");
150 }
151 return hspi;
152}
153
154/*
155 * SPI終了関数
156 */
157void
158spi_end(SPI_Handle_t *hspi)
159{
160 spi_deinit(hspi);
161}
162#endif /* SPI_DRIVER_NOSTART */
163
164
165/*
166 * CRC7計算関数
167 */
168static uint8_t
169calc_CRC7(const uint8_t *data, int len)
170{
171 uint_t i, j;
172 uint8_t crc = 0, dt;
173
174 for(i = 0; i < len; i++){
175 dt = *data++;
176 for(j = 0; j < 8; j++){
177 crc <<=1;
178 if ((crc & 0x80) ^ (dt & 0x80))
179 crc ^= 0x09;
180 dt <<= 1;
181 }
182 }
183 return ((crc & 0x7f) << 1) | 1;
184}
185
186/*
187 * CRC16-CCITT計算関数
188 */
189static uint16_t
190calc_CRC16(const uint8_t *data, int len)
191{
192 uint16_t crc = 0;
193 int i, j;
194
195 for(i = 0; i < len; i++){
196 crc ^= (data[i]<<8);
197 for(j = 0; j < 8; j++){
198 if(crc & 0x8000)
199 crc = (crc << 1) ^ CRC16POLY;
200 else
201 crc <<= 1;
202 }
203 }
204 return crc;
205}
206
207/*
208 * SDCARDからのデータ読み込み
209 */
210static ER
211sdcard_read(SPI_Handle_t *hspi, uint8_t *pres, int size)
212{
213 ER ercd;
214
215#if SPI_WAIT_TIME != 0
216 ercd = spi_receive(hspi, (uint8_t*)pres, size);
217#else
218 if((ercd = spi_receive(hspi, (uint8_t*)pres, size)) == E_OK){
219 ercd = spi_wait(hspi, 50);
220 }
221#endif
222 if(ercd != E_OK)
223 syslog_1(LOG_ERROR, "sdcard_read ERROR(%d) !", ercd);
224 return ercd;
225}
226
227/*
228 * SDCARDへのデータ書き込み
229 */
230static ER
231sdcard_write(SPI_Handle_t *hspi, uint8_t *pres, int size)
232{
233 ER ercd;
234
235#if SPI_WAIT_TIME != 0
236 ercd = spi_transmit(hspi, (uint8_t*)pres, size);
237#else
238 if((ercd = spi_transmit(hspi, (uint8_t*)pres, size)) == E_OK){
239 ercd = spi_wait(hspi, 50);
240 }
241#endif
242 if(ercd != E_OK)
243 syslog_1(LOG_ERROR, "sdcard_write ERROR(%d) !", ercd);
244 return ercd;
245}
246
247/*
248 * SDCARDへのコマンド送信
249 */
250static ER
251sdcard_sendcommand(SPI_Handle_t *hspi, const uint8_t *cmd, int size)
252{
253 ER ercd = E_OK;
254 uint8_t crc;
255
256 crc = calc_CRC7(cmd, size);
257 memcpy(aTxBuffer, cmd, size);
258 aTxBuffer[size] = crc;
259#if SPI_WAIT_TIME != 0
260 ercd = spi_transmit(hspi, (uint8_t*)aTxBuffer, (size+1));
261#else
262 if((ercd = spi_transmit(hspi, (uint8_t*)aTxBuffer, (size+1))) == E_OK){
263 ercd = spi_wait(hspi, 50);
264 }
265#endif
266 return ercd;
267}
268
269/*
270 * SDCARDへのダミー書き込み
271 */
272static ER
273sdcard_dummywrite(SPI_Handle_t *hspi)
274{
275 uint8_t dummy[2];
276 dummy[0] = 0xff;
277 return sdcard_write(hspi, dummy, 1);
278}
279
280/*
281 * SDCARDからのレスポンス受信
282 */
283static ER
284sdcard_response(SPI_Handle_t *hspi, uint8_t *pres, int size, int timeout)
285{
286 int tick, i = 0;
287
288 timeout *= 100;
289 for(tick = 0 ; tick < timeout ; tick++){
290 if(sdcard_read(hspi, aRxBuffer, 1) == E_OK){
291 pres[i] = aRxBuffer[0];
292 if((aRxBuffer[0] & 0x80) == 0){
293 i++;
294 if(i >= size)
295 return E_OK;
296 }
297 }
298 sil_dly_nse(1000*10);
299 }
300 return E_TMOUT;
301}
302
303/*
304 * SDCARDからのデータ受信
305 */
306static ER
307sdcard_receive(SPI_Handle_t *hspi, uint8_t *pdata, int size, uint16_t *crc, int timeout)
308{
309 ER ercd = E_OK;
310 bool_t ff_count;
311 int tick, i = 0;
312
313 for(tick = 0 ; tick < (timeout*1000) ; tick++){
314 *crc = 0xffff;
315 if((ercd = sdcard_read(hspi, aRxBuffer, 1)) == E_OK){
316 if(aRxBuffer[0] == 0xfe){
317 if((ercd = sdcard_read(hspi, pdata, size)) != E_OK)
318 return ercd;
319 ercd = E_TMOUT;
320 for(i = 0, ff_count = 0 ; i < 24 ; i++){
321 sdcard_read(hspi, aRxBuffer, 1);
322 dly_tsk(2);
323 if(aRxBuffer[0] != 0xff){
324 if(ff_count == 0)
325 *crc = aRxBuffer[0]<<8;
326 else if(ff_count == 1)
327 *crc |= aRxBuffer[0];
328 ff_count++;
329 }
330 if(i >= 1 && aRxBuffer[0] == 0xff && ff_count > 0)
331 ercd = E_OK;
332 }
333 return ercd;
334 }
335 else if(aRxBuffer[0] != 0xff){
336 syslog_2(LOG_NOTICE, "## sdcard_receive i(%d) resp[%02x] ##", i, aRxBuffer[0]);
337 }
338 }
339 sil_dly_nse(1000);
340 }
341 return E_TMOUT;
342}
343
344/*
345 * SDCARDへのデータ送信
346 */
347static ER
348sdcard_send(SPI_Handle_t *hspi, uint8_t *pdata, int size)
349{
350 ER ercd = E_OK;
351 uint8_t data[4];
352 uint16_t crc;
353 int res_count = 0;
354 int i = 0;
355
356 crc = calc_CRC16((const uint8_t *)pdata, size);
357 data[0] = 0xff;
358 data[1] = 0xfe;
359 if((ercd = sdcard_write(hspi, data, 2)) != E_OK)
360 return ercd;
361 if((ercd = sdcard_write(hspi, pdata, size)) != E_OK)
362 return ercd;
363 data[0] = crc >> 8;
364 data[1] = crc & 0xff;
365 if((ercd = sdcard_write(hspi, data, 2)) != E_OK)
366 return ercd;
367 ercd = E_TMOUT;
368 for(i = 0 ; i < 24 ; i++){
369 sdcard_read(hspi, aRxBuffer, 1);
370 dly_tsk(1);
371 if(aRxBuffer[0] != 0xff){
372 if(res_count == 0){
373 if((aRxBuffer[0] & 0x1F) == 0x05)
374 ercd = E_OK;
375 else
376 ercd = E_SYS;
377 res_count++;
378 }
379 else if(aRxBuffer[0] == 0x00)
380 res_count++;
381 }
382 else if(res_count >= 2)
383 break;
384 }
385 return ercd;
386}
387/*
388 * SDCARD通信ロック
389 */
390static ER
391sdcard_lock(SDCARD_Handler_t *hsd)
392{
393 ER ercd = E_OK;
394 if(hsd->spi_lock != 0)
395 ercd = wai_sem(hsd->spi_lock);
396 digitalWrite(hsd->cs2_port, PORT_LOW);
397 return ercd;
398}
399
400/*
401 * SDCARD通信アンロック
402 */
403static ER
404sdcard_unlock(SDCARD_Handler_t *hsd)
405{
406 ER ercd = E_OK;
407 digitalWrite(hsd->cs2_port, PORT_HIGH);
408 if(hsd->spi_lock != 0)
409 ercd = sig_sem(hsd->spi_lock);
410 return ercd;
411}
412
413/*
414 * SDCARDリセット
415 */
416static ER
417sdcard_reset(SDCARD_Handler_t *hsd)
418{
419 ER ercd = E_OK;
420 uint8_t resp[2];
421 int i = 0;
422
423 if((ercd = sdcard_lock(hsd)) != E_OK){
424 return ercd;
425 }
426 for(i = 0 ; i < 20 ; i++){
427 if((ercd = sdcard_sendcommand(hsd->hspi, CMD55, sizeof(CMD55))) != E_OK)
428 continue;
429 if((ercd = sdcard_response(hsd->hspi, resp, 1, 300)) != E_OK)
430 continue;
431 if((ercd = sdcard_sendcommand(hsd->hspi, ACMD41, sizeof(ACMD41))) != E_OK)
432 continue;
433 if((ercd = sdcard_response(hsd->hspi, resp, 1, 300)) != E_OK)
434 continue;
435 if(resp[0] == 0x00)
436 break;
437 dly_tsk(40);
438 }
439 sdcard_unlock(hsd);
440 return ercd;
441}
442
443
444/*
445 * SDCARDのSPI設定
446 */
447void
448sdcard_setspi(ID portid, SPI_Handle_t *hspi)
449{
450 SdHandle.hspi = hspi;
451}
452
453/*
454 * SDCARDのSPI設定:改良型
455 */
456void
457sdcard_setspi2(ID portid, SPI_Handle_t *hspi, uint8_t cs_port)
458{
459 SdHandle.hspi = hspi;
460 SdHandle.cs2_port = cs_port;
461}
462
463/*
464 * SDCARDの初期化関数、エラーならばカードなし
465 */
466bool_t
467sdcard_init(ID portid)
468{
469 SDCARD_Handler_t *hsd = &SdHandle;
470 SPI_Handle_t *hspi;
471 uint8_t resp[8];
472 uint8_t checkno = 0;
473 ER ercd;
474 int i;
475
476 if(!sdcard_sense)
477 return false;
478
479 sdcard_sense = false;
480 if((hspi = hsd->hspi) == NULL)
481 return false;
482 hsd->hspi = NULL;
483
484 if((ercd = sdcard_lock(hsd)) != E_OK)
485 return false;
486 if((ercd = sdcard_sendcommand(hspi, CMD0, sizeof(CMD0))) != E_OK){
487 sdcard_unlock(hsd);
488 return false;
489 }
490 if((ercd = sdcard_response(hspi, resp, 1, 500)) != E_OK){
491 sdcard_unlock(hsd);
492 return false;
493 }
494#if 1 /* ROI DEBUG */
495 syslog_4(LOG_NOTICE, "## resp 0[%02x] 1[%02x] 2[%02x] 3[%02x] ##", resp[0], resp[1], resp[2], resp[3]);
496#endif /* ROI DEBUG */
497 sdcard_unlock(hsd);
498 sdcard_dummywrite(hspi);
499
500 if((ercd = sdcard_lock(hsd)) != E_OK)
501 return false;
502 if((ercd = sdcard_sendcommand(hspi, CMD8, sizeof(CMD8))) == E_OK){
503 sdcard_response(hspi, resp, 1, 500);
504 }
505 if(ercd == E_OK && (resp[0] & 0x04) == 0x00){
506 ercd = sdcard_read(hspi, resp, 4);
507 if(resp[2] != 0x01 || resp[3] != 0xAA){
508 syslog_4(LOG_ERROR, "CMD8(1) ERROR [%02x][%02x][%02x][%02x] !", resp[0], resp[1], resp[2], resp[3]);
509 sdcard_unlock(hsd);
510 return false;
511 }
512 }
513 else{
514 sdcard_unlock(hsd);
515 sdcard_dummywrite(hspi);
516
517 if((ercd = sdcard_lock(hsd)) != E_OK)
518 return false;
519 checkno = 1;
520 if((ercd = sdcard_sendcommand(hspi, CMD58, sizeof(CMD58))) == E_OK){
521 ercd = sdcard_response(hspi, resp, 1, 500);
522 }
523 if(ercd == E_OK && (resp[0] & 0x04) == 0x00){
524 ercd = sdcard_read(hspi, resp, 4);
525 if(resp[2] != 0x01){
526 syslog_4(LOG_ERROR, "CMD58 ERROR [%02x][%02x][%02x][%02x] !", resp[0], resp[1], resp[2], resp[3]);
527 sdcard_unlock(hsd);
528 return false;
529 }
530 }
531 else{
532 syslog_2(LOG_ERROR, "CMD58 ERROR(%d) [%02x] !", ercd, resp[0]);
533 sdcard_unlock(hsd);
534 return false;
535 }
536 }
537 sdcard_unlock(hsd);
538 sdcard_dummywrite(hspi);
539
540 for(i = 0 ; i < 50 ; i++){ /* 5sec */
541 do{
542 if((ercd = sdcard_lock(hsd)) != E_OK)
543 return false;
544 if((ercd = sdcard_sendcommand(hspi, CMD55, sizeof(CMD55))) == E_OK){
545 if((ercd = sdcard_response(hspi, resp, 1, 500)) == E_OK){
546 sdcard_unlock(hsd);
547 sdcard_dummywrite(hspi);
548
549 if((ercd = sdcard_lock(hsd)) != E_OK)
550 return false;
551 if((ercd = sdcard_sendcommand(hspi, ACMD41, sizeof(ACMD41))) == E_OK){
552 if((ercd = sdcard_response(hspi, resp, 1, 500)) == E_OK){
553 sdcard_unlock(hsd);
554 sdcard_dummywrite(hspi);
555 break;
556 }
557 }
558 }
559 }
560 sdcard_unlock(hsd);
561 sdcard_dummywrite(hspi);
562 dly_tsk(200);
563 }while(ercd != E_OK);
564 if(resp[0] == 0x00)
565 break;
566 dly_tsk(100);
567 }
568
569 if(checkno == 1){
570 sdcard_sense = true;
571 hsd->cardtype = SD_CARD_V20;
572 hsd->hspi = hspi;
573 return true;
574 }
575
576 if((ercd = sdcard_lock(hsd)) != E_OK)
577 return false;
578 if((ercd = sdcard_sendcommand(hspi, CMD58, sizeof(CMD58))) == E_OK){
579 ercd = sdcard_response(hspi, resp, 1, 500);
580 }
581 if(ercd == E_OK && resp[0] == 0x00){
582 sdcard_sense = true;
583 ercd = sdcard_read(hspi, resp, 4);
584 if((resp[0] & 0x40) == 0)
585 hsd->cardtype = SD_CARD_V20;
586 else
587 hsd->cardtype = SD_CARD_HC;
588 hsd->hspi = hspi;
589 sdcard_unlock(hsd);
590 sdcard_dummywrite(hspi);
591 return true;
592 }
593 sdcard_unlock(hsd);
594 return false;
595}
596
597/*
598 * SDCARDオープン
599 */
600SDCARD_Handler_t*
601sdcard_open(ID portid)
602{
603 if(SdHandle.hspi != NULL){
604 SdHandle.spi_lock = 0;
605 SdHandle.RetryCount = INIT_RETRY_COUNT;
606 SdHandle.read_count = 0;
607 SdHandle.write_count = 0;
608 SdHandle.read_retry_count = 0;
609 SdHandle.write_retry_count = 0;
610 SdHandle.read_error = 0;
611 SdHandle.write_error = 0;
612 return &SdHandle;
613 }
614 else
615 return NULL;
616}
617
618/*
619 * SDCARDクローズ(未処理)
620 */
621ER
622sdcard_close(SDCARD_Handler_t *hsd)
623{
624 return E_OK;
625}
626
627/*
628 * SDカードの情報を取り込む
629 * parameter1 hsd: SDCARDハンドラ
630 * parameter2 pCardInfo: カードインフォ構造体へのポインタ
631 * return ERコード
632 */
633ER
634sdcard_getcardinfo(SDCARD_Handler_t *hsd, SDCARD_CardInfo_t *pCardInfo)
635{
636 ER ercd = E_OK;
637 uint32_t devicesize;
638 uint8_t blocklen, mul;
639
640 pCardInfo->cardtype = (uint8_t)(hsd->cardtype);
641 pCardInfo->RCA = (uint16_t)(hsd->RCA);
642
643 if(hsd->cardtype == SD_CARD_V11 || hsd->cardtype == SD_CARD_V20){
644 /* ブロック長を取り込む */
645 blocklen = (uint8_t)(hsd->CSD[5] & 0x0F);
646 devicesize = (hsd->CSD[6] & 0x03) << 10;
647 devicesize |= hsd->CSD[7] << 2;
648 devicesize |= (hsd->CSD[8] & 0xC0) >> 6;
649 mul = (hsd->CSD[9] & 0x03) << 1;
650 mul |= (hsd->CSD[10] & 0x80) >> 7;
651 pCardInfo->capacity = (devicesize + 1) ;
652 pCardInfo->capacity *= (1 << (mul + 2));
653 pCardInfo->blocksize = 1 << (blocklen);
654 pCardInfo->capacity *= pCardInfo->blocksize;
655 }
656 else if(hsd->cardtype == SD_CARD_HC){
657 devicesize = (hsd->CSD[7] & 0x3F) << 16;
658 devicesize |= (hsd->CSD[8] & 0xFF) << 8;
659 devicesize |= (hsd->CSD[9] & 0xFF);
660 pCardInfo->capacity = (uint64_t)(devicesize + 1) << 19 /* 512 * 1024*/;
661 pCardInfo->blocksize = 512;
662 }
663 else{
664 pCardInfo->capacity = 0;
665 pCardInfo->blocksize = 512;
666 ercd = E_OBJ;
667 }
668 pCardInfo->maxsector = pCardInfo->capacity / 512;
669 pCardInfo->status = (uint8_t)hsd->CSD[14];
670 return ercd;
671}
672
673/*
674 * CIDの取得
675 * SDカードCMD2,MMCカードCMD1送信後のレスポンス受信
676 * parameter1 hsd: SDCARDハンドラ
677 * return ERコード
678 */
679ER
680sdcard_checkCID(SDCARD_Handler_t *hsd)
681{
682 ER ercd = E_OK;
683 uint8_t resp[2];
684 uint16_t crc;
685 int i, timeout = 50;
686
687 if((ercd = sdcard_lock(hsd)) != E_OK)
688 return ercd;
689 for(i = 0 ; i < INIT_RETRY_COUNT ; i++, timeout = 1000){
690 /*
691 * CMD10送信
692 */
693 if((ercd = sdcard_sendcommand(hsd->hspi, CMD10, sizeof(CMD10))) != E_OK)
694 break;
695 if((ercd = sdcard_response(hsd->hspi, resp, 1, timeout)) != E_OK)
696 continue;
697 else if(resp[0] == 0x00){
698 sdcard_receive(hsd->hspi, &hsd->CID[0], 16, &crc, 5000);
699 sdcard_unlock(hsd);
700 return ercd;
701 }
702 }
703 sdcard_unlock(hsd);
704 if(i == INIT_RETRY_COUNT)
705 ercd = E_TMOUT;
706 return ercd;
707}
708
709/*
710 * CSD(Card Specific DATA)の取得
711 * parameter1 hsd: SDCARDハンドラ
712 * return ERコード
713 */
714ER
715sdcard_sendCSD(SDCARD_Handler_t *hsd)
716{
717 ER ercd = E_OK;
718 uint8_t resp[2];
719 uint16_t crc;
720 int i, timeout = 50;
721
722 if((ercd = sdcard_lock(hsd)) != E_OK)
723 return ercd;
724 for(i = 0 ; i < INIT_RETRY_COUNT ; i++, timeout = 1000){
725 /*
726 * CMD9送信
727 */
728 if((ercd = sdcard_sendcommand(hsd->hspi, CMD9, sizeof(CMD9))) != E_OK)
729 break;
730 if((ercd = sdcard_response(hsd->hspi, resp, 1, timeout)) != E_OK)
731 continue;
732 else if(resp[0] == 0x00){
733 sdcard_receive(hsd->hspi, &hsd->CSD[0], 16, &crc, 5000);
734 sdcard_unlock(hsd);
735 return E_OK;
736 }
737 dly_tsk(100);
738 }
739 if(i == INIT_RETRY_COUNT)
740 ercd = E_TMOUT;
741 sdcard_unlock(hsd);
742 return ercd;
743}
744
745/*
746 * SELECT_CARDコマンドの送信(未処理)
747 * parameter1 hsd: SDMMCハンドラ
748 * return ERコード
749 */
750ER
751sdcard_select_card(SDCARD_Handler_t *hsd, uint64_t addr)
752{
753 return E_OK;
754}
755
756/*
757 * SDCARDコンフィギュレーション
758 * parameter1 hsd: SDMMCハンドラ
759 * return ERコード
760 */
761ER
762sdcard_configuration(SDCARD_Handler_t *hsd)
763{
764 ER ercd = E_OK;
765 uint8_t resp[2];
766 int i;
767
768 if((ercd = sdcard_lock(hsd)) != E_OK)
769 return ercd;
770 for(i = 0 ; i < INIT_RETRY_COUNT ; i++){
771 if((ercd = sdcard_sendcommand(hsd->hspi, CMD16, sizeof(CMD16))) != E_OK)
772 break;
773 ercd = sdcard_response(hsd->hspi, resp, 1, 2000);
774 if(ercd == E_OK && resp[0] == 0x00)
775 break;
776 dly_tsk(100);
777 }
778 sdcard_unlock(hsd);
779 if(i == INIT_RETRY_COUNT && resp[0] != 0x04) /* SanDisk */
780 ercd = E_TMOUT;
781 return ercd;
782}
783
784/*
785 * SDCARDブロックREAD
786 * parameter1 hsd: SDCARDハンドラ
787 * parameter2 pbuf: 読み出しデータ格納領域のポインタ(uint32_t型)
788 * parameter3 ReadAddr: カード上の読み出し位置
789 * parameter4 blocksize: ブロックサイズ
790 * parameter5 num: 読み出しブロック数
791 * return ERコード
792 */
793ER
794sdcard_blockread(SDCARD_Handler_t *hsd, uint32_t *pbuf, uint64_t ReadAddr, uint32_t blocksize, uint32_t num)
795{
796 ER ercd = E_OK;
797 static uint8_t cmd17[8];
798 uint8_t resp[2];
799 uint32_t incsec = blocksize;
800 uint16_t crc1, crc2;
801 uint16_t crc3 = 0xffff;
802 int no, i = 0;
803
804 hsd->read_count++;
805 if(hsd->cardtype == SD_CARD_HC){
806 blocksize = 512;
807 incsec = 1;
808 ReadAddr /= 512;
809 }
810 for(no = 0 ; no < num ; no++){
811 for(i = 0 ; i < hsd->RetryCount ; i++){
812 if((ercd = sdcard_lock(hsd)) != E_OK){
813 return ercd;
814 }
815
816 cmd17[0] = 0x51;
817 cmd17[1] = (ReadAddr >> 24) & 0xff;
818 cmd17[2] = (ReadAddr >> 16) & 0xff;
819 cmd17[3] = (ReadAddr >> 8) & 0xff;
820 cmd17[4] = ReadAddr & 0xff;
821 /*
822 * CMD17送信
823 */
824 if((ercd = sdcard_sendcommand(hsd->hspi, cmd17, 5)) == E_OK){
825 if((ercd = sdcard_response(hsd->hspi, resp, 1, 50)) == E_OK && resp[0] == 0x00){
826 ercd = sdcard_receive(hsd->hspi, (uint8_t *)pbuf, blocksize, &crc1, 5000);
827 if(ercd == E_OK){
828 dly_tsk(5);
829 crc2 = calc_CRC16((const uint8_t *)pbuf, blocksize);
830 if(crc1 == crc2){
831 sdcard_unlock(hsd);
832 break;
833 }
834 else if(crc3 == crc2){
835 hsd->read_error++;
836 if(i > 1)
837 syslog_4(LOG_ERROR, "sdcard_blockread crc[%04x][%04x] count(%d) error(%d) !", crc1, crc2, i, hsd->read_error);
838 sdcard_unlock(hsd);
839 break;
840 dly_tsk(100);
841 }
842 crc3 = crc2;
843 }
844 }
845 }
846 hsd->read_retry_count++;
847 sdcard_unlock(hsd);
848 dly_tsk(10);
849 sdcard_reset(hsd);
850 dly_tsk(10);
851 sdcard_configuration(hsd);
852 }
853 if(i == hsd->RetryCount && ercd == E_OK){
854 ercd = E_TMOUT;
855 break;
856 }
857 ReadAddr += incsec;
858 pbuf += (blocksize/4);
859 }
860 return ercd;
861}
862
863/*
864 * SDCARDブロックWRITE
865 * parameter1 hsd: SDCARDハンドラ
866 * parameter2 pbuf: 書込みデータ格納領域のポインタ(uint32_t型)
867 * parameter3 WritedAddr: カード上の書き込み位置
868 * parameter4 blocksize: ブロックサイズ
869 * parameter5 num: 書込みブロック数
870 * return ERコード
871 */
872ER
873sdcard_blockwrite(SDCARD_Handler_t *hsd, uint32_t *pbuf, uint64_t WriteAddr, uint32_t blocksize, uint32_t num)
874{
875 ER ercd = E_OK;
876 static uint8_t cmd24[8];
877 uint8_t resp[2];
878 uint32_t incsec = blocksize;
879 int no, i = 0;
880
881 hsd->write_count++;
882 if(hsd->cardtype == SD_CARD_HC){
883 blocksize = 512;
884 incsec = 1;
885 WriteAddr /= 512;
886 }
887 for(no = 0 ; no < num ; no++){
888 for(i = 0 ; i < hsd->RetryCount ; i++){
889 if((ercd = sdcard_lock(hsd)) != E_OK){
890 return ercd;
891 }
892
893 cmd24[0] = 0x58;
894 cmd24[1] = (WriteAddr >> 24) & 0xff;
895 cmd24[2] = (WriteAddr >> 16) & 0xff;
896 cmd24[3] = (WriteAddr >> 8) & 0xff;
897 cmd24[4] = WriteAddr & 0xff;
898 /*
899 * CMD24送信
900 */
901 if((ercd = sdcard_sendcommand(hsd->hspi, cmd24, 5)) == E_OK){
902 if((ercd = sdcard_response(hsd->hspi, resp, 1, 50)) == E_OK && resp[0] == 0x00){
903 ercd = sdcard_send(hsd->hspi, (uint8_t *)pbuf, blocksize);
904 if(ercd == E_OK){
905 sdcard_unlock(hsd);
906 break;
907 }
908 }
909 }
910 hsd->read_retry_count++;
911 sdcard_unlock(hsd);
912 dly_tsk(10);
913 sdcard_reset(hsd);
914 dly_tsk(10);
915 sdcard_configuration(hsd);
916 }
917 if(i == hsd->RetryCount && ercd == E_OK){
918 ercd = E_TMOUT;
919 break;
920 }
921 WriteAddr += incsec;
922 pbuf += (blocksize/4);
923 }
924 return ercd;
925}
926
927/*
928 * SDCARDブロック転送終了待ち
929 * parameter1 hsd: SDCARDハンドラ
930 * parameter2 Timeout: タイムアウト値(1msec)
931 * return ERコード
932 */
933ER
934sdcard_wait_transfar(SDCARD_Handler_t *hsd, uint32_t Timeout)
935{
936 return E_OK;
937}
938
939/*
940 * SDカードダミー処理
941 * parameter1 hsd: SDCARDハンドラ
942 * return ERコード
943 */
944ER
945sdcard_dummy(SDCARD_Handler_t *hsd)
946{
947 return E_OK;
948}
949
950
Note: See TracBrowser for help on using the repository browser.