2 #ifndef LIBPROPELLER_SDSAFESPI_H_
3 #define LIBPROPELLER_SDSAFESPI_H_
7 #define YIELD() __asm__ volatile( "" ::: "memory" )
10 #define RET_IF_ERROR_INT if(HasError()){return error;}
11 #define RET_IF_ERROR if(HasError()){return;}
12 #define THROW_INT(value) {SetErrorCode((value)); return error;}
13 #define THROW(value) {SetErrorCode((value)); return;}
71 return Start(basepin, (basepin + 1), (basepin + 2), (basepin + 3));
82 int Start(
const int pin_do,
const int pin_clk,
83 const int pin_di,
const int pin_cs) {
90 waitcnt((CLKFREQ >> 6) + CNT);
92 mask_do = 1 << pin_do;
93 mask_di = 1 << pin_di;
94 mask_cs = 1 << pin_cs;
95 mask_clk = 1 << pin_clk;
96 mask_all = mask_cs | (1 << pin_clk) | mask_di;
98 volatile uint8_t * ldat = dat();
99 ((
int *) & ldat[1172])[0] = pin_do;
100 ((
int *) & ldat[1184])[0] = mask_do;
101 ((
int *) & ldat[1176])[0] = pin_clk;
102 ((
int *) & ldat[1180])[0] = pin_di;
103 ((
int *) & ldat[1188])[0] = mask_di;
104 ((
int *) & ldat[1192])[0] = mask_cs;
105 ((
int *) & ldat[1200])[0] = 9;
107 ((
int *) & ldat[1196])[0] = mask_all;
112 for (
int i = 0; i < 4096; i++) {
113 OUTA |= 1 << pin_clk;
114 OUTA &= ~(1 << pin_clk);
117 spi_block_index = CNT;
120 for (
int i = 0; i < 10; i++) {
122 TmpA = SendCommandSlow(Cmd0, 0, 0x95);
128 for (
int jk = 0; jk < 4; jk++) {
136 while (ReadSlow() != 0xFF) {
142 SendCommandSlow(Cmd12, 0, 0x61);
154 if (SendCommandSlow(Cmd8, 426, 135) == 1) {
157 if ((ReadSlow32() & 0x1ff) != 0x1AA) {
165 while (SendCommandSlow(Acmd41, ((1 << 30)), 0x77)) {
170 if (SendCommandSlow(Cmd58, 0, 0xFD) != 0) {
176 if (ReadSlow32() & (1 << 30)) {
178 ((
int *) & ldat[1200])[0] = 0;
185 if (SendCommandSlow(Acmd41, 0, 0xE5) < 2) {
188 while (SendCommandSlow(Acmd41, 0, 0xE5)) {
194 while (SendCommandSlow(Cmd1, 0, 0xF9)) {
200 SendCommandSlow(Cmd16, 512, 0x15);
204 SendCommandSlow(Cmd59, 0, 0x91);
212 ((
int *) & ldat[1212])[0] = (0b00100 << 26) | (pin_di << 0);
214 ((
int *) & ldat[1220])[0] = (0b00100 << 26) | (pin_clk << 0);
216 ((
int *) & ldat[1216])[0] = CLKFREQ >> (1 + 2 + 3);
219 const int idle_limit = 125;
220 ((
int *) & ldat[1256])[0] = CLKFREQ / (1000 / idle_limit);
223 ((
int *) & ldat[1204])[0] = (int) (&spi_buffer_address);
224 ((
int *) & ldat[1208])[0] = (int) (&spi_block_index);
227 spi_engine_cog = (cognew((
int) (&(*(
int *) & ldat[0])), (
int) (&spi_command)) + 1);
229 if (spi_engine_cog == 0) {
233 while (spi_command != (-1)) {
241 void ReadBlock(
const int block_index,
char * buffer_address) {
242 if (spi_engine_cog == 0) {
246 if ((
int) buffer_address & 0x3) {
250 spi_block_index = block_index;
251 spi_buffer_address = buffer_address;
253 while (spi_command ==
'r') {
256 if (spi_command < 0) {
261 void WriteBlock(
const int block_index,
char * buffer_address) {
262 if (spi_engine_cog == 0) {
266 if ((
int) buffer_address & 0x3) {
269 spi_block_index = block_index;
270 spi_buffer_address = buffer_address;
272 while (spi_command ==
'w') {
276 if (spi_command < 0) {
293 if (spi_engine_cog) {
295 while (spi_command ==
'z') {
306 if (spi_engine_cog) {
307 cogstop(spi_engine_cog - 1);
346 volatile int spi_command;
347 volatile int spi_block_index;
348 volatile char * spi_buffer_address;
354 void SetErrorCode(
const int abort_code) {
375 int SendCommandSlow(
int command,
int value,
int crc) {
377 if (command & 0x80) {
380 int ReplyA = SendCommandSlow(Cmd55, 0, 0x65);
393 SendSlow(command, 8);
396 if (command == Cmd12) {
407 }
while ((ReplyB & 0x80) && (Time_stamp--));
411 void SendSlow(
int value,
const int bits_to_send) {
412 value = __builtin_propeller_rev(value, 32 - bits_to_send);
414 for (
int i = 0; i < bits_to_send; i++) {
421 value = ((unsigned) value) >> 1;
431 int ReadSlow32(
void) {
433 for (
int i = 0; i < 4; i++) {
451 for (
int i = 0; i < 8; i++) {
454 result += result + ((
INA & mask_do) ? 1 : 0);
456 if ((CNT - spi_block_index) > (CLKFREQ << 2)) {
466 int GetSeconds(
void) {
467 if (spi_engine_cog == 0) {
472 while (spi_command ==
't') {
475 return spi_block_index;
478 int GetMilliseconds(
void) {
479 if (spi_engine_cog == 0) {
484 while (spi_command ==
't') {
487 int milliseconds = (spi_block_index * 1000);
488 milliseconds = (milliseconds + (((int) spi_buffer_address * 1000) / CLKFREQ));
493 static const int Cmd0 = 0x40 + 0;
494 static const int Cmd1 = 0x40 + 1;
495 static const int Acmd41 = 0xC0 + 41;
496 static const int Cmd8 = 0x40 + 8;
497 static const int Cmd9 = 0x40 + 9;
498 static const int Cmd10 = 0x40 + 10;
499 static const int Cmd12 = 0x40 + 12;
500 static const int Cmd13 = 0x40 + 13;
501 static const int Acmd13 = 0xC0 + 13;
502 static const int Cmd16 = 0x40 + 16;
503 static const int Cmd17 = 0x40 + 17;
504 static const int Cmd18 = 0x40 + 18;
505 static const int Cmd23 = 0x40 + 23;
506 static const int Acmd23 = 0xC0 + 23;
507 static const int Cmd24 = 0x40 + 24;
508 static const int Cmd25 = 0x40 + 25;
509 static const int Cmd55 = 0x40 + 55;
510 static const int Cmd58 = 0x40 + 58;
511 static const int Cmd59 = 0x40 + 59;
513 static volatile uint8_t * dat() {
514 static volatile uint8_t data[] = {
515 0x2f, 0xf1, 0xbf, 0xa0, 0x31, 0xf3, 0xbf, 0xa0, 0x2b, 0xed, 0xbf, 0xa0, 0x01, 0x80, 0xfe, 0xa4,
516 0xf0, 0x81, 0x3e, 0x08, 0xf1, 0x8b, 0xbe, 0xa0, 0xa4, 0x66, 0xfd, 0x5c, 0xf0, 0x81, 0xbe, 0x08,
517 0x00, 0x80, 0x7e, 0xc3, 0x06, 0x00, 0x78, 0x5c, 0x72, 0x80, 0x7e, 0x86, 0x1d, 0x00, 0x68, 0x5c,
518 0x77, 0x80, 0x7e, 0x86, 0x2d, 0x00, 0x68, 0x5c, 0x7a, 0x80, 0x7e, 0x86, 0x16, 0x00, 0x68, 0x5c,
519 0x74, 0x80, 0x7e, 0x86, 0x2e, 0x6f, 0x2a, 0x08, 0x2d, 0x71, 0x2a, 0x08, 0x00, 0x80, 0xfe, 0xa0,
520 0xf0, 0x81, 0x3e, 0x08, 0x06, 0x00, 0x7c, 0x5c, 0x7a, 0x82, 0xfe, 0xa0, 0x01, 0x76, 0xfe, 0xa4,
521 0x01, 0x84, 0xfe, 0xa4, 0x35, 0x96, 0xfc, 0x5c, 0x41, 0x81, 0xbe, 0xa0, 0xf0, 0x81, 0x3e, 0x08,
522 0x06, 0x00, 0x7c, 0x5c, 0x2e, 0x85, 0xbe, 0x08, 0x42, 0x7f, 0xbe, 0xa0, 0x01, 0x7e, 0xfe, 0x80,
523 0x3b, 0x7f, 0x3e, 0x86, 0x72, 0x78, 0x6a, 0x86, 0x25, 0x00, 0x68, 0x5c, 0x72, 0x82, 0xfe, 0xa0,
524 0x35, 0x96, 0xfc, 0x5c, 0x10, 0x78, 0xfd, 0x58, 0xb4, 0x8a, 0xfd, 0x5c, 0x41, 0x81, 0xbe, 0xa0,
525 0xf0, 0x81, 0x3e, 0x08, 0x72, 0x82, 0xfe, 0xa0, 0x01, 0x84, 0xfe, 0x80, 0x35, 0x96, 0xfc, 0x5c,
526 0x06, 0x00, 0x7c, 0x5c, 0x2e, 0x85, 0xbe, 0x08, 0x11, 0x78, 0xfd, 0x58, 0xb4, 0x8a, 0xfd, 0x5c,
527 0x41, 0x81, 0xbe, 0xa0, 0xf0, 0x81, 0x3e, 0x08, 0x77, 0x82, 0xfe, 0xa0, 0x35, 0x96, 0xfc, 0x5c,
528 0x06, 0x00, 0x7c, 0x5c, 0x42, 0x77, 0x3e, 0x86, 0x3c, 0x83, 0x2a, 0x86, 0x42, 0x00, 0x68, 0x5c,
529 0x77, 0x78, 0x7e, 0x86, 0x5a, 0xc4, 0xe8, 0x5c, 0x72, 0x78, 0x7e, 0x86, 0x53, 0xac, 0xe8, 0x5c,
530 0x77, 0x82, 0x7e, 0x86, 0x57, 0xb2, 0xe8, 0x5c, 0x72, 0x82, 0x7e, 0x86, 0x50, 0xa4, 0xe8, 0x5c,
531 0x7a, 0x82, 0x7e, 0x86, 0x4c, 0x9e, 0xe8, 0x5c, 0x42, 0x77, 0xbe, 0xa0, 0x01, 0x76, 0xfe, 0x80,
532 0x41, 0x79, 0xbe, 0xa0, 0x77, 0x82, 0x7e, 0x86, 0xf0, 0x48, 0xea, 0x5c, 0x72, 0x82, 0x7e, 0x86,
533 0xc6, 0xde, 0xe9, 0x5c, 0x7a, 0x82, 0x7e, 0x86, 0x00, 0x82, 0xea, 0xa0, 0x00, 0x00, 0x7c, 0x5c,
534 0x2a, 0xe9, 0xbf, 0x68, 0x8d, 0x46, 0xfd, 0x5c, 0x8d, 0x46, 0xfd, 0x5c, 0x00, 0x00, 0x7c, 0x5c,
535 0xa4, 0x86, 0xfe, 0x58, 0x63, 0xf6, 0xfc, 0x5c, 0x00, 0x00, 0x7c, 0x5c, 0x98, 0x86, 0xfe, 0x58,
536 0x63, 0xf6, 0xfc, 0x5c, 0x7c, 0x00, 0xfd, 0x5c, 0x00, 0x00, 0x7c, 0x5c, 0xb2, 0x86, 0xfe, 0x58,
537 0x63, 0xf6, 0xfc, 0x5c, 0x00, 0x00, 0x7c, 0x5c, 0x7c, 0x00, 0xfd, 0x5c, 0x10, 0x7e, 0xfe, 0xa0,
538 0x8d, 0x46, 0xfd, 0x5c, 0x5c, 0x7e, 0xfe, 0xe4, 0xfa, 0xf9, 0xff, 0x58, 0x81, 0x18, 0xfd, 0x5c,
539 0x8d, 0x46, 0xfd, 0x5c, 0x7c, 0x00, 0xfd, 0x5c, 0x00, 0x00, 0x7c, 0x5c, 0x2b, 0xed, 0xbf, 0xa0,
540 0x2a, 0xe9, 0xbf, 0x68, 0x2a, 0xe9, 0xbf, 0x64, 0x8d, 0x46, 0xfd, 0x5c, 0x43, 0xf9, 0xbf, 0xa0,
541 0x81, 0x18, 0xfd, 0x5c, 0x42, 0xf9, 0xbf, 0xa0, 0x2c, 0xf9, 0xbf, 0x2c, 0x81, 0x18, 0xfd, 0x5c,
542 0x01, 0xf8, 0xff, 0x24, 0x81, 0x18, 0xfd, 0x5c, 0x01, 0xf8, 0xff, 0x24, 0x81, 0x18, 0xfd, 0x5c,
543 0x01, 0xf8, 0xff, 0x24, 0x81, 0x18, 0xfd, 0x5c, 0x8d, 0x46, 0xfd, 0x5c, 0x18, 0x86, 0xfe, 0x28,
544 0x4c, 0x86, 0x7e, 0x86, 0x8d, 0x46, 0xe9, 0x5c, 0x09, 0x7e, 0xfe, 0xa0, 0x8d, 0x46, 0xfd, 0x5c,
545 0x80, 0x7c, 0x7e, 0x63, 0x77, 0x7e, 0xf2, 0xe4, 0x3e, 0x83, 0x96, 0xa4, 0x00, 0x00, 0x7c, 0x5c,
546 0x30, 0x7f, 0xbe, 0xa0, 0x8d, 0x46, 0xfd, 0x5c, 0xff, 0x7c, 0x7e, 0x86, 0x7d, 0x7e, 0xd6, 0xe4,
547 0x00, 0x00, 0x7c, 0x5c, 0x29, 0xe9, 0xbf, 0x64, 0x00, 0xfa, 0xff, 0xa0, 0x80, 0xf6, 0xff, 0x58,
548 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
549 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x00, 0xf6, 0xff, 0xa0,
550 0x00, 0x00, 0x7c, 0x5c, 0x01, 0xf8, 0xff, 0xa4, 0x00, 0x7c, 0xfe, 0xa0, 0xc0, 0xfa, 0xff, 0x58,
551 0x40, 0xf6, 0xff, 0x58, 0xf2, 0x51, 0x3e, 0x61, 0x01, 0x7c, 0xfe, 0x34, 0xf2, 0x51, 0x3e, 0x61,
552 0x01, 0x7c, 0xfe, 0x34, 0xf2, 0x51, 0x3e, 0x61, 0x01, 0x7c, 0xfe, 0x34, 0xf2, 0x51, 0x3e, 0x61,
553 0x01, 0x7c, 0xfe, 0x34, 0xf2, 0x51, 0x3e, 0x61, 0x01, 0x7c, 0xfe, 0x34, 0xf2, 0x51, 0x3e, 0x61,
554 0x01, 0x7c, 0xfe, 0x34, 0xf2, 0x51, 0x3e, 0x61, 0x01, 0x7c, 0xfe, 0x34, 0xf2, 0x51, 0x3e, 0x61,
555 0x00, 0xf6, 0xff, 0xa0, 0x01, 0x7c, 0xfe, 0x34, 0x00, 0xf8, 0xff, 0xa0, 0x00, 0x00, 0x7c, 0x5c,
556 0xf1, 0x7f, 0xbe, 0xa0, 0x3f, 0x73, 0xbe, 0x80, 0x45, 0x73, 0xbe, 0x84, 0x3f, 0x71, 0xbe, 0x80,
557 0x45, 0x71, 0xbe, 0x84, 0x3f, 0x8b, 0xbe, 0xa0, 0x00, 0x7e, 0xfe, 0x08, 0x3f, 0x71, 0xbe, 0xe1,
558 0x00, 0x6e, 0xfe, 0xc8, 0x3a, 0x73, 0x3e, 0x87, 0xb3, 0x00, 0x70, 0x5c, 0x7a, 0x82, 0xfe, 0xa0,
559 0x01, 0x76, 0xfe, 0xa4, 0x01, 0x84, 0xfe, 0xa4, 0x35, 0x96, 0xfc, 0x5c, 0x00, 0x00, 0x7c, 0x5c,
560 0x32, 0xf3, 0xbf, 0xa0, 0x01, 0xf6, 0xff, 0xa0, 0x2d, 0x89, 0xbe, 0x08, 0x04, 0x7a, 0xfe, 0xa0,
561 0x46, 0x79, 0xfd, 0x54, 0x3f, 0x7f, 0xbe, 0x08, 0x20, 0x7e, 0xfe, 0xa0, 0x44, 0xfb, 0xbf, 0xa0,
562 0xfd, 0x01, 0xbc, 0x08, 0x35, 0x79, 0xbd, 0x80, 0xbc, 0x7e, 0xfe, 0xe4, 0x36, 0x79, 0xbd, 0x84,
563 0x04, 0x88, 0xfe, 0x80, 0xb9, 0x7a, 0xfe, 0xe4, 0x00, 0xf6, 0xff, 0xa0, 0x00, 0xfa, 0xff, 0xa0,
564 0x31, 0xf3, 0xbf, 0xa0, 0x00, 0x00, 0x7c, 0x5c, 0x46, 0xcd, 0xfd, 0x54, 0x80, 0x7a, 0xfe, 0xa0,
565 0x30, 0x7f, 0xbe, 0xa0, 0x8d, 0x46, 0xfd, 0x5c, 0xfe, 0x7c, 0x7e, 0x86, 0xc9, 0x7e, 0xd6, 0xe4,
566 0x64, 0x82, 0xd6, 0xa4, 0xef, 0x00, 0x54, 0x5c, 0x01, 0xf8, 0xff, 0xa4, 0x80, 0x7a, 0xfe, 0xa0,
567 0x04, 0x7e, 0xfe, 0xa0, 0xc0, 0xfa, 0xff, 0x58, 0x40, 0xf6, 0xff, 0x58, 0xf2, 0x51, 0x3e, 0x61,
568 0x08, 0x7c, 0xfe, 0x34, 0xf2, 0x51, 0x3e, 0x61, 0x02, 0x7c, 0xfe, 0x70, 0xf2, 0x51, 0x3e, 0x61,
569 0x04, 0x7c, 0xfe, 0x70, 0xf2, 0x51, 0x3e, 0x61, 0x08, 0x7c, 0xfe, 0x70, 0xf2, 0x51, 0x3e, 0x61,
570 0x10, 0x7c, 0xfe, 0x70, 0xf2, 0x51, 0x3e, 0x61, 0x20, 0x7c, 0xfe, 0x70, 0xf2, 0x51, 0x3e, 0x61,
571 0x40, 0x7c, 0xfe, 0x70, 0xf2, 0x51, 0x3e, 0x61, 0x00, 0xf6, 0xff, 0xa0, 0x80, 0x7c, 0xfe, 0x70,
572 0xd2, 0x7e, 0xfe, 0xe4, 0x00, 0x7c, 0xfe, 0x3c, 0x3e, 0x01, 0xbc, 0xa0, 0x33, 0xcd, 0xbd, 0x80,
573 0xd0, 0x7a, 0xfe, 0xe4, 0x00, 0xf8, 0xff, 0xa0, 0x8d, 0x46, 0xfd, 0x5c, 0x8d, 0x46, 0xfd, 0x5c,
574 0x8d, 0x46, 0xfd, 0x5c, 0x00, 0x72, 0xfe, 0xa0, 0x00, 0x82, 0xfe, 0xa0, 0x00, 0x00, 0x7c, 0x5c,
575 0x46, 0xed, 0xfd, 0x50, 0x80, 0x7a, 0xfe, 0xa0, 0x7c, 0x00, 0xfd, 0x5c, 0xf8, 0xf9, 0xff, 0x58,
576 0x81, 0x18, 0xfd, 0x5c, 0x00, 0xfa, 0xff, 0xa0, 0x46, 0xf9, 0xbf, 0xa0, 0x01, 0xec, 0xfd, 0x80,
577 0x18, 0xf8, 0xff, 0x24, 0x80, 0xf6, 0xff, 0x58, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
578 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
579 0x01, 0xf8, 0xff, 0x24, 0x11, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
580 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
581 0x01, 0xf8, 0xff, 0x24, 0x11, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
582 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
583 0x01, 0xf8, 0xff, 0x24, 0x11, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
584 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24, 0x01, 0xf8, 0xff, 0x24,
585 0x01, 0xf8, 0xff, 0x24, 0x00, 0xf6, 0xff, 0xa0, 0xf6, 0x7a, 0xfe, 0xe4, 0x8d, 0x46, 0xfd, 0x5c,
586 0x8d, 0x46, 0xfd, 0x5c, 0x8d, 0x46, 0xfd, 0x5c, 0x1f, 0x7c, 0xfe, 0x60, 0x05, 0x7c, 0x7e, 0x86,
587 0x00, 0x82, 0xea, 0xa0, 0x65, 0x82, 0xd6, 0xa4, 0x8d, 0x46, 0xfd, 0x5c, 0x00, 0x72, 0xfe, 0xa0,
588 0x00, 0x00, 0x7c, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x40, 0x42, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x02, 0x00, 0x00,
592 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
594 0x00, 0x00, 0x00, 0x00,
601 #endif // LIBPROPELLER_SDSAFESPI_H_