abse/gameboy-advance

A tscircuit package created by abse.

Version
0.0.45
License
unset
Stars
0

firmware/game-console/sd-fatfs/sd_driver/sd_regs.h

#pragma once

#include <stdint.h>
#include "util.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
+-----------------------+-------+-------+-----------+
| Name                  | Field | Width | CID-slice |
+-----------------------+-------+-------+-----------+
| Manufacturer ID       | MID   | 8     | [127:120] |
| OEM/Application ID    | OID   | 16    | [119:104] |
| Product name          | PNM   | 40    | [103:64]  |
| Product revision      | PRV   | 8     | [63:56]   |
| Product serial number | PSN   | 32    | [55:24]   |
| reserved              | --    | 4     | [23:20]   |
| Manufacturing date    | MDT   | 12    | [19:8]    |
| CRC7 checksum         | CRC   | 7     | [7:1]     |
| not used, always 1-   | 1     | [0:0] |           |
+-----------------------+-------+-------+-----------+
*/
// Table 5-2: The CID Fields
typedef uint8_t CID_t[16];

/*
+---------------+-----------------------+-------------------------------------+
| CSD_STRUCTURE | CSD structure version | Card Capacity                       |
+---------------+-----------------------+-------------------------------------+
| 0             | CSD Version 1.0       | Standard Capacity                   |
| 1             | CSD Version 2.0       | High Capacity and Extended Capacity |
| 2-3           | reserved              |                                     |
+---------------+-----------------------+-------------------------------------+
*/
// Table 5-3: CSD Register Structure

/*
+--------------------------------------------------+--------------------+-------+---------------+-----------+-----------+
| Name                                             | Field              | Width | Value         | Cell Type | CSD-slice |
+--------------------------------------------------+--------------------+-------+---------------+-----------+-----------+
| CSD structure                                    | CSD_STRUCTURE      | 2     | 00b           | R         | [127:126] |
| reserved                                         | -                  | 6     | 00 0000b      | R         | [125:120] |
| data read access-time-1                          | TAAC               | 8     | xxh           | R         | [119:112] |
| data read access-time-2 in CLK cycles (NSAC*100) | NSAC               | 8     | xxh           | R         | [111:104] |
| max. data transfer rate                          | TRAN_SPEED         | 8     | 32h or 5Ah    | R         | [103:96]  |
| card command classes                             | CCC                | 12    | 01x110110101b | R         | [95:84]   |
| max. read data block length                      | READ_BL_LEN        | 4     | xh            | R         | [83:80]   |
| partial blocks for read allowed                  | READ_BL_PARTIAL    | 1     | 1b            | R         | [79:79]   |
| write block misalignment                         | WRITE_BLK_MISALIGN | 1     | xb            | R         | [78:78]   |
| read block misalignment                          | READ_BLK_MISALIGN  | 1     | xb            | R         | [77:77]   |
| DSR implemented                                  | DSR_IMP            | 1     | xb            | R         | [76:76]   |
| reserved                                         | -                  | 2     | 00b           | R         | [75:74]   |
| device size                                      | C_SIZE             | 12    | xxxh          | R         | [73:62]   |
| max. read current @VDD min                       | VDD_R_CURR_MIN     | 3     | xxxb          | R         | [61:59]   |
| max. read current @VDD max                       | VDD_R_CURR_MAX     | 3     | xxxb          | R         | [58:56]   |
| max. write current @VDD min                      | VDD_W_CURR_MIN     | 3     | xxxb          | R         | [55:53]   |
| max. write current @VDD max                      | VDD_W_CURR_MAX     | 3     | xxxb          | R         | [52:50]   |
| device size multiplier                           | C_SIZE_MULT        | 3     | xxxb          | R         | [49:47]   |
| erase single block enable                        | ERASE_BLK_EN       | 1     | xb            | R         | [46:46]   |
| erase sector size                                | SECTOR_SIZE        | 7     | xxxxxxxb      | R         | [45:39]   |
| write protect group size                         | WP_GRP_SIZE        | 7     | xxxxxxxb      | R         | [38:32]   |
| write protect group enable                       | WP_GRP_ENABLE      | 1     | xb            | R         | [31:31]   |
| reserved                                         | (Do not use)       | 2     | 00b           | R         | [30:29]   |
| write speed factor                               | R2W_FACTOR         | 3     | xxxb          | R         | [28:26]   |
| max. write data block length                     | WRITE_BL_LEN       | 4     | xxxxb         | R         | [25:22]   |
| partial blocks for write allowed                 | WRITE_BL_PARTIAL   | 1     | xb            | R         | [21:21]   |
| reserved                                         | -                  | 5     | 00000b        | R         | [20:16]   |
| File format group                                | FILE_FORMAT_GRP    | 1     | xb            | R/W(1)    | [15:15]   |
| copy flag                                        | COPY               | 1     | xb            | R/W(1)    | [14:14]   |
| permanent write protection                       | PERM_WRITE_PROTECT | 1     | xb            | R/W(1)    | [13:13]   |
| temporary write protection                       | TMP_WRITE_PROTECT  | 1     | xb            | R/W       | [12:12]   |
| File format                                      | FILE_FORMAT        | 2     | xxb           | R/W(1)    | [11:10]   |
| reserved                                         |                    | 2     | 00b           | R/W       | [9:8]     |
| CRC                                              | CRC                | 7     | xxxxxxxb      | R/W       | [7:1]     |
| not used, always'1'                              | -                  | 1     | 1b            | -         | [0:0]     |
+--------------------------------------------------+--------------------+-------+---------------+-----------+-----------+
*/
// Table 5-4: The CSD Register Fields (CSD Version 1.0)

/*
+------------------------------------------------+----------------------+-------+----------------------+-----------+-----------+
| Name                                           | Field                | Width | Value                | Cell Type | CSD-slice |
+------------------------------------------------+----------------------+-------+----------------------+-----------+-----------+
| CSD structure                                  | CSD_STRUCTURE        | 2     | 01b                  | R         | [127:126] |
| reserved                                       | -                    | 6     | 00 0000b             | R         | [125:120] |
| data read access-time                          | (TAAC)               | 8     | 0Eh                  | R         | [119:112] |
| data read access-time in CLK cycles (NSAC*100) | (NSAC)               | 8     | 00h                  | R         | [111:104] |
| max. data transfer rate                        | (TRAN_SPEED)         | 8     | 32h, 5Ah, 0Bh or 2Bh | R         | [103:96]  |
| card command classes                           | CCC                  | 12    | 01x110110101b        | R         | [95:84]   |
| max. read data block length                    | (READ_BL_LEN)        | 4     | 9                    | R         | [83:80]   |
| partial blocks for read allowed                | (READ_BL_PARTIAL)    | 1     | 0                    | R         | [79:79]   |
| write block misalignment                       | (WRITE_BLK_MISALIGN) | 1     | 0                    | R         | [78:78]   |
| read block misalignment                        | (READ_BLK_MISALIGN)  | 1     | 0                    | R         | [77:77]   |
| DSR implemented                                | DSR_IMP              | 1     | x                    | R         | [76:76]   |
| reserved                                       | -                    | 6     | 00 0000b             | R         | [75:70]   |
| device size                                    | C_SIZE               | 22    | xxxxxxh              | R         | [69:48]   |
| reserved                                       | -                    | 1     | 0                    | R         | [47:47]   |
| erase single block enable                      | (ERASE_BLK_EN)       | 1     | 1                    | R         | [46:46]   |
| erase sector size                              | (SECTOR_SIZE)        | 7     | 7Fh                  | R         | [45:39]   |
| write protect group size                       | (WP_GRP_SIZE)        | 7     | 0000000b             | R         | [38:32]   |
| write protect group enable                     | (WP_GRP_ENABLE)      | 1     | 0                    | R         | [31:31]   |
| reserved                                       |                      | 2     | 00b                  | R         | [30:29]   |
| write speed factor                             | (R2W_FACTOR)         | 3     | 010b                 | R         | [28:26]   |
| max. write data block length                   | (WRITE_BL_LEN)       | 4     | 9                    | R         | [25:22]   |
| partial blocks for write allowed               | (WRITE_BL_PARTIAL)   | 1     | 0                    | R         | [21:21]   |
| reserved                                       | -                    | 5     | 00000b               | R         | [20:16]   |
| File format group                              | (FILE_FORMAT_GRP)    | 1     | 0                    | R         | [15:15]   |
| copy flag                                      | COPY                 | 1     | x                    | R/W(1)    | [14:14]   |
| permanent write protection                     | PERM_WRITE_PROTECT   | 1     | x                    | R/W(1)    | [13:13]   |
| temporary write protection                     | TMP_WRITE_PROTECT    | 1     | x                    | R/W       | [12:12]   |
| File format                                    | (FILE_FORMAT)        | 2     | 00b                  | R         | [11:10]   |
| reserved                                       | -                    | 2     | 00b                  | R         | [9:8]     |
| CRC                                            | CRC                  | 7     | xxxxxxxb             | R/W       | [7:1]     |
| not used, always'1'                            | -                    | 1     | 1                    | -         | [0:0]     |
+------------------------------------------------+----------------------+-------+----------------------+-----------+-----------+
*/
// Table 5-16: The CSD Register Fields (CSD Version 2.0)
typedef uint8_t CSD_t[16];

/* return Capacity in sectors */
static inline uint32_t CSD_sectors(CSD_t csd) /*  const  */ {
    uint32_t c_size;
    // +--------------------------------------------------+--------------------+-------+---------------+-----------+-----------+
    // | Name                                             | Field              | Width | Value         | Cell Type | CSD-slice |
    // +--------------------------------------------------+--------------------+-------+---------------+-----------+-----------+
    // | CSD structure                                    | CSD_STRUCTURE      | 2     | 00b           | R         | [127:126] |
    uint8_t ver = ext_bits16(csd, 127, 126);
    if (ver == 0) {
        // | device size                                      | C_SIZE             | 12    | xxxh          | R         | [73:62]   |
        c_size = ext_bits16(csd, 73, 62);
        // | device size multiplier                           | C_SIZE_MULT        | 3     | xxxb          | R         | [49:47]   |
        uint8_t c_size_mult = ext_bits16(csd, 49, 47);
        //  MULT = 2^(C_SIZE_MULT+2)
        uint32_t mult = 1UL << (c_size_mult + 2);
        //  BLOCKNR = (C_SIZE+1) * MULT
        // GBA: normalize native READ_BL_LEN blocks to 512-byte sectors.
        uint8_t read_bl_len = ext_bits16(csd, 83, 80);
        return (uint32_t)(((uint64_t)(c_size + 1) * mult << read_bl_len) / 512u);
    } else if (ver == 1) {
        // | device size                                    | C_SIZE               | 22    | xxxxxxh              | R         | [69:48]   |
        c_size = ext_bits16(csd, 69, 48);
        /* The user data area capacity is calculated from C_SIZE as follows:
        memory capacity = (C_SIZE+1) * 512K byte */
        return (c_size + 1) * 1024; // sectors
    } else {
        return 0;
    }
}

#ifdef __cplusplus
}
#endif