File indexing completed on 2025-05-11 08:23:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define RTEMS_STATUS_CHECKS_USE_PRINTK
0013
0014 #include <rtems.h>
0015 #include <rtems/libio.h>
0016 #include <rtems/blkdev.h>
0017 #include <rtems/status-checks.h>
0018 #include <errno.h>
0019 #include <bsp.h>
0020 #include "../include/system_conf.h"
0021 #include <bsp/milkymist_memcard.h>
0022
0023
0024
0025 #define BLOCK_SIZE 512
0026
0027 static void memcard_start_cmd_tx(void)
0028 {
0029 MM_WRITE(MM_MEMCARD_ENABLE, MEMCARD_ENABLE_CMD_TX);
0030 }
0031
0032 static void memcard_start_cmd_rx(void)
0033 {
0034 MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_CMD_RX);
0035 MM_WRITE(MM_MEMCARD_START, MEMCARD_START_CMD_RX);
0036 MM_WRITE(MM_MEMCARD_ENABLE, MEMCARD_ENABLE_CMD_RX);
0037 }
0038
0039 static void memcard_start_cmd_dat_rx(void)
0040 {
0041 MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_CMD_RX|MEMCARD_PENDING_DAT_RX);
0042 MM_WRITE(MM_MEMCARD_START, MEMCARD_START_CMD_RX|MEMCARD_START_DAT_RX);
0043 MM_WRITE(MM_MEMCARD_ENABLE, MEMCARD_ENABLE_CMD_RX|MEMCARD_ENABLE_DAT_RX);
0044 }
0045
0046 static void memcard_send_command(unsigned char cmd, unsigned int arg)
0047 {
0048 unsigned char packet[6];
0049 int a;
0050 int i;
0051 unsigned char data;
0052 unsigned char crc;
0053
0054 packet[0] = cmd | 0x40;
0055 packet[1] = ((arg >> 24) & 0xff);
0056 packet[2] = ((arg >> 16) & 0xff);
0057 packet[3] = ((arg >> 8) & 0xff);
0058 packet[4] = (arg & 0xff);
0059
0060 crc = 0;
0061 for(a=0;a<5;a++) {
0062 data = packet[a];
0063 for(i=0;i<8;i++) {
0064 crc <<= 1;
0065 if((data & 0x80) ^ (crc & 0x80))
0066 crc ^= 0x09;
0067 data <<= 1;
0068 }
0069 }
0070 crc = (crc<<1) | 1;
0071
0072 packet[5] = crc;
0073
0074 #ifdef MEMCARD_DEBUG
0075 printk(">> %02x %02x %02x %02x %02x %02x\n",
0076 packet[0], packet[1], packet[2], packet[3], packet[4], packet[5]);
0077 #endif
0078
0079 for(i=0;i<6;i++) {
0080 MM_WRITE(MM_MEMCARD_CMD, packet[i]);
0081 while(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_TX);
0082 }
0083 }
0084
0085 static void memcard_send_dummy(void)
0086 {
0087 MM_WRITE(MM_MEMCARD_CMD, 0xff);
0088 while(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_TX);
0089 }
0090
0091 static bool memcard_receive_command(unsigned char *buffer, int len)
0092 {
0093 int i;
0094 int timeout;
0095
0096 for(i=0;i<len;i++) {
0097 timeout = 2000000;
0098 while(!(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_RX)) {
0099 timeout--;
0100 if(timeout == 0) {
0101 #ifdef MEMCARD_DEBUG
0102 printk("Command receive timeout\n");
0103 #endif
0104 return false;
0105 }
0106 }
0107 buffer[i] = MM_READ(MM_MEMCARD_CMD);
0108 MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_CMD_RX);
0109 }
0110
0111 while(!(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_RX));
0112
0113 #ifdef MEMCARD_DEBUG
0114 printk("<< ");
0115 for(i=0;i<len;i++)
0116 printk("%02x ", buffer[i]);
0117 printk("\n");
0118 #endif
0119
0120 return true;
0121 }
0122
0123 static bool memcard_receive_command_data(unsigned char *command,
0124 unsigned int *data)
0125 {
0126 int i, j;
0127 int timeout;
0128
0129 i = 0;
0130 j = 0;
0131 while(j < 128) {
0132 timeout = 2000000;
0133 while(!(MM_READ(MM_MEMCARD_PENDING) &
0134 (MEMCARD_PENDING_CMD_RX|MEMCARD_PENDING_DAT_RX))) {
0135 timeout--;
0136 if(timeout == 0) {
0137 #ifdef MEMCARD_DEBUG
0138 printk("Command receive timeout\n");
0139 #endif
0140 return false;
0141 }
0142 }
0143 if(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_RX) {
0144 command[i++] = MM_READ(MM_MEMCARD_CMD);
0145 MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_CMD_RX);
0146 if(i == 6)
0147
0148 MM_WRITE(MM_MEMCARD_ENABLE, MEMCARD_ENABLE_DAT_RX);
0149 }
0150 if(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_DAT_RX) {
0151 data[j++] = MM_READ(MM_MEMCARD_DAT);
0152 MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_DAT_RX);
0153 }
0154 }
0155
0156
0157 for(i=0;i<2;i++) {
0158 while(!(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_DAT_RX));
0159 #ifdef MEMCARD_DEBUG
0160 printk("CRC: %08x\n", MM_READ(MM_MEMCARD_DAT));
0161 #endif
0162 MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_DAT_RX);
0163 }
0164
0165 while(!(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_DAT_RX));
0166
0167 #ifdef MEMCARD_DEBUG
0168 printk("<< %02x %02x %02x %02x %02x %02x\n",
0169 command[0], command[1], command[2], command[3], command[4], command[5]);
0170 #endif
0171
0172
0173
0174
0175
0176 return true;
0177 }
0178
0179 static unsigned int block_count;
0180
0181 static int memcard_disk_block_read(rtems_blkdev_request *r)
0182 {
0183 unsigned char b[6];
0184 unsigned int i, nblocks;
0185 unsigned int block;
0186
0187 block = RTEMS_BLKDEV_START_BLOCK(r);
0188 nblocks = r->bufnum;
0189
0190 for(i=0;i<nblocks;i++) {
0191
0192 memcard_start_cmd_tx();
0193 memcard_send_command(17, (block+i)*BLOCK_SIZE);
0194 memcard_start_cmd_dat_rx();
0195 if(!memcard_receive_command_data(b, (unsigned int *)r->bufs[i].buffer))
0196 return -RTEMS_IO_ERROR;
0197 }
0198
0199 rtems_blkdev_request_done(r, RTEMS_SUCCESSFUL);
0200
0201 return 0;
0202 }
0203
0204 static int memcard_disk_block_write(rtems_blkdev_request *r)
0205 {
0206 rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
0207
0208 return 0;
0209 }
0210
0211 static rtems_status_code memcard_init(void)
0212 {
0213 unsigned char b[17];
0214 unsigned int rca;
0215 unsigned int block_shift;
0216 unsigned int c_size;
0217 unsigned int c_size_mult;
0218
0219 MM_WRITE(MM_MEMCARD_CLK2XDIV, 250);
0220
0221
0222 memcard_start_cmd_tx();
0223 memcard_send_command(0, 0);
0224
0225 memcard_send_dummy();
0226
0227
0228 memcard_send_command(8, 0x1aa);
0229 memcard_start_cmd_rx();
0230 if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
0231
0232
0233 while(1) {
0234 memcard_start_cmd_tx();
0235 memcard_send_command(55, 0);
0236 memcard_start_cmd_rx();
0237 if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
0238 memcard_start_cmd_tx();
0239 memcard_send_command(41, 0x00300000);
0240 memcard_start_cmd_rx();
0241 if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
0242 if(b[1] & 0x80) break;
0243 #ifdef MEMCARD_DEBUG
0244 printk("Card is busy, retrying\n");
0245 #endif
0246 }
0247
0248
0249 memcard_start_cmd_tx();
0250 memcard_send_command(2, 0);
0251 memcard_start_cmd_rx();
0252 if(!memcard_receive_command(b, 17)) return RTEMS_IO_ERROR;
0253
0254
0255 memcard_start_cmd_tx();
0256 memcard_send_command(3, 0);
0257 memcard_start_cmd_rx();
0258 if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
0259 rca = (((unsigned int)b[1]) << 8)|((unsigned int)b[2]);
0260 #ifdef MEMCARD_DEBUG
0261 printk("RCA: %04x\n", rca);
0262 #endif
0263
0264
0265 memcard_start_cmd_tx();
0266 memcard_send_command(9, rca << 16);
0267 memcard_start_cmd_rx();
0268 if(!memcard_receive_command(b, 17)) return RTEMS_IO_ERROR;
0269
0270 if(((b)[0] >> 6) != 0)
0271 return RTEMS_IO_ERROR;
0272
0273 block_shift = ((unsigned int)(b)[5] & 0xf);
0274 c_size = ((((unsigned int)(b)[6] & 0x3) << 10)
0275 + (((unsigned int)(b)[7]) << 2)
0276 + ((((unsigned int)(b)[8]) >> 6) & 0x3));
0277 c_size_mult = ((((b)[9] & 0x3) << 1) + (((b)[10] >> 7) & 0x1));
0278 block_count = (c_size + 1) * (1U << (c_size_mult + 2));
0279
0280
0281 if(block_shift < 9)
0282 return RTEMS_IO_ERROR;
0283 block_count <<= block_shift - 9;
0284
0285
0286 memcard_start_cmd_tx();
0287 memcard_send_command(7, rca << 16);
0288 memcard_start_cmd_rx();
0289 if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
0290
0291
0292 memcard_start_cmd_tx();
0293 memcard_send_command(55, rca << 16);
0294 memcard_start_cmd_rx();
0295 if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
0296 memcard_start_cmd_tx();
0297 memcard_send_command(6, 2);
0298 memcard_start_cmd_rx();
0299 if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
0300
0301 MM_WRITE(MM_MEMCARD_CLK2XDIV, 3);
0302
0303 return RTEMS_SUCCESSFUL;
0304 }
0305
0306 static int memcard_disk_ioctl(rtems_disk_device *dd, uint32_t req, void *arg)
0307 {
0308 if (req == RTEMS_BLKIO_REQUEST) {
0309 rtems_blkdev_request *r = (rtems_blkdev_request *)arg;
0310 switch (r->req) {
0311 case RTEMS_BLKDEV_REQ_READ:
0312 return memcard_disk_block_read(r);
0313 case RTEMS_BLKDEV_REQ_WRITE:
0314 return memcard_disk_block_write(r);
0315 default:
0316 errno = EINVAL;
0317 return -1;
0318 }
0319 } else if (req == RTEMS_BLKIO_CAPABILITIES) {
0320 *(uint32_t *)arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
0321 return 0;
0322 } else {
0323 errno = EINVAL;
0324 return -1;
0325 }
0326 }
0327
0328 rtems_status_code memcard_register(void)
0329 {
0330 rtems_status_code sc;
0331
0332 sc = memcard_init();
0333 RTEMS_CHECK_SC(sc, "Initialize memory card");
0334
0335 sc = rtems_blkdev_create("/dev/memcard", BLOCK_SIZE, block_count,
0336 memcard_disk_ioctl, NULL);
0337 RTEMS_CHECK_SC(sc, "Create disk device");
0338
0339 return RTEMS_SUCCESSFUL;
0340 }