Changeset 555 for trunk/modules/sdmmc/caba/source
- Timestamp:
- Oct 22, 2013, 10:46:43 PM (11 years ago)
- Location:
- trunk/modules/sdmmc/caba/source
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/sdmmc/caba/source/include/sdmmc.h
r552 r555 85 85 86 86 void handle_sdmmc_cmd(uint8_t, uint32_t); 87 void handle_sdmmc_write( );87 void handle_sdmmc_write(uint8_t, uint32_t); 88 88 89 89 // Master FSM states … … 94 94 S_RECEIVE_ARGS = 3, 95 95 S_RECEIVE_CRC = 4, 96 S_RECEIVE_DATA 97 S_RECEIVE_DATA _END= 6,96 S_RECEIVE_DATA_WAIT = 5, 97 S_RECEIVE_DATA = 6, 98 98 S_SEND_DATA = 7, 99 S_NOP = 8,100 99 }; 101 100 -
trunk/modules/sdmmc/caba/source/src/sdmmc.cpp
r552 r555 1 /* -*- c++ -*- 1 /* 2 -*- c++ -*- 2 3 * 3 4 * SOCLIB_LGPL_HEADER_BEGIN … … 49 50 } 50 51 if (p_spi_ss.read()) { 52 if (r_spi_fsm != S_IDLE) { 53 std::cerr << name() << " deselect but not idle, state " 54 << std::dec << r_spi_fsm << " last cmd " << (int)r_command 55 << " args " << std::hex << r_args << std::dec 56 << " bitcount " << (int)r_spi_bitcount.read() 57 << " idx " << m_data_idx << " len_snd " << m_datalen_snd 58 << " len_rcv " << m_datalen_rcv << std::endl; 59 } 51 60 r_spi_fsm = S_IDLE; 52 61 return; … … 73 82 r_spi_fsm = S_RECEIVE_ARGS_START; 74 83 } else { 75 #ifdef SOCLIB_MODULE_DEBUG 84 #ifdef SOCLIB_MODULE_DEBUG0 76 85 std::cout << name() << " S_RECEIVE_CMD " << std::hex << ((int)((r_command << 1) | p_spi_mosi) & 0xff) << std::endl; 77 86 #endif … … 125 134 r_spi_fsm = S_SEND_DATA; 126 135 m_data_idx++; 127 #ifdef SOCLIB_MODULE_DEBUG 136 #ifdef SOCLIB_MODULE_DEBUG0 128 137 std::cout << name() << " S_SEND_DATA " << std::dec << m_datalen_snd << " idx " << m_data_idx << " " << std::hex << (uint32_t)m_databuf[m_data_idx] << std::endl; 129 138 #endif 130 139 } else if (m_datalen_rcv != 0) { 131 r_spi_fsm = S_RECEIVE_DATA ;140 r_spi_fsm = S_RECEIVE_DATA_WAIT; 132 141 r_spi_bitcount = 7; 133 142 m_data_idx = 0; … … 141 150 } 142 151 break; 152 case S_RECEIVE_DATA_WAIT: 153 if (p_spi_clk.read() == 1 && r_spi_clk.read() == 0) { 154 uint8_t s_data; 155 // rising edge 156 s_data = (m_databuf[0] << 1) | p_spi_mosi; 157 m_databuf[0] = s_data; 158 r_spi_bitcount = r_spi_bitcount - 1; 159 if (r_spi_bitcount == 0) { 160 #ifdef SOCLIB_MODULE_DEBUG 161 std::cout << name() << " S_RECEIVE_DATA_WAIT " << std::dec << (int)s_data << std::endl; 162 #endif 163 r_spi_bitcount = 7; 164 if (s_data == 0xfe) { // data start token 165 r_spi_fsm = S_RECEIVE_DATA; 166 m_data_idx = 1; 167 } else { 168 #ifdef SOCLIB_MODULE_DEBUG 169 std::cout << name() << " S_RECEIVE_DATA_WAIT " << std::hex << (int)s_data << std::endl; 170 #endif 171 r_spi_fsm = S_RECEIVE_DATA_WAIT; 172 } 173 } 174 } 175 break; 176 case S_RECEIVE_DATA: 177 if (p_spi_clk.read() == 1 && r_spi_clk.read() == 0) { 178 // rising edge 179 m_databuf[m_data_idx] = (m_databuf[m_data_idx] << 1) | p_spi_mosi; 180 if (r_spi_bitcount == 0) { 181 m_data_idx++; 182 if (m_data_idx != m_datalen_rcv) { 183 r_spi_fsm = S_RECEIVE_DATA; 184 r_spi_bitcount = 7; 185 } else { 186 handle_sdmmc_write(r_command.read(), r_args.read()); 187 if (m_datalen_snd > 0) { 188 r_spi_bitcount = 0; // SEND_DATA will reset it 189 r_spi_fsm = S_SEND_DATA; 190 m_data_idx = 0; 191 } else { 192 r_spi_fsm = S_IDLE; 193 } 194 } 195 } else { 196 r_spi_bitcount = r_spi_bitcount - 1; 197 } 198 } 199 break; 143 200 } 144 201 } // end transition … … 177 234 cmd &= 0x3f; 178 235 if (m_acmd) { 179 #ifdef SOCLIB_MODULE_DEBUG 236 #ifdef SOCLIB_MODULE_DEBUG0 180 237 std::cout << name() << " new acmd " << std::dec << (int)cmd << " args " << std::hex << data << " crc " << (int)r_cmdcrc << std::endl; 181 238 #endif … … 209 266 } 210 267 } else { 211 #ifdef SOCLIB_MODULE_DEBUG 268 #ifdef SOCLIB_MODULE_DEBUG0 212 269 std::cout << name() << " new cmd " << std::dec << (int)cmd << " args " << std::hex << data << " crc " << (int)r_cmdcrc << std::endl; 213 270 #endif … … 323 380 break; 324 381 } 382 case 24: 383 { 384 // write data block 385 if (m_sdstate == SD_IDLE) { 386 // return illegal command 387 return; 388 } 389 #ifdef SOCLIB_MODULE_DEBUG 390 std::cout << name() << " new cmd write " << std::dec << (int)cmd << " args " << std::hex << data << std::endl; 391 #endif 392 m_databuf[0] = 0x0; // R1 393 m_datalen_snd = 1; 394 m_datalen_rcv = 512 + 2 + 1; // data + tocken + CRC 395 break; 396 } 325 397 case 55: 326 398 // app-specific command follow … … 346 418 } 347 419 348 void SdMMC::handle_sdmmc_write() 349 { 420 void SdMMC::handle_sdmmc_write(uint8_t cmd, uint32_t data) 421 { 422 m_datalen_rcv = 0; 423 cmd &= 0x3f; 424 #ifdef SOCLIB_MODULE_DEBUG 425 std::cout << name() << " cmd write " << std::dec << (int)cmd << " args " << std::hex << data << std::endl; 426 #endif 427 switch(cmd) { 428 case 24: 429 { 430 int ret; 431 // write data block 432 assert(m_sdstate != SD_IDLE && "can't write in idle state"); 433 if (data >= m_device_size) { 434 std::cerr << name() << " write: request " << data 435 << " past end of file " << m_device_size << std::endl; 436 m_databuf[0] = 0xd; // write error 437 m_datalen_snd = 1; 438 return; 439 } 440 do { 441 if (lseek(m_fd, data, SEEK_SET) < 0) { 442 std::cerr << name() << " lseek: " << 443 strerror(errno) << std::endl; 444 m_databuf[0] = 0xd; // write error 445 m_datalen_snd = 1; 446 return; 447 } 448 ret = write(m_fd, &m_databuf[1], 512); 449 } while (ret < 0 && errno == EINTR); 450 if (ret < 0) { 451 std::cerr << name() << " write: " << 452 strerror(errno) << std::endl; 453 m_databuf[0] = 0xd; // write error 454 m_datalen_snd = 1; 455 return; 456 } 457 m_databuf[0] = 0x5; // write complete 458 m_databuf[1] = 0x0; // busy 459 m_datalen_snd = 2; 460 break; 461 } 462 default: 463 std::cerr << name() << " unkown write cmd " << std::dec << 464 (int)cmd << std::endl; 465 m_databuf[0] = 0xd; // write error; 466 m_datalen_snd = 1; 467 } 350 468 return; 351 469 } … … 401 519 "S_RECEIVE_ARGS", 402 520 "S_RECEIVE_CRC", 521 "S_RECEIVE_DATA_START", 403 522 "S_RECEIVE_DATA", 404 "S_RECEIVE_DATA_END",405 523 "S_SEND_DATA", 406 524 "S_NOP",
Note: See TracChangeset
for help on using the changeset viewer.