1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
-147
-148
-149
-150
-151
-152
-153
-154
-155
-156
-157
-158
-159
-160
-161
-162
-163
-164
-165
-166
-167
-168
-169
-170
-171
-172
-173
-174
-175
-176
-177
-178
-179
-180
-181
-182
-183
-184
-185
-186
-187
-188
-189
-190
-191
-192
-193
-194
-195
-196
-197
-198
-199
-200
-201
-202
-203
-204
-205
-206
-207
-208
-209
-210
-211
-212
-213
-214
-215
-216
-217
-218
-219
-220
-221
-222
-223
-224
-225
-226
-227
-228
-229
-230
-231
-232
-233
-234
-235
-236
-237
-238
-239
-240
-241
-242
-243
-244
-245
-246
-247
-248
-249
-250
-251
-252
-253
-254
-255
-256
-257
-258
-259
-260
-261
-262
-263
-264
-265
-266
-267
-268
-269
-270
-271
-272
-273
-274
-275
-276
-277
-278
-279
-280
-281
-282
-283
-284
-285
-286
-287
-288
-289
-290
-291
-292
-293
-294
-295
-296
-297
-298
-299
-300
-301
-302
-303
-304
-305
-306
-307
-308
-309
-310
-311
-312
-313
-314
-315
-316
-317
-318
-319
-320
-321
-322
-323
-324
-325
-326
-327
-328
-329
-330
-331
-332
-333
-334
-335
-336
-337
-338
-339
-340
-341
-342
-343
-344
-345
-346
-347
-348
-349
-350
-351
-352
-353
-354
-355
-356
-357
-358
-359
-360
-361
-362
-363
-364
-365
-366
-367
-368
-369
-370
-371
-372
-373
-374
-375
-376
-377
-378
-379
-380
-381
-382
-383
-384
-385
-386
-387
-388
-389
-390
-391
-392
-393
-394
-395
-396
-397
-398
-399
-400
-401
-402
-403
-404
-405
-406
-407
-408
-409
-410
-411
-412
-413
-414
-415
-416
-417
-418
-419
-420
-421
-422
-423
-424
-425
-426
-427
-428
-429
-430
-431
-432
-433
-434
-435
-436
-437
-438
-439
-440
-441
-442
-443
-444
-445
-446
-447
-448
-449
-450
-451
-452
-453
-454
-455
-456
-457
-458
-459
-460
-461
-462
-463
-464
-465
-466
-467
-468
-469
-470
-471
-472
-473
-474
-475
-476
-477
-478
-479
-480
-481
-482
-483
-484
-485
-486
-487
-488
-489
-490
-491
-492
-493
-494
-495
-496
-497
-498
-499
-500
-501
-502
-503
-504
-505
-506
-507
-508
-509
-510
-511
-512
-513
-514
-515
-516
-517
-518
-519
-520
-521
-522
-523
-524
-525
-526
-527
-528
-529
-530
-531
-532
-533
-534
-535
-536
-537
-538
-539
-540
-541
-542
-543
-544
-545
-546
-547
-548
-549
-550
-551
-552
-553
-554
-555
-556
-557
-558
-559
-560
-561
-562
-563
-564
-565
-566
-567
-568
-569
-570
-571
-572
-573
-574
-575
-576
-577
-578
-579
-580
-581
-582
-583
-584
-585
-586
-587
-588
-589
-590
-591
-592
-593
-594
-595
-596
-597
-598
-599
-600
-601
-602
-603
-604
-605
-606
-607
-608
-609
-610
-611
-612
-613
-614
-615
-616
-617
-618
-619
-620
-621
-622
-623
-624
-625
-626
-627
-628
-629
-630
-631
-632
-633
-634
-635
-636
-637
-638
-639
-640
-641
-642
-643
-644
-645
-646
-647
-648
-649
-650
-651
-652
-653
-654
-655
-656
-657
-658
-659
-660
-661
-662
-663
-664
-665
-666
-667
-668
-669
-670
-671
-672
-673
-674
-675
-676
-677
-678
-679
-680
-681
-682
-683
-684
-685
-686
-687
-688
-689
-690
-691
-692
-693
-694
-695
-696
-697
-698
-699
-700
-701
-702
-703
-704
-705
-706
-707
-708
-709
-710
-711
-712
-713
-714
-715
-716
-717
-718
-719
-720
-721
-722
-723
-724
-725
-726
-727
-728
-729
-730
-731
-732
-733
-734
-735
-736
-737
-738
-739
-740
-741
-742
-743
-744
-745
-746
-747
-748
-749
-750
-751
-752
-753
-754
-755
-756
-757
-758
-759
-760
-761
-762
-763
-764
-765
-766
-767
-
#![allow(non_snake_case)]
-#![allow(non_camel_case_types)]
-#![allow(unused)]
-
-use super::BlockDevice;
-use crate::sync::UPIntrFreeCell;
-use core::convert::TryInto;
-use k210_hal::prelude::*;
-use k210_pac::{Peripherals, SPI0};
-use k210_soc::{
- fpioa::{self, io},
-
- gpio,
- gpiohs,
- sleep::usleep,
- spi::{aitm, frame_format, tmod, work_mode, SPIExt, SPIImpl, SPI},
- sysctl,
-};
-use lazy_static::*;
-
-pub struct SDCard<SPI> {
- spi: SPI,
- spi_cs: u32,
- cs_gpionum: u8,
-
-
-}
-
-
-
-pub const SD_START_DATA_SINGLE_BLOCK_READ: u8 = 0xFE;
-
-pub const SD_START_DATA_MULTIPLE_BLOCK_READ: u8 = 0xFE;
-
-pub const SD_START_DATA_SINGLE_BLOCK_WRITE: u8 = 0xFE;
-
-pub const SD_START_DATA_MULTIPLE_BLOCK_WRITE: u8 = 0xFC;
-
-pub const SEC_LEN: usize = 512;
-
-
-#[repr(u8)]
-#[derive(Debug, PartialEq, Eq, Copy, Clone)]
-#[allow(unused)]
-pub enum CMD {
-
- CMD0 = 0,
-
- CMD8 = 8,
-
- CMD9 = 9,
-
- CMD10 = 10,
-
- CMD12 = 12,
-
- CMD16 = 16,
-
- CMD17 = 17,
-
- CMD18 = 18,
-
- ACMD23 = 23,
-
- CMD24 = 24,
-
- CMD25 = 25,
-
- ACMD41 = 41,
-
- CMD55 = 55,
-
- CMD58 = 58,
-
- CMD59 = 59,
-}
-
-#[allow(unused)]
-#[derive(Debug, Copy, Clone)]
-pub enum InitError {
- CMDFailed(CMD, u8),
- CardCapacityStatusNotSet([u8; 4]),
- CannotGetCardInfo,
-}
-
-
-#[derive(Debug, Copy, Clone)]
-pub struct SDCardCSD {
- pub CSDStruct: u8,
- pub SysSpecVersion: u8,
- pub Reserved1: u8,
- pub TAAC: u8,
- pub NSAC: u8,
- pub MaxBusClkFrec: u8,
- pub CardComdClasses: u16,
- pub RdBlockLen: u8,
- pub PartBlockRead: u8,
- pub WrBlockMisalign: u8,
- pub RdBlockMisalign: u8,
- pub DSRImpl: u8,
- pub Reserved2: u8,
- pub DeviceSize: u32,
-
-
-
-
-
- pub EraseGrSize: u8,
- pub EraseGrMul: u8,
- pub WrProtectGrSize: u8,
- pub WrProtectGrEnable: u8,
- pub ManDeflECC: u8,
- pub WrSpeedFact: u8,
- pub MaxWrBlockLen: u8,
- pub WriteBlockPaPartial: u8,
- pub Reserved3: u8,
- pub ContentProtectAppli: u8,
- pub FileFormatGroup: u8,
- pub CopyFlag: u8,
- pub PermWrProtect: u8,
- pub TempWrProtect: u8,
- pub FileFormat: u8,
- pub ECC: u8,
- pub CSD_CRC: u8,
- pub Reserved4: u8,
-}
-
-
-#[derive(Debug, Copy, Clone)]
-pub struct SDCardCID {
- pub ManufacturerID: u8,
- pub OEM_AppliID: u16,
- pub ProdName1: u32,
- pub ProdName2: u8,
- pub ProdRev: u8,
- pub ProdSN: u32,
- pub Reserved1: u8,
- pub ManufactDate: u16,
- pub CID_CRC: u8,
- pub Reserved2: u8,
-}
-
-
-#[derive(Debug, Copy, Clone)]
-pub struct SDCardInfo {
- pub SD_csd: SDCardCSD,
- pub SD_cid: SDCardCID,
- pub CardCapacity: u64,
- pub CardBlockSize: u64,
-}
-
-impl< X: SPI> SDCard< X> {
- pub fn new(
- spi: X,
- spi_cs: u32,
- cs_gpionum: u8,
- ) -> Self {
- Self {
- spi,
- spi_cs,
- cs_gpionum,
-
- }
- }
-
- fn CS_HIGH(&self) {
- gpiohs::set_pin(self.cs_gpionum, true);
- }
-
- fn CS_LOW(&self) {
- gpiohs::set_pin(self.cs_gpionum, false);
- }
-
- fn HIGH_SPEED_ENABLE(&self) {
- self.spi.set_clk_rate(10000000);
- }
-
- fn lowlevel_init(&self) {
- gpiohs::set_direction(self.cs_gpionum, gpio::direction::OUTPUT);
- self.spi.set_clk_rate(200000);
- }
-
- fn write_data(&self, data: &[u8]) {
- self.spi.configure(
- work_mode::MODE0,
- frame_format::STANDARD,
- 8,
- 0,
- 0,
- 0,
- 0,
- aitm::STANDARD,
- tmod::TRANS,
- );
- self.spi.send_data(self.spi_cs, data);
- }
-
-
-
- fn read_data(&self, data: &mut [u8]) {
- self.spi.configure(
- work_mode::MODE0,
- frame_format::STANDARD,
- 8,
- 0,
- 0,
- 0,
- 0,
- aitm::STANDARD,
- tmod::RECV,
- );
- self.spi.recv_data(self.spi_cs, data);
- }
-
-
-
-
- fn send_cmd(&self, cmd: CMD, arg: u32, crc: u8) {
-
- self.CS_LOW();
-
- self.write_data(&[
-
- ((cmd as u8) | 0x40),
-
- (arg >> 24) as u8,
-
- ((arg >> 16) & 0xff) as u8,
-
- ((arg >> 8) & 0xff) as u8,
-
- (arg & 0xff) as u8,
-
- crc,
- ]);
- }
-
-
- fn end_cmd(&self) {
-
- self.CS_HIGH();
-
- self.write_data(&[0xff]);
- }
-
-
- fn get_response(&self) -> u8 {
- let result = &mut [0u8];
- let mut timeout = 0x0FFF;
-
- while timeout != 0 {
- self.read_data(result);
-
- if result[0] != 0xFF {
- return result[0];
- }
- timeout -= 1;
- }
-
- 0xFF
- }
-
-
- fn get_dataresponse(&self) -> u8 {
- let response = &mut [0u8];
-
- self.read_data(response);
-
- response[0] &= 0x1F;
- if response[0] != 0x05 {
- return 0xFF;
- }
-
- self.read_data(response);
- while response[0] == 0 {
- self.read_data(response);
- }
-
- 0
- }
-
-
- fn get_csdregister(&self) -> Result<SDCardCSD, ()> {
- let mut csd_tab = [0u8; 18];
-
- self.send_cmd(CMD::CMD9, 0, 0);
-
- if self.get_response() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
- self.end_cmd();
- return Err(());
- }
-
-
- self.read_data(&mut csd_tab);
- self.end_cmd();
-
- Ok(SDCardCSD {
-
- CSDStruct: (csd_tab[0] & 0xC0) >> 6,
- SysSpecVersion: (csd_tab[0] & 0x3C) >> 2,
- Reserved1: csd_tab[0] & 0x03,
-
- TAAC: csd_tab[1],
-
- NSAC: csd_tab[2],
-
- MaxBusClkFrec: csd_tab[3],
-
- CardComdClasses: (u16::from(csd_tab[4]) << 4) | ((u16::from(csd_tab[5]) & 0xF0) >> 4),
-
- RdBlockLen: csd_tab[5] & 0x0F,
-
- PartBlockRead: (csd_tab[6] & 0x80) >> 7,
- WrBlockMisalign: (csd_tab[6] & 0x40) >> 6,
- RdBlockMisalign: (csd_tab[6] & 0x20) >> 5,
- DSRImpl: (csd_tab[6] & 0x10) >> 4,
- Reserved2: 0,
-
-
- DeviceSize: ((u32::from(csd_tab[7]) & 0x3F) << 16)
- | (u32::from(csd_tab[8]) << 8)
- | u32::from(csd_tab[9]),
-
- EraseGrSize: (csd_tab[10] & 0x40) >> 6,
-
- EraseGrMul: ((csd_tab[10] & 0x3F) << 1) | ((csd_tab[11] & 0x80) >> 7),
-
- WrProtectGrSize: (csd_tab[11] & 0x7F),
-
- WrProtectGrEnable: (csd_tab[12] & 0x80) >> 7,
- ManDeflECC: (csd_tab[12] & 0x60) >> 5,
- WrSpeedFact: (csd_tab[12] & 0x1C) >> 2,
-
- MaxWrBlockLen: ((csd_tab[12] & 0x03) << 2) | ((csd_tab[13] & 0xC0) >> 6),
-
- WriteBlockPaPartial: (csd_tab[13] & 0x20) >> 5,
- Reserved3: 0,
- ContentProtectAppli: (csd_tab[13] & 0x01),
-
- FileFormatGroup: (csd_tab[14] & 0x80) >> 7,
- CopyFlag: (csd_tab[14] & 0x40) >> 6,
- PermWrProtect: (csd_tab[14] & 0x20) >> 5,
- TempWrProtect: (csd_tab[14] & 0x10) >> 4,
- FileFormat: (csd_tab[14] & 0x0C) >> 2,
- ECC: (csd_tab[14] & 0x03),
-
- CSD_CRC: (csd_tab[15] & 0xFE) >> 1,
- Reserved4: 1,
-
- })
- }
-
-
- fn get_cidregister(&self) -> Result<SDCardCID, ()> {
- let mut cid_tab = [0u8; 18];
-
- self.send_cmd(CMD::CMD10, 0, 0);
-
- if self.get_response() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
- self.end_cmd();
- return Err(());
- }
-
-
- self.read_data(&mut cid_tab);
- self.end_cmd();
- Ok(SDCardCID {
-
- ManufacturerID: cid_tab[0],
-
- OEM_AppliID: (u16::from(cid_tab[1]) << 8) | u16::from(cid_tab[2]),
-
- ProdName1: (u32::from(cid_tab[3]) << 24)
- | (u32::from(cid_tab[4]) << 16)
- | (u32::from(cid_tab[5]) << 8)
- | u32::from(cid_tab[6]),
-
- ProdName2: cid_tab[7],
-
- ProdRev: cid_tab[8],
-
- ProdSN: (u32::from(cid_tab[9]) << 24)
- | (u32::from(cid_tab[10]) << 16)
- | (u32::from(cid_tab[11]) << 8)
- | u32::from(cid_tab[12]),
-
- Reserved1: (cid_tab[13] & 0xF0) >> 4,
- ManufactDate: ((u16::from(cid_tab[13]) & 0x0F) << 8) | u16::from(cid_tab[14]),
-
- CID_CRC: (cid_tab[15] & 0xFE) >> 1,
- Reserved2: 1,
- })
- }
-
-
- fn get_cardinfo(&self) -> Result<SDCardInfo, ()> {
- let mut info = SDCardInfo {
- SD_csd: self.get_csdregister()?,
- SD_cid: self.get_cidregister()?,
- CardCapacity: 0,
- CardBlockSize: 0,
- };
- info.CardBlockSize = 1 << u64::from(info.SD_csd.RdBlockLen);
- info.CardCapacity = (u64::from(info.SD_csd.DeviceSize) + 1) * 1024 * info.CardBlockSize;
-
- Ok(info)
- }
-
-
- pub fn init(&self) -> Result<SDCardInfo, InitError> {
-
- self.lowlevel_init();
-
- self.CS_HIGH();
-
-
-
-
-
- self.write_data(&[0xff; 10]);
-
-
-
-
- self.send_cmd(CMD::CMD0, 0, 0x95);
- let result = self.get_response();
- self.end_cmd();
- if result != 0x01 {
- return Err(InitError::CMDFailed(CMD::CMD0, result));
- }
-
-
- self.send_cmd(CMD::CMD8, 0x01AA, 0x87);
-
- let result = self.get_response();
- let mut frame = [0u8; 4];
- self.read_data(&mut frame);
- self.end_cmd();
- if result != 0x01 {
- return Err(InitError::CMDFailed(CMD::CMD8, result));
- }
- let mut index = 255;
- while index != 0 {
-
- self.send_cmd(CMD::CMD55, 0, 0);
- let result = self.get_response();
- self.end_cmd();
- if result != 0x01 {
- return Err(InitError::CMDFailed(CMD::CMD55, result));
- }
-
- self.send_cmd(CMD::ACMD41, 0x40000000, 0);
- let result = self.get_response();
- self.end_cmd();
- if result == 0x00 {
- break;
- }
- index -= 1;
- }
- if index == 0 {
- return Err(InitError::CMDFailed(CMD::ACMD41, result));
- }
- index = 255;
- let mut frame = [0u8; 4];
- while index != 0 {
-
- self.send_cmd(CMD::CMD58, 0, 1);
- let result = self.get_response();
- self.read_data(&mut frame);
- self.end_cmd();
- if result == 0 {
- break;
- }
- index -= 1;
- }
- if index == 0 {
- return Err(InitError::CMDFailed(CMD::CMD58, result));
- }
- if (frame[0] & 0x40) == 0 {
- return Err(InitError::CardCapacityStatusNotSet(frame));
- }
- self.HIGH_SPEED_ENABLE();
- self.get_cardinfo()
- .map_err(|_| InitError::CannotGetCardInfo)
- }
-
-
- pub fn read_sector(&self, data_buf: &mut [u8], sector: u32) -> Result<(), ()> {
- assert!(data_buf.len() >= SEC_LEN && (data_buf.len() % SEC_LEN) == 0);
-
- let flag = if data_buf.len() == SEC_LEN {
- self.send_cmd(CMD::CMD17, sector, 0);
- false
- } else {
- self.send_cmd(CMD::CMD18, sector, 0);
- true
- };
-
- if self.get_response() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- let mut error = false;
-
- let mut tmp_chunk = [0u8; SEC_LEN];
- for chunk in data_buf.chunks_mut(SEC_LEN) {
- if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
- error = true;
- break;
- }
-
-
- self.read_data(&mut tmp_chunk);
-
- for (a, b) in chunk.iter_mut().zip( tmp_chunk.iter()) {
-
- *a = *b;
- }
-
- let mut frame = [0u8; 2];
- self.read_data(&mut frame);
- }
- self.end_cmd();
- if flag {
- self.send_cmd(CMD::CMD12, 0, 0);
- self.get_response();
- self.end_cmd();
- self.end_cmd();
- }
-
- if error {
- Err(())
- } else {
- Ok(())
- }
- }
-
-
- pub fn write_sector(&self, data_buf: &[u8], sector: u32) -> Result<(), ()> {
- assert!(data_buf.len() >= SEC_LEN && (data_buf.len() % SEC_LEN) == 0);
- let mut frame = [0xff, 0x00];
- if data_buf.len() == SEC_LEN {
- frame[1] = SD_START_DATA_SINGLE_BLOCK_WRITE;
- self.send_cmd(CMD::CMD24, sector, 0);
- } else {
- frame[1] = SD_START_DATA_MULTIPLE_BLOCK_WRITE;
- self.send_cmd(
- CMD::ACMD23,
- (data_buf.len() / SEC_LEN).try_into().unwrap(),
- 0,
- );
- self.get_response();
- self.end_cmd();
- self.send_cmd(CMD::CMD25, sector, 0);
- }
-
- if self.get_response() != 0x00 {
- self.end_cmd();
- return Err(());
- }
-
- let mut tmp_chunk = [0u8; SEC_LEN];
- for chunk in data_buf.chunks(SEC_LEN) {
-
- self.write_data(&frame);
-
- for (a, &b) in tmp_chunk.iter_mut().zip(chunk.iter()) {
-
- *a = b;
- }
-
- self.write_data(&tmp_chunk);
-
- self.write_data(&[0xff, 0xff]);
-
- if self.get_dataresponse() != 0x00 {
- self.end_cmd();
- return Err(());
- }
- }
- self.end_cmd();
- self.end_cmd();
- Ok(())
- }
-}
-
-
-const SD_CS_GPIONUM: u8 = 7;
-
-const SD_CS: u32 = 3;
-
-
-fn io_init() {
- fpioa::set_function(io::SPI0_SCLK, fpioa::function::SPI0_SCLK);
- fpioa::set_function(io::SPI0_MOSI, fpioa::function::SPI0_D0);
- fpioa::set_function(io::SPI0_MISO, fpioa::function::SPI0_D1);
- fpioa::set_function(io::SPI0_CS0, fpioa::function::gpiohs(SD_CS_GPIONUM));
- fpioa::set_io_pull(io::SPI0_CS0, fpioa::pull::DOWN);
-}
-
-lazy_static! {
- static ref PERIPHERALS: UPIntrFreeCell<Peripherals> =
- unsafe { UPIntrFreeCell::new(Peripherals::take().unwrap()) };
-}
-
-fn init_sdcard() -> SDCard<SPIImpl<SPI0>> {
-
- usleep(100000);
- let peripherals = unsafe { Peripherals::steal() };
- sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap();
- sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap();
- sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap();
- let clocks = k210_hal::clock::Clocks::new();
- peripherals.UARTHS.configure(115_200.bps(), &clocks);
- io_init();
-
- let spi = peripherals.SPI0.constrain();
- let sd = SDCard::new(spi, SD_CS, SD_CS_GPIONUM);
- let info = sd.init().unwrap();
- let num_sectors = info.CardCapacity / 512;
- assert!(num_sectors > 0);
-
- println!("init sdcard!");
- sd
-}
-
-pub struct SDCardWrapper(UPIntrFreeCell<SDCard<SPIImpl<SPI0>>>);
-
-impl SDCardWrapper {
- pub fn new() -> Self {
- unsafe { Self(UPIntrFreeCell::new(init_sdcard())) }
- }
-}
-
-impl BlockDevice for SDCardWrapper {
- fn read_block(&self, block_id: usize, buf: &mut [u8]) {
- self.0
- .exclusive_access()
- .read_sector(buf, block_id as u32)
- .unwrap();
- }
- fn write_block(&self, block_id: usize, buf: &[u8]) {
- self.0
- .exclusive_access()
- .write_sector(buf, block_id as u32)
- .unwrap();
- }
- fn handle_irq(&self) {
- unimplemented!();
- }
-}
-
-