PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Committer:
spinal
Date:
Sun Nov 18 15:47:54 2018 +0000
Revision:
64:6e6c6c2b664e
Parent:
52:c04087025cab
added fix for directrectangle()

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pokitto 52:c04087025cab 1 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 2 /* PFF - Low level disk control module for ATtiny85 (C)ChaN, 2009 */
Pokitto 52:c04087025cab 3 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 4
Pokitto 52:c04087025cab 5
Pokitto 52:c04087025cab 6
Pokitto 52:c04087025cab 7 #include "diskio.h"
Pokitto 52:c04087025cab 8 #include "mbed.h"
Pokitto 52:c04087025cab 9 #include "connect.h"
Pokitto 52:c04087025cab 10 #include "PokittoDisk.h"
Pokitto 52:c04087025cab 11
Pokitto 52:c04087025cab 12 namespace PFFS {
Pokitto 52:c04087025cab 13
Pokitto 52:c04087025cab 14 #define _WRITE_FUNC 1
Pokitto 52:c04087025cab 15
Pokitto 52:c04087025cab 16 /* Definitions for MMC/SDC command */
Pokitto 52:c04087025cab 17 #define CMD0 (0x40+0) /* GO_IDLE_STATE */
Pokitto 52:c04087025cab 18 #define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
Pokitto 52:c04087025cab 19 #define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
Pokitto 52:c04087025cab 20 #define CMD8 (0x40+8) /* SEND_IF_COND */
Pokitto 52:c04087025cab 21 #define CMD16 (0x40+16) /* SET_BLOCKLEN */
Pokitto 52:c04087025cab 22 #define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
Pokitto 52:c04087025cab 23 #define CMD24 (0x40+24) /* WRITE_BLOCK */
Pokitto 52:c04087025cab 24 #define CMD55 (0x40+55) /* APP_CMD */
Pokitto 52:c04087025cab 25 #define CMD58 (0x40+58) /* READ_OCR */
Pokitto 52:c04087025cab 26
Pokitto 52:c04087025cab 27
Pokitto 52:c04087025cab 28
Pokitto 52:c04087025cab 29 /* Port Controls (Platform dependent) */
Pokitto 52:c04087025cab 30 #define SELECT() CLR_SD_CS //mmccs.write(0) /* MMC CS = L */
Pokitto 52:c04087025cab 31 #define DESELECT() SET_SD_CS // mmccs.write(1) /* MMC CS = H */
Pokitto 52:c04087025cab 32 #define MMC_SEL !GET_SD_CS // !mmccs.read() /* MMC CS status (true:selected) */
Pokitto 52:c04087025cab 33
Pokitto 52:c04087025cab 34 void xmit_spi (BYTE c) {
Pokitto 52:c04087025cab 35 device.write(c); /* Send a byte */
Pokitto 52:c04087025cab 36 }
Pokitto 52:c04087025cab 37
Pokitto 52:c04087025cab 38 BYTE rcv_spi (void) {
Pokitto 52:c04087025cab 39 return device.write(0xff);
Pokitto 52:c04087025cab 40 }
Pokitto 52:c04087025cab 41
Pokitto 52:c04087025cab 42 /*--------------------------------------------------------------------------
Pokitto 52:c04087025cab 43
Pokitto 52:c04087025cab 44 Module Private Functions
Pokitto 52:c04087025cab 45
Pokitto 52:c04087025cab 46 ---------------------------------------------------------------------------*/
Pokitto 52:c04087025cab 47
Pokitto 52:c04087025cab 48 static
Pokitto 52:c04087025cab 49 BYTE CardType;
Pokitto 52:c04087025cab 50
Pokitto 52:c04087025cab 51
Pokitto 52:c04087025cab 52 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 53 /* Deselect the card and release SPI bus */
Pokitto 52:c04087025cab 54 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 55
Pokitto 52:c04087025cab 56 static
Pokitto 52:c04087025cab 57 void release_spi (void) {
Pokitto 52:c04087025cab 58 DESELECT();
Pokitto 52:c04087025cab 59 rcv_spi();
Pokitto 52:c04087025cab 60 }
Pokitto 52:c04087025cab 61
Pokitto 52:c04087025cab 62
Pokitto 52:c04087025cab 63 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 64 /* Send a command packet to MMC */
Pokitto 52:c04087025cab 65 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 66
Pokitto 52:c04087025cab 67 static
Pokitto 52:c04087025cab 68 BYTE send_cmd (
Pokitto 52:c04087025cab 69 BYTE cmd, /* Command byte */
Pokitto 52:c04087025cab 70 DWORD arg /* Argument */
Pokitto 52:c04087025cab 71 ) {
Pokitto 52:c04087025cab 72 BYTE n, res;
Pokitto 52:c04087025cab 73
Pokitto 52:c04087025cab 74
Pokitto 52:c04087025cab 75 if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
Pokitto 52:c04087025cab 76 cmd &= 0x7F;
Pokitto 52:c04087025cab 77 res = send_cmd(CMD55, 0);
Pokitto 52:c04087025cab 78 if (res > 1) return res;
Pokitto 52:c04087025cab 79 }
Pokitto 52:c04087025cab 80
Pokitto 52:c04087025cab 81 /* Select the card */
Pokitto 52:c04087025cab 82 DESELECT();
Pokitto 52:c04087025cab 83 rcv_spi();
Pokitto 52:c04087025cab 84 SELECT();
Pokitto 52:c04087025cab 85 rcv_spi();
Pokitto 52:c04087025cab 86
Pokitto 52:c04087025cab 87 /* Send a command packet */
Pokitto 52:c04087025cab 88 xmit_spi(cmd); /* Start + Command index */
Pokitto 52:c04087025cab 89 xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
Pokitto 52:c04087025cab 90 xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
Pokitto 52:c04087025cab 91 xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
Pokitto 52:c04087025cab 92 xmit_spi((BYTE)arg); /* Argument[7..0] */
Pokitto 52:c04087025cab 93 n = 0x01; /* Dummy CRC + Stop */
Pokitto 52:c04087025cab 94 if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
Pokitto 52:c04087025cab 95 if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
Pokitto 52:c04087025cab 96 xmit_spi(n);
Pokitto 52:c04087025cab 97
Pokitto 52:c04087025cab 98 /* Receive a command response */
Pokitto 52:c04087025cab 99 n = 10; /* Wait for a valid response in timeout of 10 attempts */
Pokitto 52:c04087025cab 100 do {
Pokitto 52:c04087025cab 101 res = rcv_spi();
Pokitto 52:c04087025cab 102 } while ((res & 0x80) && --n);
Pokitto 52:c04087025cab 103
Pokitto 52:c04087025cab 104 return res; /* Return with the response value */
Pokitto 52:c04087025cab 105 }
Pokitto 52:c04087025cab 106
Pokitto 52:c04087025cab 107
Pokitto 52:c04087025cab 108
Pokitto 52:c04087025cab 109 /*--------------------------------------------------------------------------
Pokitto 52:c04087025cab 110
Pokitto 52:c04087025cab 111 Public Functions
Pokitto 52:c04087025cab 112
Pokitto 52:c04087025cab 113 ---------------------------------------------------------------------------*/
Pokitto 52:c04087025cab 114
Pokitto 52:c04087025cab 115
Pokitto 52:c04087025cab 116 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 117 /* Initialize Disk Drive */
Pokitto 52:c04087025cab 118 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 119
Pokitto 52:c04087025cab 120 //__attribute__((section(".SD_Code")))
Pokitto 52:c04087025cab 121 DSTATUS disk_initialize (void) {
Pokitto 52:c04087025cab 122 BYTE n, cmd, ty, ocr[4];
Pokitto 52:c04087025cab 123 WORD tmr;
Pokitto 52:c04087025cab 124
Pokitto 52:c04087025cab 125 DESELECT();
Pokitto 52:c04087025cab 126 device.frequency(SPI_FREQ);
Pokitto 52:c04087025cab 127 device.format(8);
Pokitto 52:c04087025cab 128 // device.frequency(SPI_FREQ); // hangs if this is after format
Pokitto 52:c04087025cab 129
Pokitto 52:c04087025cab 130 #if _WRITE_FUNC
Pokitto 52:c04087025cab 131 if (MMC_SEL) disk_writep(0, 0); /* Finalize write process if it is in progress */
Pokitto 52:c04087025cab 132 #endif
Pokitto 52:c04087025cab 133 for (n = 100; n; n--) rcv_spi(); /* Dummy clocks */
Pokitto 52:c04087025cab 134
Pokitto 52:c04087025cab 135 ty = 0;
Pokitto 52:c04087025cab 136 if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
Pokitto 52:c04087025cab 137 if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */
Pokitto 52:c04087025cab 138 for (n = 0; n < 4; n++) ocr[n] = rcv_spi(); /* Get trailing return value of R7 resp */
Pokitto 52:c04087025cab 139 if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
Pokitto 52:c04087025cab 140 for (tmr = 12000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) ; /* Wait for leaving idle state (ACMD41 with HCS bit) */
Pokitto 52:c04087025cab 141 if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
Pokitto 52:c04087025cab 142 for (n = 0; n < 4; n++) ocr[n] = rcv_spi();
Pokitto 52:c04087025cab 143 ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */
Pokitto 52:c04087025cab 144 }
Pokitto 52:c04087025cab 145 }
Pokitto 52:c04087025cab 146 } else { /* SDv1 or MMCv3 */
Pokitto 52:c04087025cab 147 if (send_cmd(ACMD41, 0) <= 1) {
Pokitto 52:c04087025cab 148 ty = CT_SD1;
Pokitto 52:c04087025cab 149 cmd = ACMD41; /* SDv1 */
Pokitto 52:c04087025cab 150 } else {
Pokitto 52:c04087025cab 151 ty = CT_MMC;
Pokitto 52:c04087025cab 152 cmd = CMD1; /* MMCv3 */
Pokitto 52:c04087025cab 153 }
Pokitto 52:c04087025cab 154 for (tmr = 25000; tmr && send_cmd(cmd, 0); tmr--) ; /* Wait for leaving idle state */
Pokitto 52:c04087025cab 155 if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
Pokitto 52:c04087025cab 156 ty = 0;
Pokitto 52:c04087025cab 157 }
Pokitto 52:c04087025cab 158 }
Pokitto 52:c04087025cab 159 CardType = ty;
Pokitto 52:c04087025cab 160 release_spi();
Pokitto 52:c04087025cab 161
Pokitto 52:c04087025cab 162 return ty ? 0 : STA_NOINIT;
Pokitto 52:c04087025cab 163 }
Pokitto 52:c04087025cab 164
Pokitto 52:c04087025cab 165
Pokitto 52:c04087025cab 166
Pokitto 52:c04087025cab 167 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 168 /* Read partial sector */
Pokitto 52:c04087025cab 169 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 170
Pokitto 52:c04087025cab 171 DRESULT disk_readp (
Pokitto 52:c04087025cab 172 BYTE *buff, /* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */
Pokitto 52:c04087025cab 173 DWORD lba, /* Sector number (LBA) */
Pokitto 52:c04087025cab 174 WORD ofs, /* Byte offset to read from (0..511) */
Pokitto 52:c04087025cab 175 WORD cnt /* Number of bytes to read (ofs + cnt mus be <= 512) */
Pokitto 52:c04087025cab 176 ) {
Pokitto 52:c04087025cab 177 DRESULT res;
Pokitto 52:c04087025cab 178 BYTE rc;
Pokitto 52:c04087025cab 179 WORD bc;
Pokitto 52:c04087025cab 180
Pokitto 52:c04087025cab 181
Pokitto 52:c04087025cab 182 if (!(CardType & CT_BLOCK)) lba *= 512; /* Convert to byte address if needed */
Pokitto 52:c04087025cab 183
Pokitto 52:c04087025cab 184 res = RES_ERROR;
Pokitto 52:c04087025cab 185 if (send_cmd(CMD17, lba) == 0) { /* READ_SINGLE_BLOCK */
Pokitto 52:c04087025cab 186
Pokitto 52:c04087025cab 187 bc = 30000;
Pokitto 52:c04087025cab 188 do { /* Wait for data packet in timeout of 100ms */
Pokitto 52:c04087025cab 189 rc = rcv_spi();
Pokitto 52:c04087025cab 190 } while (rc == 0xFF && --bc);
Pokitto 52:c04087025cab 191
Pokitto 52:c04087025cab 192 if (rc == 0xFE) { /* A data packet arrived */
Pokitto 52:c04087025cab 193 bc = 514 - ofs - cnt;
Pokitto 52:c04087025cab 194
Pokitto 52:c04087025cab 195 /* Skip leading bytes */
Pokitto 52:c04087025cab 196 if (ofs) {
Pokitto 52:c04087025cab 197 do {
Pokitto 52:c04087025cab 198 rcv_spi();
Pokitto 52:c04087025cab 199 } while (--ofs);
Pokitto 52:c04087025cab 200 }
Pokitto 52:c04087025cab 201
Pokitto 52:c04087025cab 202 /* Receive a part of the sector */
Pokitto 52:c04087025cab 203 if (buff) { /* Store data to the memory */
Pokitto 52:c04087025cab 204 do {
Pokitto 52:c04087025cab 205 *buff++ = rcv_spi();
Pokitto 52:c04087025cab 206 } while (--cnt);
Pokitto 52:c04087025cab 207 } else { /* Forward data to the outgoing stream (depends on the project) */
Pokitto 52:c04087025cab 208 do {
Pokitto 52:c04087025cab 209 rcv_spi();
Pokitto 52:c04087025cab 210 } while (--cnt);
Pokitto 52:c04087025cab 211 }
Pokitto 52:c04087025cab 212
Pokitto 52:c04087025cab 213 /* Skip trailing bytes and CRC */
Pokitto 52:c04087025cab 214 do rcv_spi();
Pokitto 52:c04087025cab 215 while (--bc);
Pokitto 52:c04087025cab 216
Pokitto 52:c04087025cab 217 res = RES_OK;
Pokitto 52:c04087025cab 218 }
Pokitto 52:c04087025cab 219 }
Pokitto 52:c04087025cab 220
Pokitto 52:c04087025cab 221 release_spi();
Pokitto 52:c04087025cab 222
Pokitto 52:c04087025cab 223 return res;
Pokitto 52:c04087025cab 224 }
Pokitto 52:c04087025cab 225
Pokitto 52:c04087025cab 226
Pokitto 52:c04087025cab 227
Pokitto 52:c04087025cab 228 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 229 /* Write partial sector */
Pokitto 52:c04087025cab 230 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 231 #if _WRITE_FUNC
Pokitto 52:c04087025cab 232
Pokitto 52:c04087025cab 233 DRESULT disk_writep (
Pokitto 52:c04087025cab 234 const BYTE *buff, /* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */
Pokitto 52:c04087025cab 235 DWORD sa /* Number of bytes to send, Sector number (LBA) or zero */
Pokitto 52:c04087025cab 236 ) {
Pokitto 52:c04087025cab 237 DRESULT res;
Pokitto 52:c04087025cab 238 WORD bc;
Pokitto 52:c04087025cab 239 static WORD wc;
Pokitto 52:c04087025cab 240
Pokitto 52:c04087025cab 241
Pokitto 52:c04087025cab 242 res = RES_ERROR;
Pokitto 52:c04087025cab 243
Pokitto 52:c04087025cab 244 if (buff) { /* Send data bytes */
Pokitto 52:c04087025cab 245 bc = (WORD)sa;
Pokitto 52:c04087025cab 246 while (bc && wc) { /* Send data bytes to the card */
Pokitto 52:c04087025cab 247 xmit_spi(*buff++);
Pokitto 52:c04087025cab 248 wc--;
Pokitto 52:c04087025cab 249 bc--;
Pokitto 52:c04087025cab 250 }
Pokitto 52:c04087025cab 251 res = RES_OK;
Pokitto 52:c04087025cab 252 } else {
Pokitto 52:c04087025cab 253 if (sa) { /* Initiate sector write process */
Pokitto 52:c04087025cab 254 if (!(CardType & CT_BLOCK)) sa *= 512; /* Convert to byte address if needed */
Pokitto 52:c04087025cab 255 if (send_cmd(CMD24, sa) == 0) { /* WRITE_SINGLE_BLOCK */
Pokitto 52:c04087025cab 256 xmit_spi(0xFF);
Pokitto 52:c04087025cab 257 xmit_spi(0xFE); /* Data block header */
Pokitto 52:c04087025cab 258 wc = 512; /* Set byte counter */
Pokitto 52:c04087025cab 259 res = RES_OK;
Pokitto 52:c04087025cab 260 }
Pokitto 52:c04087025cab 261 } else { /* Finalize sector write process */
Pokitto 52:c04087025cab 262 bc = wc + 2;
Pokitto 52:c04087025cab 263 while (bc--) xmit_spi(0); /* Fill left bytes and CRC with zeros */
Pokitto 52:c04087025cab 264 if ((rcv_spi() & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 300ms */
Pokitto 52:c04087025cab 265 for (bc = 65000; rcv_spi() != 0xFF && bc; bc--) ; /* Wait ready */
Pokitto 52:c04087025cab 266 if (bc) res = RES_OK;
Pokitto 52:c04087025cab 267 }
Pokitto 52:c04087025cab 268 release_spi();
Pokitto 52:c04087025cab 269 }
Pokitto 52:c04087025cab 270 }
Pokitto 52:c04087025cab 271
Pokitto 52:c04087025cab 272 return res;
Pokitto 52:c04087025cab 273 }
Pokitto 52:c04087025cab 274 #endif
Pokitto 52:c04087025cab 275
Pokitto 52:c04087025cab 276 } // namespace PFFS
Pokitto 52:c04087025cab 277
Pokitto 52:c04087025cab 278