Changeset 1052 for trunk/modules
- Timestamp:
- Jun 21, 2017, 10:50:42 AM (8 years ago)
- Location:
- trunk/modules
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/sdmmc/caba/source/include/sdmmc.h
r574 r1052 55 55 56 56 // Registers 57 int spi_fsm; // SPI state register58 int spi_shiftreg;// data shift in/out59 int spi_bitcount;60 int spi_clk;61 int spi_mosi_previous; // sampled MOSI value57 int spi_fsm; // SPI state register 58 int spi_shiftreg; // data shift in/out 59 int spi_bitcount; 60 int spi_clk; 61 int spi_mosi_previous; // sampled MOSI value 62 62 63 uint8_t command;63 uint8_t command; 64 64 uint32_t args; 65 uint8_t cmdcrc; 65 uint8_t cmdcrc; 66 66 67 int m_fd; // File descriptor 67 68 uint64_t m_device_size; // Total number of blocks 68 69 const uint32_t m_latency; // device latency 69 70 70 uint8_t m_databuf[1 /* reponse */ + 1 /* data tocken */ + 512 /* data block */ + 2 /* CRC */ ]; 71 uint32_t m_datalen_snd; // data size to be sent to host 72 uint32_t m_datalen_rcv; // data size expected from host 71 uint8_t m_databuf[1 /* reponse */ + 72 1 /* data tocken */ + 73 512 /* data block */ + 74 2 /* CRC */ ]; 75 76 uint32_t m_datalen_snd; // data size to be sent to host 77 uint32_t m_datalen_rcv; // data size expected from host 73 78 uint32_t m_data_idx; 74 bool m_acmd;// next command will be acmd75 int m_sdstate;// sdcard internal state79 bool m_acmd; // next command will be acmd 80 int m_sdstate; // sdcard internal state 76 81 77 82 // sd states 78 enum { 79 SD_IDLE = 0, 80 SD_READY = 1, 83 enum 84 { 85 SD_IDLE = 0, 86 SD_READY = 1, 81 87 }; 82 88 … … 88 94 89 95 // Master FSM states 90 enum { 96 enum 97 { 91 98 S_IDLE = 0, 92 99 S_RECEIVE_CMD = 1, -
trunk/modules/sdmmc/caba/source/src/sdmmc.cpp
r709 r1052 46 46 { 47 47 spi_fsm = S_IDLE; 48 49 48 m_acmd = false; 49 m_sdstate = SD_IDLE; 50 50 return; 51 51 } 52 if (p_spi_ss.read()) { 53 if (spi_fsm != S_IDLE) { 54 std::cerr << name() << " deselect but not idle, state " 55 << std::dec << spi_fsm << " last cmd " << (int)command 56 << " args " << std::hex << args << std::dec 57 << " bitcount " << (int)spi_bitcount 58 << " idx " << m_data_idx << " len_snd " << m_datalen_snd 59 << " len_rcv " << m_datalen_rcv << std::endl; 60 } 61 spi_fsm = S_IDLE; 62 spi_clk = p_spi_clk; 63 spi_mosi_previous = p_spi_mosi; 64 return; 52 53 if (p_spi_ss.read()) 54 { 55 if (spi_fsm != S_IDLE) 56 { 57 std::cerr << name() << " deselect but not idle, state " 58 << std::dec << spi_fsm << " last cmd " << (int)command 59 << " args " << std::hex << args << std::dec 60 << " bitcount " << (int)spi_bitcount 61 << " idx " << m_data_idx << " len_snd " << m_datalen_snd 62 << " len_rcv " << m_datalen_rcv << std::endl; 63 } 64 spi_fsm = S_IDLE; 65 spi_clk = p_spi_clk; 66 spi_mosi_previous = p_spi_mosi; 67 return; 65 68 } 66 69 67 switch(spi_fsm) { 68 case S_IDLE: 69 if (p_spi_clk.read() == 1 && spi_clk == 0) { 70 // rising edge 71 command = (command << 1) | spi_mosi_previous; 72 spi_bitcount = 6; 73 spi_fsm = S_RECEIVE_CMD; 74 } 75 break; 76 case S_RECEIVE_CMD: 77 if (p_spi_clk.read() == 1 && spi_clk == 0) { 78 // rising edge 79 command = (command << 1) | spi_mosi_previous; 80 if (spi_bitcount == 0) { 81 if ((command & 0x80) == 0) { 82 spi_fsm = S_RECEIVE_ARGS_START; 83 } else { 70 switch(spi_fsm) 71 { 72 case S_IDLE: 73 if (p_spi_clk.read() == 1 && spi_clk == 0) // rising edge 74 { 75 command = (command << 1) | spi_mosi_previous; 76 spi_bitcount = 6; 77 spi_fsm = S_RECEIVE_CMD; 78 } 79 break; 80 case S_RECEIVE_CMD: 81 if (p_spi_clk.read() == 1 && spi_clk == 0) // rising edge 82 { 83 command = (command << 1) | spi_mosi_previous; 84 if (spi_bitcount == 0) 85 { 86 if ((command & 0x80) == 0) 87 { 88 spi_fsm = S_RECEIVE_ARGS_START; 89 } 90 else 91 { 84 92 #ifdef SOCLIB_MODULE_DEBUG0 85 93 std::cout << name() << " S_RECEIVE_CMD " << std::hex << (int)command << std::endl; 86 94 #endif 87 spi_fsm = S_IDLE; 88 } 89 } else { 90 spi_bitcount = spi_bitcount - 1; 91 } 92 } 93 break; 94 case S_RECEIVE_ARGS_START: 95 if (p_spi_clk.read() == 1 && spi_clk == 0) { 96 // rising edge 97 args = (args << 1) | spi_mosi_previous; 98 spi_bitcount = 30; 99 spi_fsm = S_RECEIVE_ARGS; 100 } 101 break; 102 case S_RECEIVE_ARGS: 103 if (p_spi_clk.read() == 1 && spi_clk == 0) { 104 // rising edge 105 args = (args << 1) | spi_mosi_previous; 106 if (spi_bitcount == 0) { 107 spi_bitcount = 7; 108 spi_fsm = S_RECEIVE_CRC; 109 } else { 110 spi_bitcount = spi_bitcount - 1; 111 } 112 } 113 break; 114 case S_RECEIVE_CRC: 115 if (p_spi_clk.read() == 1 && spi_clk == 0) { 116 // rising edge 117 cmdcrc = (cmdcrc << 1) | spi_mosi_previous; 118 if (spi_bitcount == 0) { 119 handle_sdmmc_cmd(command, args); 120 spi_bitcount = 0; // SEND_DATA will reset it 121 spi_fsm = S_SEND_DATA; 122 m_data_idx = 0; 123 } else { 124 spi_bitcount = spi_bitcount - 1; 125 } 126 } 127 break; 95 spi_fsm = S_IDLE; 96 } 97 } 98 else 99 { 100 spi_bitcount = spi_bitcount - 1; 101 } 102 } 103 break; 104 case S_RECEIVE_ARGS_START: 105 if (p_spi_clk.read() == 1 && spi_clk == 0) // rising edge 106 { 107 args = (args << 1) | spi_mosi_previous; 108 spi_bitcount = 30; 109 spi_fsm = S_RECEIVE_ARGS; 110 } 111 break; 112 case S_RECEIVE_ARGS: 113 if (p_spi_clk.read() == 1 && spi_clk == 0) // rising edge 114 { 115 args = (args << 1) | spi_mosi_previous; 116 if (spi_bitcount == 0) 117 { 118 spi_bitcount = 7; 119 spi_fsm = S_RECEIVE_CRC; 120 } 121 else 122 { 123 spi_bitcount = spi_bitcount - 1; 124 } 125 } 126 break; 127 case S_RECEIVE_CRC: 128 if (p_spi_clk.read() == 1 && spi_clk == 0) // rising edge 129 { 130 cmdcrc = (cmdcrc << 1) | spi_mosi_previous; 131 if (spi_bitcount == 0) 132 { 133 handle_sdmmc_cmd(command, args); 134 spi_bitcount = 0; // SEND_DATA will reset it 135 spi_fsm = S_SEND_DATA; 136 m_data_idx = 0; 137 } 138 else 139 { 140 spi_bitcount = spi_bitcount - 1; 141 } 142 } 143 break; 128 144 129 case S_SEND_DATA: 130 if (p_spi_clk.read() == 0 && spi_clk == 1) { 131 // falling edge 132 if (spi_bitcount == 0) { 133 if (m_data_idx != m_datalen_snd) { 134 spi_shiftreg = m_databuf[m_data_idx]; 135 spi_bitcount = 7; 136 spi_fsm = S_SEND_DATA; 137 m_data_idx++; 145 case S_SEND_DATA: 146 if (p_spi_clk.read() == 0 && spi_clk == 1) // falling edge 147 { 148 if (spi_bitcount == 0) 149 { 150 if (m_data_idx != m_datalen_snd) 151 { 152 spi_shiftreg = m_databuf[m_data_idx]; 153 spi_bitcount = 7; 154 spi_fsm = S_SEND_DATA; 155 m_data_idx++; 138 156 #ifdef SOCLIB_MODULE_DEBUG0 139 157 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; 140 158 #endif 141 } else if (m_datalen_rcv != 0) { 142 spi_fsm = S_RECEIVE_DATA_WAIT; 143 spi_bitcount = 7; 144 m_data_idx = 0; 145 } else { 146 spi_fsm = S_IDLE; 147 } 148 } else { 149 spi_bitcount = spi_bitcount - 1; 150 spi_shiftreg = spi_shiftreg << 1; 151 } 152 } 153 break; 154 case S_RECEIVE_DATA_WAIT: 155 if (p_spi_clk.read() == 1 && spi_clk == 0) { 156 // rising edge 157 uint8_t s_data; 158 s_data = (m_databuf[0] << 1) | spi_mosi_previous; 159 m_databuf[0] = s_data; 160 if (spi_bitcount == 0) { 159 } 160 else if (m_datalen_rcv != 0) 161 { 162 spi_fsm = S_RECEIVE_DATA_WAIT; 163 spi_bitcount = 7; 164 m_data_idx = 0; 165 } 166 else 167 { 168 spi_fsm = S_IDLE; 169 } 170 } 171 else 172 { 173 spi_bitcount = spi_bitcount - 1; 174 spi_shiftreg = spi_shiftreg << 1; 175 } 176 } 177 break; 178 ///////////////////////// 179 case S_RECEIVE_DATA_WAIT: 180 if (p_spi_clk.read() == 1 && spi_clk == 0) // rising edge 181 { 182 uint8_t s_data; 183 s_data = (m_databuf[0] << 1) | spi_mosi_previous; 184 m_databuf[0] = s_data; 185 if (spi_bitcount == 0) 186 { 161 187 #ifdef SOCLIB_MODULE_DEBUG 162 std::cout << name() << " S_RECEIVE_DATA_WAIT " << std::dec << (int)s_data << std::endl; 163 #endif 164 spi_bitcount = 7; 165 if (s_data == 0xfe) { // data start token 166 spi_fsm = S_RECEIVE_DATA; 167 m_data_idx = 1; 168 } else { 188 std::cout << name() << " S_RECEIVE_DATA_WAIT " << std::dec << (int)s_data << std::endl; 189 #endif 190 spi_bitcount = 7; 191 if (s_data == 0xfe) // data start token 192 { 193 spi_fsm = S_RECEIVE_DATA; 194 m_data_idx = 1; 195 } 196 else 197 { 169 198 #ifdef SOCLIB_MODULE_DEBUG 170 std::cout << name() << " S_RECEIVE_DATA_WAIT " << std::hex << (int)s_data << std::endl; 171 #endif 172 spi_fsm = S_RECEIVE_DATA_WAIT; 173 } 174 } else { 175 spi_bitcount = spi_bitcount - 1; 176 } 177 } 178 break; 179 case S_RECEIVE_DATA: 180 if (p_spi_clk.read() == 1 && spi_clk == 0) { 181 // rising edge 182 m_databuf[m_data_idx] = (m_databuf[m_data_idx] << 1) | spi_mosi_previous; 183 if (spi_bitcount == 0) { 184 m_data_idx++; 185 if (m_data_idx != m_datalen_rcv) { 186 spi_fsm = S_RECEIVE_DATA; 187 spi_bitcount = 7; 188 } else { 189 handle_sdmmc_write(command, args); 190 if (m_datalen_snd > 0) { 191 spi_bitcount = 0; // SEND_DATA will reset it 192 spi_fsm = S_SEND_DATA; 193 m_data_idx = 0; 194 } else { 195 spi_fsm = S_IDLE; 196 } 197 } 198 } else { 199 spi_bitcount = spi_bitcount - 1; 200 } 201 } 199 std::cout << name() << " S_RECEIVE_DATA_WAIT " << std::hex << (int)s_data << std::endl; 200 #endif 201 spi_fsm = S_RECEIVE_DATA_WAIT; 202 } 203 } 204 else 205 { 206 spi_bitcount = spi_bitcount - 1; 207 } 208 } 209 break; 210 //////////////////// 211 case S_RECEIVE_DATA: 212 if (p_spi_clk.read() == 1 && spi_clk == 0) // rising edge 213 { 214 m_databuf[m_data_idx] = (m_databuf[m_data_idx] << 1) | spi_mosi_previous; 215 if (spi_bitcount == 0) 216 { 217 m_data_idx++; 218 if (m_data_idx != m_datalen_rcv) 219 { 220 spi_fsm = S_RECEIVE_DATA; 221 spi_bitcount = 7; 222 } 223 else 224 { 225 handle_sdmmc_write(command, args); 226 if (m_datalen_snd > 0) 227 { 228 spi_bitcount = 0; // SEND_DATA will reset it 229 spi_fsm = S_SEND_DATA; 230 m_data_idx = 0; 231 } 232 else 233 { 234 spi_fsm = S_IDLE; 235 } 236 } 237 } 238 else 239 { 240 spi_bitcount = spi_bitcount - 1; 241 } 242 } 243 break; 244 } // end switch spi_fsm 245 246 //// now generate output signal 247 248 switch(spi_fsm) 249 { 250 case S_IDLE: 251 p_spi_miso = !p_spi_ss.read(); 252 break; 253 254 case S_SEND_DATA: 255 p_spi_miso = (spi_shiftreg & 0x80) != 0; 202 256 break; 257 258 default: 259 p_spi_miso = !p_spi_ss.read(); 260 break; 203 261 } 204 262 205 //// now genrate output signal 206 207 switch(spi_fsm) { 208 case S_IDLE: 209 p_spi_miso = !p_spi_ss.read(); 210 break; 211 case S_SEND_DATA: 212 p_spi_miso = (spi_shiftreg & 0x80) != 0; 213 break; 214 default: 215 p_spi_miso = !p_spi_ss.read(); 216 break; 217 } 263 //// sample inputs 218 264 spi_clk = p_spi_clk.read(); 219 265 spi_mosi_previous = p_spi_mosi; 266 220 267 } // end GenMealy() 221 268 222 269 223 ////////////////////// 270 //////////////////////////////////////////////////////// 224 271 void SdMMC::handle_sdmmc_cmd(uint8_t cmd, uint32_t data) 225 272 { 226 273 m_datalen_rcv = 0; 227 m_databuf[0] = 0x04; //illegal command228 m_datalen_snd = 1; 274 m_databuf[0] = 0x04; // default value : illegal command 275 m_datalen_snd = 1; // default value : 1 byte 229 276 230 277 if (m_sdstate == SD_IDLE) 231 278 m_databuf[0] |= 0x01; // idle 232 279 233 if ((cmd & 0x40) == 0) { 280 if ((cmd & 0x40) == 0) 281 { 234 282 //illegal command 235 283 return; 236 284 } 237 285 cmd &= 0x3f; 238 if (m_acmd) { 286 287 if (m_acmd) 288 { 239 289 #ifdef SOCLIB_MODULE_DEBUG0 240 290 std::cout << name() << " new acmd " << std::dec << (int)cmd << " args " << std::hex << data << " crc " << (int)cmdcrc << std::endl; 241 291 #endif 242 292 m_acmd = false; 243 switch (cmd) {244 case 41: 245 m_databuf[0] = 0x0; // card ready 246 m_datalen_snd = 1;247 m_sdstate = SD_READY;248 break;249 case 51:250 251 252 253 254 255 256 257 258 m_databuf[ 7] = 0; // vendor specific259 260 261 262 263 264 break;265 default:266 std::cout << name() << " unknown acmd " << std::dec267 << (int)cmd << std::endl;268 break; // return illegal command293 switch (cmd) 294 { 295 case 41: // ACD41 : Send OP_COND 296 m_databuf[0] = 0x0; // card ready 297 m_datalen_snd = 1; 298 m_sdstate = SD_READY; 299 break; 300 case 51: // send SCR 301 m_databuf[ 0] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1 302 m_databuf[ 1] = 0xfe; // data token 303 m_databuf[ 2] = 0x00; // SCR_STRUCTURE / SD_SPEC 304 m_databuf[ 3] = 0x05; // DATA_STAT_AFTER_ERASE, SD_SECURITY, SD_BUS_WIDTHS 305 m_databuf[ 4] = 0; // SD_SPEC3, EX_SECURITY, SD_SPEC4 306 m_databuf[ 5] = 0; // CMD_SUPPORT 307 m_databuf[ 6] = 0; // vendor specific 308 m_databuf[ 7] = 0; // vendor specific 309 m_databuf[ 8] = 0; // vendor specific 310 m_databuf[ 9] = 0; // vendor specific 311 m_databuf[10] = 0x0; // CRC16 312 m_databuf[11] = 0x0; // CRC16 313 m_datalen_snd = 12; 314 break; 315 default: 316 std::cout << name() << " unknown acmd " << std::dec 317 << (int)cmd << std::endl; 318 break; // return illegal command 269 319 } 270 } else { 320 } 321 else 322 { 271 323 #ifdef SOCLIB_MODULE_DEBUG0 272 std::cout << name() << " new cmd " << std::dec << (int)cmd << " args " << std::hex << data << " crc " << (int)cmdcrc << std::endl; 273 #endif 274 switch (cmd) { 275 case 0: 276 m_databuf[0] = 0x1; 277 m_datalen_snd = 1; 278 m_sdstate = SD_IDLE; 279 break; 280 case 8: 281 // reply with illegal command for now 282 break; 283 case 9: 284 { 285 // send CSD 286 // we use a block len of 1024 287 uint32_t csize = ((m_device_size + (512 * 1024) - 1) / (512 * 1024)) - 1; 288 m_databuf[ 0] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1 289 m_databuf[ 1] = 0xfe; // data token 290 m_databuf[ 2] = 0x00; // CSD_STRUCTURE 291 m_databuf[ 3] = 0xe; // TAAC 292 m_databuf[ 4] = 0; // NSAC 293 m_databuf[ 5] = 0x32; // TRAN_SPEED 294 m_databuf[ 6] = 0x5b; // CCC_H 295 m_databuf[ 7] = 0x5a; // CCC_L + READ_BL_LEN 296 m_databuf[ 8] = 0x80; // READ_BL_PARTIAL, R/W_BLK_MISALIGN, DSR_IMP 297 m_databuf[ 8] |= (csize >> 10) & 0x03; // CSIZE[12-11] 298 m_databuf[ 9] = (csize >> 2) & 0xff; // CSIZE[10-2] 299 m_databuf[10] = (csize << 6) & 0xc0; // CSIZE[1-0] 300 m_databuf[10] |= 0; // R_CURR_MIN, R_CURR_MAX 301 m_databuf[11] = 0x3; // W_CURR_MIN, W_CURR_MAX, CSIZE_MULT[2-1]; 302 m_databuf[12] = 0xff; // CSIZE_MULT[1], ERASE_BLK_EN, ERASE_SECTOR_SIZE[6-1] 303 m_databuf[13] = 0x80; // ERASE_SECTOR_SIZE[0]. WP_GRP_SIZE 304 m_databuf[14] = 0x0a; // WP_GRP_ENABLE, R2W_FACTOR, WRITE_BL_LEN[2-3] 305 m_databuf[15] = 0x40; // WRITE_BL_LEN[0-1], WR_BL_PARTIAL 306 m_databuf[16] = 0; // FILE_FORMAT 307 m_databuf[17] = 0x1; // CRC7 308 m_databuf[18] = 0x0; // CRC16 309 m_databuf[19] = 0x0; // CRC16 310 m_datalen_snd = 20; 311 break; 312 } 313 case 10: 314 // send CID 315 m_databuf[ 0] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1 316 m_databuf[ 1] = 0xfe; // data token 317 m_databuf[ 2] = 0xda; // MID 318 m_databuf[ 3] = 'P'; // OID 319 m_databuf[ 4] = '6'; // OID 320 m_databuf[ 5] = 's'; // PNM 321 m_databuf[ 6] = 'o'; // PNM 322 m_databuf[ 7] = 'c'; // PNM 323 m_databuf[ 8] = 's'; // PNM 324 m_databuf[ 9] = 'd'; // PNM 325 m_databuf[10] = 0x01; // PRV 326 m_databuf[11] = 0xde; // PSN 327 m_databuf[12] = 0xad; // PSN 328 m_databuf[13] = 0xbe; // PSN 329 m_databuf[14] = 0xef; // PSN 330 m_databuf[15] = 10; // MDT 331 m_databuf[16] = 13; // MDT 332 m_databuf[17] = 0x1; // CRC7 333 m_databuf[18] = 0x0; // CRC16 334 m_databuf[19] = 0x0; // CRC16 335 m_datalen_snd = 20; 336 break; 337 case 16: 338 // set block size 339 if (m_sdstate != SD_IDLE && data == 512) { 340 m_databuf[0] = 0x00; 341 m_datalen_snd = 1; 342 } // else illegal command 343 break; 344 case 17: 345 { 346 int ret; 347 // read data block 348 if (m_sdstate == SD_IDLE) { 349 // return illegal command 350 return; 351 } 352 if (data >= m_device_size) { 353 std::cerr << name() << " read: request " << data 354 << " past end of file " << m_device_size << std::endl; 355 m_databuf[0] = 0x00; // R1 OK 356 m_databuf[1] = 0x08; // error tocken "out of range" 357 m_datalen_snd = 2; 358 return; 359 } 360 do { 361 if (lseek(m_fd, data, SEEK_SET) < 0) { 362 std::cerr << name() << " lseek: " << 363 strerror(errno) << std::endl; 364 m_databuf[0] = 0x00; // R1 OK 365 m_databuf[1] = 0x02; // error tocken "CC err" 366 m_datalen_snd = 2; 367 return; 368 } 369 ret = read(m_fd, &m_databuf[2], 512); 370 } while (ret < 0 && errno == EINTR); 371 if (ret < 0) { 372 std::cerr << name() << " read: " << 373 strerror(errno) << std::endl; 374 m_databuf[0] = 0x00; // R1 OK 375 m_databuf[1] = 0x04; // error tocken "card ECC failed" 376 m_datalen_snd = 2; 377 return; 378 } 379 m_databuf[514] = m_databuf[515] = 0; // XXX CRC 380 m_databuf[0] = 0x0; // R1 381 m_databuf[1] = 0xfe; // start block tocken 382 m_datalen_snd = 516; 383 break; 384 } 385 case 24: 386 { 387 // write data block 388 if (m_sdstate == SD_IDLE) { 389 // return illegal command 390 return; 391 } 324 std::cout << name() << " new cmd " << std::dec << (int)cmd << " args " << std::hex << data << " crc " << (int)cmdcrc << std::endl; 325 #endif 326 switch (cmd) 327 { 328 /////// 329 case 0: // CMD0 330 m_databuf[0] = 0x1; 331 m_datalen_snd = 1; 332 m_sdstate = SD_IDLE; 333 break; 334 /////// 335 case 8: // CMD8 336 // reply with illegal command for now 337 break; 338 /////// 339 case 9: // CMD9 : send CSD 340 { 341 // we use a block len of 1024 342 uint32_t csize = ((m_device_size + (512 * 1024) - 1) / (512 * 1024)) - 1; 343 m_databuf[ 0] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1 344 m_databuf[ 1] = 0xfe; // data token 345 m_databuf[ 2] = 0x00; // CSD_STRUCTURE 346 m_databuf[ 3] = 0xe; // TAAC 347 m_databuf[ 4] = 0; // NSAC 348 m_databuf[ 5] = 0x32; // TRAN_SPEED 349 m_databuf[ 6] = 0x5b; // CCC_H 350 m_databuf[ 7] = 0x5a; // CCC_L + READ_BL_LEN 351 m_databuf[ 8] = 0x80; // READ_BL_PARTIAL, R/W_BLK_MISALIGN, DSR_IMP 352 m_databuf[ 8] |= (csize >> 10) & 0x03; // CSIZE[12-11] 353 m_databuf[ 9] = (csize >> 2) & 0xff; // CSIZE[10-2] 354 m_databuf[10] = (csize << 6) & 0xc0; // CSIZE[1-0] 355 m_databuf[10] |= 0; // R_CURR_MIN, R_CURR_MAX 356 m_databuf[11] = 0x3; // W_CURR_MIN, W_CURR_MAX, CSIZE_MULT[2-1]; 357 m_databuf[12] = 0xff; // CSIZE_MULT[1], ERASE_BLK_EN, ERASE_SECTOR_SIZE[6-1] 358 m_databuf[13] = 0x80; // ERASE_SECTOR_SIZE[0]. WP_GRP_SIZE 359 m_databuf[14] = 0x0a; // WP_GRP_ENABLE, R2W_FACTOR, WRITE_BL_LEN[2-3] 360 m_databuf[15] = 0x40; // WRITE_BL_LEN[0-1], WR_BL_PARTIAL 361 m_databuf[16] = 0; // FILE_FORMAT 362 m_databuf[17] = 0x1; // CRC7 363 m_databuf[18] = 0x0; // CRC16 364 m_databuf[19] = 0x0; // CRC16 365 m_datalen_snd = 20; 366 } 367 break; 368 //////// 369 case 10: // CMD10 : send CID 370 m_databuf[ 0] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1 371 m_databuf[ 1] = 0xfe; // data token 372 m_databuf[ 2] = 0xda; // MID 373 m_databuf[ 3] = 'P'; // OID 374 m_databuf[ 4] = '6'; // OID 375 m_databuf[ 5] = 's'; // PNM 376 m_databuf[ 6] = 'o'; // PNM 377 m_databuf[ 7] = 'c'; // PNM 378 m_databuf[ 8] = 's'; // PNM 379 m_databuf[ 9] = 'd'; // PNM 380 m_databuf[10] = 0x01; // PRV 381 m_databuf[11] = 0xde; // PSN 382 m_databuf[12] = 0xad; // PSN 383 m_databuf[13] = 0xbe; // PSN 384 m_databuf[14] = 0xef; // PSN 385 m_databuf[15] = 10; // MDT 386 m_databuf[16] = 13; // MDT 387 m_databuf[17] = 0x1; // CRC7 388 m_databuf[18] = 0x0; // CRC16 389 m_databuf[19] = 0x0; // CRC16 390 m_datalen_snd = 20; 391 break; 392 //////// 393 case 16: // CMD16 : set block size 394 if (m_sdstate != SD_IDLE && data == 512) 395 { 396 m_databuf[0] = 0x00; 397 m_datalen_snd = 1; 398 } // else illegal command 399 break; 400 //////// 401 case 17: // CMD17 : read data block 402 { 403 int ret; 404 if (m_sdstate == SD_IDLE) // return illegal command 405 { 406 return; 407 } 408 if (data >= m_device_size) // return "out of range" 409 { 410 std::cerr << name() << " read: request " << data 411 << " past end of file " << m_device_size << std::endl; 412 m_databuf[0] = 0x00; // R1 OK 413 m_databuf[1] = 0x08; // error tocken "out of range" 414 m_datalen_snd = 2; 415 return; 416 } 417 do 418 { 419 if (lseek(m_fd, data, SEEK_SET) < 0) 420 { 421 std::cerr << name() << " lseek: " << 422 strerror(errno) << std::endl; 423 m_databuf[0] = 0x00; // R1 OK 424 m_databuf[1] = 0x02; // error tocken "CC err" 425 m_datalen_snd = 2; 426 return; 427 } 428 ret = read(m_fd, &m_databuf[2], 512); 429 } while (ret < 0 && errno == EINTR); 430 if (ret < 0) 431 { 432 std::cerr << name() << " read: " << strerror(errno) << std::endl; 433 m_databuf[0] = 0x00; // R1 OK 434 m_databuf[1] = 0x04; // error tocken "card ECC failed" 435 m_datalen_snd = 2; 436 return; 437 } 438 m_databuf[514] = m_databuf[515] = 0; // XXX CRC 439 m_databuf[0] = 0x0; // R1 440 m_databuf[1] = 0xfe; // start block tocken 441 m_datalen_snd = 516; 442 } 443 break; 444 //////// 445 case 24: // CMD 24 : write data block 446 { 447 if (m_sdstate == SD_IDLE) // return illegal command 448 { 449 return; 450 } 392 451 #ifdef SOCLIB_MODULE_DEBUG 393 452 std::cout << name() << " new cmd write " << std::dec << (int)cmd << " args " << std::hex << data << std::endl; 394 453 #endif 395 396 397 398 break;399 }400 case 55: 401 //app-specific command follow402 403 404 405 406 case 58: 407 //send OCR408 m_databuf[4] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1409 m_databuf[3] = 0x80; // power up complete, SDSC410 m_databuf[2] = 0xff; // all voltages supported411 m_databuf[1] = 0x00;412 m_databuf[0] = 0x00;413 m_datalen_snd = 5;414 415 default: 416 std::cout << name() << " unknown cmd " << std::dec 417 << (int)cmd << std::endl;418 break; // return illegal command 454 m_databuf[0] = 0x0; // R1 455 m_datalen_snd = 1; 456 m_datalen_rcv = 512 + 2 + 1; // data + tocken + CRC 457 } 458 break; 459 //////// 460 case 55: // CMD55 : app-specific command follow 461 m_acmd = true; 462 m_databuf[0] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; 463 m_datalen_snd = 1; 464 break; 465 //////// 466 case 58: // CMD 58 : send OCR 467 m_databuf[4] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1 468 m_databuf[3] = 0x80; // power up complete, SDSC 469 m_databuf[2] = 0xff; // all voltages supported 470 m_databuf[1] = 0x00; 471 m_databuf[0] = 0x00; 472 m_datalen_snd = 5; 473 break; 474 //////// 475 default: // return illegal command 476 std::cout << name() << " unknown cmd " << std::dec << (int)cmd << std::endl; 477 break; 419 478 } 420 479 } 421 } 422 480 } // end handle_sdmmc_cmd() 481 482 /////////////////////////////////////////////////////////// 423 483 void SdMMC::handle_sdmmc_write(uint8_t cmd, uint32_t data) 424 484 { … … 428 488 std::cout << name() << " cmd write " << std::dec << (int)cmd << " args " << std::hex << data << std::endl; 429 489 #endif 430 switch(cmd) { 431 case 24: 432 { 433 int ret; 434 // write data block 435 assert(m_sdstate != SD_IDLE && "can't write in idle state"); 436 if (data >= m_device_size) { 437 std::cerr << name() << " write: request " << data 438 << " past end of file " << m_device_size << std::endl; 439 m_databuf[0] = 0xd; // write error 440 m_datalen_snd = 1; 441 return; 442 } 443 do { 444 if (lseek(m_fd, data, SEEK_SET) < 0) { 445 std::cerr << name() << " lseek: " << 446 strerror(errno) << std::endl; 447 m_databuf[0] = 0xd; // write error 448 m_datalen_snd = 1; 449 return; 450 } 451 ret = write(m_fd, &m_databuf[1], 512); 452 } while (ret < 0 && errno == EINTR); 453 if (ret < 0) { 454 std::cerr << name() << " write: " << 455 strerror(errno) << std::endl; 456 m_databuf[0] = 0xd; // write error 457 m_datalen_snd = 1; 458 return; 459 } 460 m_databuf[0] = 0x5; // write complete 461 m_databuf[1] = 0x0; // busy 462 m_datalen_snd = 2; 490 switch(cmd) 491 { 492 case 24: // CMD24 : write data block 493 { 494 int ret; 495 assert(m_sdstate != SD_IDLE && "can't write in idle state"); 496 if (data >= m_device_size) 497 { 498 std::cerr << name() << " write: request " << data 499 << " past end of file " << m_device_size << std::endl; 500 m_databuf[0] = 0xd; // write error 501 m_datalen_snd = 1; 502 return; 503 } 504 do 505 { 506 if (lseek(m_fd, data, SEEK_SET) < 0) 507 { 508 std::cerr << name() << " lseek: " << strerror(errno) << std::endl; 509 m_databuf[0] = 0xd; // write error 510 m_datalen_snd = 1; 511 return; 512 } 513 ret = write(m_fd, &m_databuf[1], 512); 514 } 515 while (ret < 0 && errno == EINTR); 516 if (ret < 0) 517 { 518 std::cerr << name() << " write: " << strerror(errno) << std::endl; 519 m_databuf[0] = 0xd; // write error 520 m_datalen_snd = 1; 521 return; 522 } 523 m_databuf[0] = 0x5; // write complete 524 m_databuf[1] = 0x0; // busy 525 m_datalen_snd = 2; 526 } 463 527 break; 464 }465 528 default: 466 std::cerr << name() << " unkown write cmd " << std::dec << 467 (int)cmd << std::endl; 468 m_databuf[0] = 0xd; // write error; 469 m_datalen_snd = 1; 529 { 530 std::cerr << name() << " unkown write cmd " << std::dec << (int)cmd << std::endl; 531 m_databuf[0] = 0xd; // write error; 532 m_datalen_snd = 1; 533 } 470 534 } 471 535 return; 472 536 } 473 537 474 ////////////////////////////////////////////////////////////// ////////////////538 ////////////////////////////////////////////////////////////// 475 539 SdMMC::SdMMC( sc_core::sc_module_name name, 476 477 540 const std::string &filename, 541 const uint32_t latency) 478 542 479 543 : caba::BaseModule(name), … … 516 580 const char* spi_str[] = 517 581 { 518 519 520 521 522 523 524 525 526 582 "S_IDLE", 583 "S_RECEIVE_CMD", 584 "S_RECEIVE_ARGS_START", 585 "S_RECEIVE_ARGS", 586 "S_RECEIVE_CRC", 587 "S_RECEIVE_DATA_START", 588 "S_RECEIVE_DATA", 589 "S_SEND_DATA", 590 "S_NOP", 527 591 }; 528 592 if (spi_clk != p_spi_clk.read()) { -
trunk/modules/vci_block_device_tsar/caba/source/src/vci_block_device_tsar.cpp
r1017 r1052 875 875 const char* target_str[] = 876 876 { 877 "TGT_IDLE", 878 "TGT_WRITE_BUFFER", 879 "TGT_READ_BUFFER", 880 "TGT_WRITE_BUFFER_EXT", 881 "TGT_READ_BUFFER_EXT", 882 "TGT_WRITE_COUNT", 883 "TGT_READ_COUNT", 884 "TGT_WRITE_LBA", 885 "TGT_READ_LBA", 886 "TGT_WRITE_ OP",887 "TGT_READ_STATUS", 888 "TGT_WRITE_IRQEN", 889 "TGT_READ_IRQEN", 890 "TGT_ READ_SIZE",891 "TGT_READ_ BLOCK",892 "TGT_READ_ ERROR",893 "TGT_ WRITE_ERROR ",877 "TGT_IDLE", // 0 878 "TGT_WRITE_BUFFER", // 1 879 "TGT_READ_BUFFER", // 2 880 "TGT_WRITE_BUFFER_EXT", // 3 881 "TGT_READ_BUFFER_EXT", // 4 882 "TGT_WRITE_COUNT", // 5 883 "TGT_READ_COUNT", // 6 884 "TGT_WRITE_LBA", // 7 885 "TGT_READ_LBA", // 8 886 "TGT_WRITE_STATUS", // 9 887 "TGT_READ_STATUS", // 10 888 "TGT_WRITE_IRQEN", // 11 889 "TGT_READ_IRQEN", // 12 890 "TGT_WRITE_OP", // 13 891 "TGT_READ_SIZE", // 14 892 "TGT_READ_BLOCK", // 15 893 "TGT_ERROR", // 16 894 894 }; 895 895 -
trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
r1039 r1052 4761 4761 { 4762 4762 std::cout << " <MEMC " << name() << " XRAM_RSP_TRT_COPY>" 4763 << " Select a victim slot: " 4764 << " way = " << std::dec << way 4763 << " Select a victim line: " << std::hex 4764 << " paddr = " << (r_xram_rsp_victim_nline.read() * m_words * 4) 4765 << " / way = " << std::dec << way 4765 4766 << " / set = " << set 4766 4767 << " / inval_required = " << inval << std::endl; -
trunk/modules/vci_mem_cache/include/soclib/mem_cache.h
r912 r1052 178 178 enum SoclibMemCacheRerrorRegs 179 179 { 180 MEMC_RERROR_ADDR_LO = 0,181 MEMC_RERROR_ADDR_HI ,182 MEMC_RERROR_SRCID ,183 MEMC_RERROR_IRQ_RESET ,184 MEMC_RERROR_IRQ_ENABLE 180 MEMC_RERROR_ADDR_LO = 0, 181 MEMC_RERROR_ADDR_HI = 1, 182 MEMC_RERROR_SRCID = 2, 183 MEMC_RERROR_IRQ_RESET = 3, 184 MEMC_RERROR_IRQ_ENABLE = 4, 185 185 }; 186 186 -
trunk/modules/vci_spi/caba/source/include/vci_spi.h
r595 r1052 68 68 69 69 // Registers 70 sc_signal<int> 71 sc_signal<int> 72 sc_signal<int> r_spi_fsm; // spi engine state73 sc_signal<uint64_t> 74 sc_signal<uint32_t> 75 sc_signal<uint8_t> r_ss;// SPI slave select76 sc_signal<bool> r_ctrl_cpol;// clock polarity77 sc_signal<bool> r_ctrl_cpha;// clock phase78 sc_signal<bool> r_ctrl_ie;// interrupt enable79 sc_signal<uint8_t> r_ctrl_char_len;// number of bits in xfer80 sc_signal<uint64_t> r_buf_address;// memory buffer address81 sc_signal<uint32_t> r_dma_count;// DMA burst count82 sc_signal<bool> r_read; // DMA read/write83 84 sc_signal<uint32_t> r_burst_word;// DMA burst word count85 sc_signal<bool> r_dma_error;// DMA error86 87 sc_signal<bool> r_spi_bsy;// SPI shifter busy88 sc_signal<uint32_t> 89 sc_signal<uint32_t> 90 sc_signal<uint32_t> 70 sc_signal<int> r_target_fsm; // target fsm state register 71 sc_signal<int> r_initiator_fsm; // initiator fsm state register 72 sc_signal<int> r_spi_fsm; // spi engine state 73 sc_signal<uint64_t> r_txrx[2]; // data in/out 74 sc_signal<uint32_t> r_divider; // SPI clk divider 75 sc_signal<uint8_t> r_ss; // SPI slave select 76 sc_signal<bool> r_ctrl_cpol; // clock polarity 77 sc_signal<bool> r_ctrl_cpha; // clock phase 78 sc_signal<bool> r_ctrl_ie; // interrupt enable 79 sc_signal<uint8_t> r_ctrl_char_len; // number of bits in xfer 80 sc_signal<uint64_t> r_buf_address; // memory buffer address 81 sc_signal<uint32_t> r_dma_count; // DMA burst count 82 sc_signal<bool> r_read; // DMA read/write 83 84 sc_signal<uint32_t> r_burst_word; // DMA burst word count 85 sc_signal<bool> r_dma_error; // DMA error 86 87 sc_signal<bool> r_spi_bsy; // SPI shifter busy 88 sc_signal<uint32_t> r_spi_bit_count; 89 sc_signal<uint32_t> r_spi_word_count; 90 sc_signal<uint32_t> r_spi_clk_counter; 91 91 sc_signal<bool> r_spi_clk; 92 92 sc_signal<bool> r_spi_clk_previous; … … 189 189 soclib::caba::VciInitiator<vci_param> p_vci_initiator; 190 190 soclib::caba::VciTarget<vci_param> p_vci_target; 191 191 192 sc_out<bool> p_spi_ss; 192 193 sc_out<bool> p_spi_clk; -
trunk/modules/vci_spi/caba/source/src/vci_spi.cpp
r595 r1052 46 46 47 47 bool s_dma_bsy = (r_initiator_fsm != M_IDLE); 48 48 49 if(p_resetn.read() == false) 49 50 { 50 r_initiator_fsm = M_IDLE;51 r_target_fsm = T_IDLE;52 r_spi_fsm= S_IDLE;53 r_ss = 0;54 r_divider= 0xffff;55 r_ctrl_char_len = 0;56 r_ctrl_ie= false;57 r_ctrl_cpol = false;58 r_ctrl_cpha = false;59 r_spi_bsy = false;60 r_dma_count = 0;61 r_dma_error = false;62 r_spi_clk_counter = 0xffff;63 r_spi_clk= 0;64 r_spi_done = false;65 66 r_irq= false;67 r_read= false;68 69 r_dma_fifo_read.init();70 r_dma_fifo_write.init();71 72 return;51 r_initiator_fsm = M_IDLE; 52 r_target_fsm = T_IDLE; 53 r_spi_fsm = S_IDLE; 54 r_ss = 0; 55 r_divider = 0xffff; 56 r_ctrl_char_len = 0; 57 r_ctrl_ie = false; 58 r_ctrl_cpol = false; 59 r_ctrl_cpha = false; 60 r_spi_bsy = false; 61 r_dma_count = 0; 62 r_dma_error = false; 63 r_spi_clk_counter = 0xffff; 64 r_spi_clk = 0; 65 r_spi_done = false; 66 67 r_irq = false; 68 r_read = false; 69 70 r_dma_fifo_read.init(); 71 r_dma_fifo_write.init(); 72 73 return; 73 74 } 74 75 75 76 ////////////////////////////////////////////////////////////////////////////// 76 // The Target FSM controls the following registers: 77 // r_target_fsm, r_irq_enable, r_nblocks, r_buf adress, r_lba, r_go, r_read 77 // The Target FSM handles the software access to addressable registers 78 78 ////////////////////////////////////////////////////////////////////////////// 79 79 … … 81 81 r_spi_bsy = false; 82 82 83 switch(r_target_fsm) { 83 switch(r_target_fsm) 84 { 84 85 //////////// 85 86 case T_IDLE: 86 87 { 87 88 89 r_srcid = p_vci_target.srcid.read();90 r_trdid = p_vci_target.trdid.read();91 r_pktid = p_vci_target.pktid.read();92 uint32_t wdata = p_vci_target.wdata.read();93 sc_dt::sc_uint<vci_param::N> address = p_vci_target.address.read();94 95 bool found = false;96 std::list<soclib::common::Segment>::iterator seg;97 for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ )98 {99 if ( seg->contains(address) ) found = true;100 }88 if ( p_vci_target.cmdval.read() ) 89 { 90 r_srcid = p_vci_target.srcid.read(); 91 r_trdid = p_vci_target.trdid.read(); 92 r_pktid = p_vci_target.pktid.read(); 93 uint32_t wdata = p_vci_target.wdata.read(); 94 sc_dt::sc_uint<vci_param::N> address = p_vci_target.address.read(); 95 96 bool found = false; 97 std::list<soclib::common::Segment>::iterator seg; 98 for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) 99 { 100 if ( seg->contains(address) ) found = true; 101 } 101 102 102 103 if (not found) { 104 if (p_vci_target.cmd.read() == vci_param::CMD_WRITE) 105 r_target_fsm = T_ERROR_WRITE; 106 else 103 if (not found) 104 { 105 if (p_vci_target.cmd.read() == vci_param::CMD_WRITE) 106 r_target_fsm = T_ERROR_WRITE; 107 else 108 r_target_fsm = T_ERROR_READ; 109 } 110 else if (p_vci_target.cmd.read() != vci_param::CMD_READ && 111 p_vci_target.cmd.read() != vci_param::CMD_WRITE) 112 { 107 113 r_target_fsm = T_ERROR_READ; 108 } else if (p_vci_target.cmd.read() != vci_param::CMD_READ && 109 p_vci_target.cmd.read() != vci_param::CMD_WRITE) { 110 r_target_fsm = T_ERROR_READ; 111 } else { 112 bool write = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) & !r_spi_bsy &!s_dma_bsy; 113 uint32_t cell = (uint32_t)((address & 0x3F)>>2); 114 switch(cell) { 115 case SPI_DATA_TXRX0: 116 r_rdata = r_txrx[0] & (uint64_t)0x00000000ffffffffULL; 117 if (write) { 118 r_txrx[0] = 119 (r_txrx[0] & (uint64_t)0xffffffff00000000ULL) | 120 ((uint64_t)wdata); 121 } 122 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 123 break; 124 case SPI_DATA_TXRX1: 125 r_rdata = r_txrx[0] >> 32; 126 if (write) { 127 r_txrx[0] = 128 (r_txrx[0] & (uint64_t)0x00000000ffffffffULL) | 129 ((uint64_t)wdata << 32); 130 } 131 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 132 break; 133 case SPI_DATA_TXRX2: 134 r_rdata = r_txrx[1] & (uint64_t)0x00000000ffffffffULL; 135 if (write) { 136 r_txrx[1] = 137 (r_txrx[1] & (uint64_t)0xffffffff00000000ULL) | 138 ((uint64_t)wdata); 139 } 140 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 141 break; 142 case SPI_DATA_TXRX3: 143 r_rdata = r_txrx[1] >> 32; 144 if (write) { 145 r_txrx[1] = 146 (r_txrx[1] & (uint64_t)0x00000000ffffffffULL) | 147 ((uint64_t)wdata << 32); 148 } 149 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 150 break; 151 case SPI_CTRL: 152 { 153 uint32_t data = 0; 154 if (r_ctrl_cpol.read()) 155 data |= SPI_CTRL_CPOL; 156 if (r_ctrl_cpha.read()) 157 data |= SPI_CTRL_CPHA; 158 if (r_ctrl_ie.read()) 159 data |= SPI_CTRL_IE_EN; 160 if (r_spi_bsy.read()) 161 data |= SPI_CTRL_GO_BSY; 162 if (s_dma_bsy) 163 data |= SPI_CTRL_DMA_BSY; 164 if (r_dma_error) 165 data |= SPI_CTRL_DMA_ERR; 166 data |= (uint32_t)r_ctrl_char_len.read(); 167 r_rdata = data; 168 if (write) { 169 r_ctrl_cpol = ((wdata & SPI_CTRL_CPOL) != 0); 170 r_ctrl_cpha = ((wdata & SPI_CTRL_CPHA) != 0); 171 r_ctrl_ie = ((wdata & SPI_CTRL_IE_EN) != 0); 172 if (wdata & SPI_CTRL_GO_BSY) 173 r_spi_bsy = true; 174 r_ctrl_char_len = (wdata & SPI_CTRL_CHAR_LEN_MASK); 114 } 115 else 116 { 117 bool write = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) 118 & !r_spi_bsy & !s_dma_bsy; 119 uint32_t cell = (uint32_t)((address & 0x3F)>>2); 120 switch(cell) 121 { 122 case SPI_DATA_TXRX0: 123 r_rdata = r_txrx[0] & (uint64_t)0x00000000ffffffffULL; 124 if (write) 125 { 126 r_txrx[0] = (r_txrx[0] & (uint64_t)0xffffffff00000000ULL) | 127 ((uint64_t)wdata); 128 } 129 r_target_fsm = (p_vci_target.cmd.read() 130 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 131 break; 132 case SPI_DATA_TXRX1: 133 r_rdata = r_txrx[0] >> 32; 134 if (write) 135 { 136 r_txrx[0] = (r_txrx[0] & (uint64_t)0x00000000ffffffffULL) | 137 ((uint64_t)wdata << 32); 138 } 139 r_target_fsm = (p_vci_target.cmd.read() 140 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 141 break; 142 case SPI_DATA_TXRX2: 143 r_rdata = r_txrx[1] & (uint64_t)0x00000000ffffffffULL; 144 if (write) 145 { 146 r_txrx[1] = (r_txrx[1] & (uint64_t)0xffffffff00000000ULL) | 147 ((uint64_t)wdata); 148 } 149 r_target_fsm = (p_vci_target.cmd.read() 150 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 151 break; 152 case SPI_DATA_TXRX3: 153 r_rdata = r_txrx[1] >> 32; 154 if (write) 155 { 156 r_txrx[1] = (r_txrx[1] & (uint64_t)0x00000000ffffffffULL) | 157 ((uint64_t)wdata << 32); 158 } 159 r_target_fsm = (p_vci_target.cmd.read() 160 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 161 break; 162 case SPI_CTRL: 163 uint32_t data = 0; 164 if (r_ctrl_cpol.read()) data |= SPI_CTRL_CPOL; 165 if (r_ctrl_cpha.read()) data |= SPI_CTRL_CPHA; 166 if (r_ctrl_ie.read()) data |= SPI_CTRL_IE_EN; 167 if (r_spi_bsy.read()) data |= SPI_CTRL_GO_BSY; 168 if (s_dma_bsy) data |= SPI_CTRL_DMA_BSY; 169 if (r_dma_error) data |= SPI_CTRL_DMA_ERR; 170 data |= (uint32_t)r_ctrl_char_len.read(); 171 r_rdata = data; 172 if (write) 173 { 174 r_ctrl_cpol = ((wdata & SPI_CTRL_CPOL) != 0); 175 r_ctrl_cpha = ((wdata & SPI_CTRL_CPHA) != 0); 176 r_ctrl_ie = ((wdata & SPI_CTRL_IE_EN) != 0); 177 if (wdata & SPI_CTRL_GO_BSY) r_spi_bsy = true; 178 r_ctrl_char_len = (wdata & SPI_CTRL_CHAR_LEN_MASK); 179 175 180 #ifdef SOCLIB_MODULE_DEBUG 176 181 if ((wdata & SPI_CTRL_GO_BSY) != 0) { … … 178 183 } 179 184 #endif 180 } else { 181 r_irq = false; 182 } 183 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 184 break; 185 } 186 case SPI_DIVIDER: 187 r_rdata = r_divider.read(); 188 if (write) { 185 } 186 else 187 { 188 r_irq = false; 189 } 190 r_target_fsm = (p_vci_target.cmd.read() 191 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 192 break; 193 case SPI_DIVIDER: 194 r_rdata = r_divider.read(); 195 if (write) r_divider = wdata; 196 189 197 #ifdef SOCLIB_MODULE_DEBUG 190 198 std::cout << name() << " divider set to " << std::dec << wdata << std::endl; 191 199 #endif 192 r_divider = wdata;193 } 194 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;195 break;196 case SPI_SS:197 r_rdata = r_ss.read();198 if (write) {199 r_ss = wdata;200 }201 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;202 break;203 case SPI_DMA_BASE:204 r_rdata = r_buf_address.read();205 if (write) {206 r_buf_address = (r_buf_address & (uint64_t)0xffffffff00000000) | wdata;207 }208 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 209 break;210 case SPI_DMA_BASEH:211 r_rdata = r_buf_address >> 32;212 if (write) {213 r_buf_address = (r_buf_address & (uint64_t)0x00000000ffffffff) | ((uint64_t)wdata << 32);214 }215 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;216 break;217 case SPI_DMA_COUNT:218 r_rdata = (r_dma_count.read() << m_byte2burst_shift) | 219 r_read;220 if (write) { 221 r_read = (wdata & 0x1);222 r_dma_count = wdata >> m_byte2burst_shift;223 r_ctrl_char_len = vci_param::B * 8;224 } 225 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;226 break;227 default:228 r_target_fsm = (p_vci_target.cmd.read()== vci_param::CMD_WRITE) ? T_ERROR_WRITE : T_ERROR_READ;229 break;230 }231 }232 }233 break;200 r_target_fsm = (p_vci_target.cmd.read() 201 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 202 break; 203 case SPI_SS: 204 r_rdata = r_ss.read(); 205 if (write) r_ss = wdata; 206 r_target_fsm = (p_vci_target.cmd.read() 207 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 208 break; 209 case SPI_DMA_BASE: 210 r_rdata = r_buf_address.read(); 211 if (write) r_buf_address = (r_buf_address.read & 212 (uint64_t)0xffffffff00000000) | wdata; 213 r_target_fsm = (p_vci_target.cmd.read() 214 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 215 break; 216 case SPI_DMA_BASEH: 217 r_rdata = r_buf_address >> 32; 218 if (write) r_buf_address = (r_buf_address & 219 (uint64_t)0x00000000ffffffff) | ((uint64_t)wdata << 32); 220 r_target_fsm = (p_vci_target.cmd.read() 221 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 222 break; 223 case SPI_DMA_COUNT: 224 r_rdata = (r_dma_count.read() << m_byte2burst_shift) | r_read; 225 if (write) 226 { 227 r_read = (wdata & 0x1); 228 r_dma_count = wdata >> m_byte2burst_shift; 229 r_ctrl_char_len = vci_param::B * 8; 230 } 231 r_target_fsm = (p_vci_target.cmd.read() 232 == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 233 break; 234 default: 235 r_target_fsm = (p_vci_target.cmd.read() 236 == vci_param::CMD_WRITE) ? T_ERROR_WRITE : T_ERROR_READ; 237 break; 238 } 239 } 240 } 241 break; 234 242 } 235 243 //////////////////// … … 238 246 case T_ERROR_READ: 239 247 case T_ERROR_WRITE: 240 if (p_vci_target.rspack.read() ){241 r_target_fsm = T_IDLE;242 }243 break; 248 { 249 if (p_vci_target.rspack.read() ) r_target_fsm = T_IDLE; 250 break; 251 } 244 252 } // end switch target fsm 245 253 … … 252 260 if (r_spi_bsy == false) 253 261 r_spi_done = false; 254 switch (r_spi_fsm) { 255 case S_IDLE: 256 r_spi_clk_counter = r_divider.read(); 257 r_spi_clk = 0; 258 r_spi_clk_previous = r_ctrl_cpha; 259 r_spi_clk_ignore = r_ctrl_cpha; 260 r_spi_bit_count = r_ctrl_char_len; 261 if (r_dma_count != 0) { 262 if (r_read.read()) 263 r_spi_fsm = S_DMA_SEND_START; 264 else 265 r_spi_fsm = S_DMA_RECEIVE; 266 } else if (r_spi_bsy.read() && !r_spi_done.read()) { 262 263 switch (r_spi_fsm) 264 { 265 //////////// 266 case S_IDLE: // polling the (r_dma_count/r_read) registers for dma request 267 // polling the r_spi_bsy register for config request 268 { 269 r_spi_clk_counter = r_divider.read(); 270 r_spi_clk = 0; 271 r_spi_clk_previous = r_ctrl_cpha; 272 r_spi_clk_ignore = r_ctrl_cpha; 273 r_spi_bit_count = r_ctrl_char_len; 274 if (r_dma_count != 0) 275 { 276 if (r_read.read()) r_spi_fsm = S_DMA_SEND_START; 277 else r_spi_fsm = S_DMA_RECEIVE; 278 } 279 else if (r_spi_bsy.read() && !r_spi_done.read()) 280 { 281 r_spi_fsm = S_XMIT; 282 r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) 283 & (uint64_t)0x0000000000000001ULL; 284 } 285 break; 286 } 287 /////////////////// 288 case S_DMA_RECEIVE: // copy one word from fifo_write to shift register 289 { 290 r_spi_clk_counter = r_divider.read(); 291 r_spi_clk = 0; 292 r_spi_clk_previous = r_ctrl_cpha; 293 r_spi_clk_ignore = r_ctrl_cpha; 294 r_spi_bit_count = r_ctrl_char_len; 295 if (r_initiator_fsm != M_WRITE_RSP || !p_vci_initiator.rspval.read()) 296 { 297 if (r_dma_fifo_write.rok()) 298 { 299 typename vci_param::data_t v = r_dma_fifo_write.read(); 300 r_dma_fifo_write.simple_get(); 301 r_txrx[0] = v; 302 r_spi_out = (v >> ((vci_param::B * 8) - 1)) & 0x1; 303 r_spi_fsm = S_XMIT; 304 } 305 else if (r_initiator_fsm == M_WRITE_END) 306 { 307 r_spi_fsm = S_IDLE; 308 } 309 } 310 break; 311 } 312 ////////////////////// 313 case S_DMA_SEND_START: 314 { 315 r_spi_word_count = (r_dma_count << (m_byte2burst_shift - 2)) - 1; 316 r_spi_out = 1; 317 r_txrx[0] = 0xffffffff; 267 318 r_spi_fsm = S_XMIT; 268 r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL; 269 } 270 break; 271 case S_DMA_RECEIVE: 272 { 273 r_spi_clk_counter = r_divider.read(); 274 r_spi_clk = 0; 275 r_spi_clk_previous = r_ctrl_cpha; 276 r_spi_clk_ignore = r_ctrl_cpha; 277 r_spi_bit_count = r_ctrl_char_len; 278 if (r_initiator_fsm != M_WRITE_RSP || !p_vci_initiator.rspval.read()) { 279 if (r_dma_fifo_write.rok()) { 280 typename vci_param::data_t v = r_dma_fifo_write.read(); 281 r_dma_fifo_write.simple_get(); 282 r_txrx[0] = v; 283 r_spi_out = (v >> ((vci_param::B * 8) - 1)) & 0x1; 284 r_spi_fsm = S_XMIT; 285 } else if (r_initiator_fsm == M_WRITE_END) { 286 r_spi_fsm = S_IDLE; 287 } 288 } 289 break; 290 } 291 case S_DMA_SEND_START: 292 r_spi_word_count = (r_dma_count << (m_byte2burst_shift - 2)) - 1; 293 r_spi_out = 1; 294 r_txrx[0] = 0xffffffff; 295 r_spi_fsm = S_XMIT; 296 break; 319 break; 320 } 321 //////////////// 297 322 case S_DMA_SEND: 298 r_spi_out = 1; 299 r_spi_clk_counter = r_divider.read(); 300 r_spi_clk = 0; 301 r_spi_clk_previous = r_ctrl_cpha; 302 r_spi_clk_ignore = r_ctrl_cpha; 303 r_spi_bit_count = r_ctrl_char_len; 304 if (r_initiator_fsm != M_READ_CMD) { 305 if (r_dma_fifo_read.wok()) { 306 r_dma_fifo_read.simple_put( 307 (typename vci_param::data_t)r_txrx[0]); 308 r_spi_word_count = r_spi_word_count - 1; 309 r_txrx[0] = 0xffffffff; 310 if ( r_spi_word_count == 0 ) { 311 r_spi_fsm = S_DMA_SEND_END; 312 } else { 313 r_spi_fsm = S_XMIT; 314 } 315 } 316 } 317 break; 318 case S_DMA_SEND_END: 319 if (r_initiator_fsm == M_IDLE) 320 r_spi_fsm = S_IDLE; 321 break; 322 case S_XMIT: 323 { 324 bool s_clk_sample; 325 // on clock transition, sample input line, and shift data 326 s_clk_sample = r_spi_clk ^ r_ctrl_cpha; 327 if (!r_spi_clk_ignore) { 328 if (r_spi_clk_previous == 0 && s_clk_sample == 1) { 329 // low to high transition: shift and sample 330 r_txrx[1] = (r_txrx[1] << 1) | (r_txrx[0] >> 63); 331 r_txrx[0] = (r_txrx[0] << 1) | p_spi_miso; 332 r_spi_bit_count = r_spi_bit_count - 1; 333 } else if (r_spi_clk_previous == 1 && s_clk_sample == 0) { 334 // high to low transition: change output, or stop 335 if (r_spi_bit_count == 0) { 336 if (r_initiator_fsm != M_IDLE) { 337 if (r_read) 338 r_spi_fsm = S_DMA_SEND; 339 else 340 r_spi_fsm = S_DMA_RECEIVE; 341 } else { 342 r_spi_fsm = S_IDLE; 343 r_irq = r_ctrl_ie; 344 r_spi_done = true; 345 } 323 { 324 r_spi_out = 1; 325 r_spi_clk_counter = r_divider.read(); 326 r_spi_clk = 0; 327 r_spi_clk_previous = r_ctrl_cpha; 328 r_spi_clk_ignore = r_ctrl_cpha; 329 r_spi_bit_count = r_ctrl_char_len; 330 if (r_initiator_fsm != M_READ_CMD) 331 { 332 if (r_dma_fifo_read.wok()) 333 { 334 r_dma_fifo_read.simple_put( (typename vci_param::data_t)r_txrx[0] ); 335 r_spi_word_count = r_spi_word_count - 1; 336 r_txrx[0] = 0xffffffff; 337 if ( r_spi_word_count == 0 ) r_spi_fsm = S_DMA_SEND_END; 338 else r_spi_fsm = S_XMIT; 339 } 340 } 341 break; 342 } 343 //////////////////// 344 case S_DMA_SEND_END: 345 { 346 if (r_initiator_fsm == M_IDLE) r_spi_fsm = S_IDLE; 347 break; 348 } 349 //////////// 350 case S_XMIT: // on SPI clock transitions, sample input line, and shift data 351 { 352 bool s_clk_sample; 353 // on clock transition, sample input line, and shift data 354 s_clk_sample = r_spi_clk ^ r_ctrl_cpha; 355 356 if ( !r_spi_clk_ignore ) 357 { 358 if (r_spi_clk_previous == 0 && s_clk_sample == 1) 359 { 360 // low to high transition: shift and sample 361 r_txrx[1] = (r_txrx[1] << 1) | (r_txrx[0] >> 63); 362 r_txrx[0] = (r_txrx[0] << 1) | p_spi_miso; 363 r_spi_bit_count = r_spi_bit_count - 1; 364 } 365 else if (r_spi_clk_previous == 1 && s_clk_sample == 0) 366 { 367 // high to low transition: change output, or stop 368 if (r_spi_bit_count == 0) 369 { 370 if (r_initiator_fsm != M_IDLE) 371 { 372 if (r_read) r_spi_fsm = S_DMA_SEND; 373 else r_spi_fsm = S_DMA_RECEIVE; 374 } 375 else 376 { 377 r_spi_fsm = S_IDLE; 378 r_irq = r_ctrl_ie; 379 r_spi_done = true; 380 } 346 381 #ifdef SOCLIB_MODULE_DEBUG0 347 382 std::cout << name() << " end xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl; 348 383 #endif 349 } else { 350 r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL; 351 } 352 } 353 } 354 r_spi_clk_previous = s_clk_sample; 355 // generate the SPI clock 356 if (r_spi_clk_counter.read() == 0) { 357 r_spi_clk_counter = r_divider.read(); 358 r_spi_clk = !r_spi_clk.read(); 359 r_spi_clk_ignore = false; 360 } else { 361 r_spi_clk_counter = r_spi_clk_counter.read() - 1; 362 } 363 break; 364 } 365 } 384 } 385 else 386 { 387 r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) 388 & (uint64_t)0x0000000000000001ULL; 389 } 390 } 391 } 392 r_spi_clk_previous = s_clk_sample; 393 394 // generate the SPI clock 395 if (r_spi_clk_counter.read() == 0) 396 { 397 r_spi_clk_counter = r_divider.read(); 398 r_spi_clk = !r_spi_clk.read(); 399 r_spi_clk_ignore = false; 400 } 401 else 402 { 403 r_spi_clk_counter = r_spi_clk_counter.read() - 1; 404 } 405 break; 406 } 407 } // end r_spi_fsm 408 366 409 ////////////////////////////////////////////////////////////////////////////// 367 410 // The initiator FSM executes a loop, transfering one burst per iteration. … … 370 413 ////////////////////////////////////////////////////////////////////////////// 371 414 372 switch( r_initiator_fsm.read() ) { 415 switch( r_initiator_fsm.read() ) 416 { 373 417 //////////// 374 case M_IDLE: // check buffer alignment to compute the number of bursts 375 { 376 if ( r_dma_count != 0 ) 377 { 378 // start transfer 379 if ( r_read.read() ) r_initiator_fsm = M_READ_WAIT; 380 else r_initiator_fsm = M_WRITE_WAIT; 381 } 382 break; 383 } 418 case M_IDLE: // poll the r_dma_count and r_read registers 419 { 420 if ( r_dma_count != 0 ) 421 { 422 // start transfer 423 if ( r_read.read() ) r_initiator_fsm = M_READ_WAIT; 424 else r_initiator_fsm = M_WRITE_WAIT; 425 } 426 break; 427 } 428 ///////////////// 384 429 case M_READ_WAIT: // wait for the FIFO to be full 385 if (!r_dma_fifo_read.wok()) { 386 r_burst_word = m_words_per_burst - 1; 387 r_initiator_fsm = M_READ_CMD; 388 } 389 break; 430 { 431 if (!r_dma_fifo_read.wok()) 432 { 433 r_burst_word = m_words_per_burst - 1; 434 r_initiator_fsm = M_READ_CMD; 435 } 436 break; 437 } 390 438 //////////////// 391 case M_READ_CMD: // Send a multi-flits VCI WRITE command 392 { 393 if ( p_vci_initiator.cmdack.read() ) 394 { 395 if ( r_burst_word == 0 ) // last flit 439 case M_READ_CMD: // multi-flits VCI WRITE command for one burst 440 { 441 if ( p_vci_initiator.cmdack.read() ) 396 442 { 397 r_initiator_fsm = M_READ_RSP; 398 } 399 else // not the last flit 400 { 401 r_burst_word = r_burst_word.read() - 1; 402 } 403 404 r_dma_fifo_read.simple_get(); // consume one fifo word 405 // compute next word address 406 r_buf_address = r_buf_address.read() + vci_param::B; 407 } 408 break; 443 if ( r_burst_word == 0 ) // last flit 444 { 445 r_initiator_fsm = M_READ_RSP; 446 } 447 else // not the last flit 448 { 449 r_burst_word = r_burst_word.read() - 1; 450 } 451 452 r_dma_fifo_read.simple_get(); // consume one fifo word 453 // compute next word address 454 r_buf_address = r_buf_address.read() + vci_param::B; 455 } 456 break; 409 457 } 410 458 //////////////// 411 459 case M_READ_RSP: // Wait a single flit VCI WRITE response 412 460 { 413 if ( p_vci_initiator.rspval.read() ) 414 { 415 if ( (p_vci_initiator.rerror.read()&0x1) != 0 ) 461 if ( p_vci_initiator.rspval.read() ) 416 462 { 417 r_burst_word = 0; 418 r_dma_count = 0; 419 r_dma_error = true; 420 r_initiator_fsm = M_INTR; 463 if ( (p_vci_initiator.rerror.read()&0x1) != 0 ) 464 { 465 r_burst_word = 0; 466 r_dma_count = 0; 467 r_dma_error = true; 468 r_initiator_fsm = M_INTR; 469 421 470 #ifdef SOCLIB_MODULE_DEBUG 422 471 std::cout << "vci_bd M_READ_ERROR" << std::endl; 423 472 #endif 424 } 425 else if ( r_spi_fsm == S_DMA_SEND_END ) // last burst 426 { 427 r_dma_count = 0; 428 r_initiator_fsm = M_INTR; 429 r_dma_error = false; 473 474 } 475 else if ( r_spi_fsm == S_DMA_SEND_END ) // last burst 476 { 477 r_dma_count = 0; 478 r_initiator_fsm = M_INTR; 479 r_dma_error = false; 480 430 481 #ifdef SOCLIB_MODULE_DEBUG 431 482 std::cout << "vci_bd M_READ_SUCCESS" << std::endl; 432 483 #endif 433 } 434 else // keep on reading 435 { 436 r_dma_count = r_dma_count - 1; 437 r_initiator_fsm = M_READ_WAIT; 438 } 439 } 440 break; 484 485 } 486 else // keep on reading 487 { 488 r_dma_count = r_dma_count - 1; 489 r_initiator_fsm = M_READ_WAIT; 490 } 491 } 492 break; 441 493 } 442 494 /////////////////// 443 495 case M_INTR: 444 r_initiator_fsm = M_IDLE; 445 r_irq = true; 446 break; 496 { 497 r_initiator_fsm = M_IDLE; 498 r_irq = true; 499 break; 500 } 447 501 /////////////////// 448 502 case M_WRITE_WAIT: // wait for the FIFO to be empty 449 if (!r_dma_fifo_write.rok()) { 450 r_burst_word = m_words_per_burst - 1; 451 r_dma_count = r_dma_count - 1; 452 r_initiator_fsm = M_WRITE_CMD; 453 } 454 break; 503 { 504 if (!r_dma_fifo_write.rok()) 505 { 506 r_burst_word = m_words_per_burst - 1; 507 r_dma_count = r_dma_count - 1; 508 r_initiator_fsm = M_WRITE_CMD; 509 } 510 break; 511 } 455 512 ///////////////// 456 case M_WRITE_CMD: // This is actually a single flit VCI READ command457 { 458 if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;459 break;513 case M_WRITE_CMD: // single flit VCI READ command for one burst 514 { 515 if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP; 516 break; 460 517 } 461 518 ///////////////// 462 case M_WRITE_RSP: // This is actually a multi-words VCI READ response 463 { 464 if ( p_vci_initiator.rspval.read() ) 465 { 466 typename vci_param::data_t v = p_vci_initiator.rdata.read(); 467 typename vci_param::data_t f = 0; 468 // byte-swap 469 for (int i = 0; i < (vci_param::B * 8); i += 8) { 470 f |= ((v >> i) & 0xff) << ((vci_param::B * 8) - 8 - i); 471 } 472 r_dma_fifo_write.simple_put(f); 473 r_burst_word = r_burst_word.read() - 1; 474 if ( p_vci_initiator.reop.read() ) // last flit of the burst 519 case M_WRITE_RSP: // wait multi-words VCI READ response 520 { 521 if ( p_vci_initiator.rspval.read() ) 475 522 { 476 r_buf_address = r_buf_address.read() + m_burst_size; 477 478 if( (p_vci_initiator.rerror.read()&0x1) != 0 ) 479 { 480 r_dma_count = 0; 481 r_dma_error = 1; 482 r_initiator_fsm = M_WRITE_END; 523 typename vci_param::data_t v = p_vci_initiator.rdata.read(); 524 typename vci_param::data_t f = 0; 525 // byte-swap 526 for (int i = 0; i < (vci_param::B * 8); i += 8) 527 { 528 f |= ((v >> i) & 0xff) << ((vci_param::B * 8) - 8 - i); 529 } 530 r_dma_fifo_write.simple_put(f); 531 r_burst_word = r_burst_word.read() - 1; 532 if ( p_vci_initiator.reop.read() ) // last flit of the burst 533 { 534 r_buf_address = r_buf_address.read() + m_burst_size; 535 536 if( (p_vci_initiator.rerror.read()&0x1) != 0 ) 537 { 538 r_dma_count = 0; 539 r_dma_error = 1; 540 r_initiator_fsm = M_WRITE_END; 541 483 542 #ifdef SOCLIB_MODULE_DEBUG 484 std::cout << "vci_ bdM_WRITE_ERROR" << std::endl;543 std::cout << "vci_spi M_WRITE_ERROR" << std::endl; 485 544 #endif 486 487 else if ( r_dma_count.read() == 0) // last burst488 489 r_dma_error = 0;490 r_initiator_fsm = M_WRITE_END;491 }492 493 494 r_initiator_fsm = M_WRITE_WAIT;495 }496 }497 }498 break;545 } 546 else if ( r_dma_count.read() == 0) // last burst 547 { 548 r_dma_error = 0; 549 r_initiator_fsm = M_WRITE_END; 550 } 551 else // not the last burst 552 { 553 r_initiator_fsm = M_WRITE_WAIT; 554 } 555 } 556 } 557 break; 499 558 } 500 559 ///////////////// 501 case M_WRITE_END: // wait for the write to be complete 502 { 503 if (r_spi_fsm == S_IDLE) { // write complete 504 r_initiator_fsm = M_INTR; 505 } 506 break; 507 } 508 } // end switch r_initiator_fsm 560 case M_WRITE_END: // wait for the write to be completed by SPI FSM 561 { 562 if (r_spi_fsm == S_IDLE) r_initiator_fsm = M_INTR; 563 break; 564 } 565 } // end switch r_initiator_fsm 509 566 } // end transition 510 567 … … 609 666 } 610 667 611 // SPI signals668 ////////////// SPI signals 612 669 p_spi_ss = ((r_ss & 0x1) == 0); 613 switch(r_spi_fsm) { 670 671 switch(r_spi_fsm) 672 { 614 673 default: 615 p_spi_mosi = r_spi_out;616 p_spi_clk = 0;617 break;674 p_spi_mosi = r_spi_out; 675 p_spi_clk = 0; 676 break; 618 677 case S_XMIT: 619 { 620 bool s_clk_sample = r_spi_clk ^ r_ctrl_cpha; 621 p_spi_clk = r_spi_clk ^ r_ctrl_cpol; 622 if (s_clk_sample == 0) { 623 // clock low: get data directly from shift register 624 // as r_spi_out may be delayed by one clock cycle 625 p_spi_mosi = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL; 626 } else { 627 // clock high: get data from saved value, as the shift register 628 // may have changed 629 p_spi_mosi = r_spi_out; 630 } 631 break; 632 } 678 { 679 bool s_clk_sample = r_spi_clk ^ r_ctrl_cpha; 680 p_spi_clk = r_spi_clk ^ r_ctrl_cpol; 681 if (s_clk_sample == 0) 682 { 683 // clock low: get data directly from shift register 684 // as r_spi_out may be delayed by one clock cycle 685 p_spi_mosi = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL; 686 } 687 else 688 { 689 // clock high: get data from saved value, as the shift register 690 // may have changed 691 p_spi_mosi = r_spi_out; 692 } 693 break; 694 } 633 695 } 634 696 … … 638 700 639 701 ////////////////////////////////////////////////////////////////////////////// 640 tmpl(/**/)::VciSpi( sc_core::sc_module_name name,702 tmpl(/**/)::VciSpi( sc_core::sc_module_name name, 641 703 const soclib::common::MappingTable &mt, 642 const soclib::common::IntTab 643 const soclib::common::IntTab 644 const uint32_t burst_size)704 const soclib::common::IntTab &srcid, 705 const soclib::common::IntTab &tgtid, 706 const uint32_t burst_size) 645 707 646 708 : caba::BaseModule(name),
Note: See TracChangeset
for help on using the changeset viewer.