Changeset 1052 for trunk/modules


Ignore:
Timestamp:
Jun 21, 2017, 10:50:42 AM (7 years ago)
Author:
alain
Message:

few bugs

Location:
trunk/modules
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/sdmmc/caba/source/include/sdmmc.h

    r574 r1052  
    5555
    5656    // Registers
    57     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
     57    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
    6262
    63     uint8_t           command;
     63    uint8_t               command;
    6464    uint32_t          args;
    65     uint8_t           cmdcrc;
     65    uint8_t               cmdcrc;
     66
    6667    int               m_fd;              // File descriptor
    6768    uint64_t          m_device_size;     // Total number of blocks
    6869    const uint32_t    m_latency;         // device latency
    6970
    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
    7378    uint32_t          m_data_idx;
    74     bool              m_acmd; // next command will be acmd
    75     int               m_sdstate; // sdcard internal state
     79    bool                  m_acmd;            // next command will be acmd
     80    int                   m_sdstate;        // sdcard internal state
    7681
    7782    // sd states
    78     enum {
    79         SD_IDLE = 0,
    80         SD_READY = 1,
     83    enum
     84    {
     85            SD_IDLE = 0,
     86            SD_READY = 1,
    8187    };
    8288
     
    8894
    8995    //  Master FSM states
    90     enum {
     96    enum
     97    {
    9198    S_IDLE               = 0,
    9299    S_RECEIVE_CMD        = 1,
  • trunk/modules/sdmmc/caba/source/src/sdmmc.cpp

    r709 r1052  
    4646    {
    4747        spi_fsm  = S_IDLE;
    48         m_acmd     = false;     
    49         m_sdstate  = SD_IDLE;
     48        m_acmd     = false;     
     49        m_sdstate  = SD_IDLE;
    5050        return;
    5151    }
    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;
    6568    }
    6669
    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                {
    8492#ifdef SOCLIB_MODULE_DEBUG0
    8593                                std::cout << name() << " S_RECEIVE_CMD " << std::hex << (int)command << std::endl;
    8694#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;
    128144       
    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++;
    138156#ifdef SOCLIB_MODULE_DEBUG0
    139157                        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;
    140158#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            {
    161187#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 {
     188std::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                {
    169198#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             }
     199std::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;
    202256            break;
     257
     258        default:
     259            p_spi_miso = !p_spi_ss.read();
     260        break;
    203261    }
    204262
    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
    218264    spi_clk = p_spi_clk.read();
    219265    spi_mosi_previous = p_spi_mosi;
     266
    220267} // end GenMealy()
    221268
    222269
    223 //////////////////////
     270////////////////////////////////////////////////////////
    224271void SdMMC::handle_sdmmc_cmd(uint8_t cmd, uint32_t data)
    225272{
    226273        m_datalen_rcv = 0;
    227         m_databuf[0] = 0x04; // illegal command
    228         m_datalen_snd = 1;
     274        m_databuf[0] = 0x04;    // default value : illegal command
     275        m_datalen_snd = 1;      // default value : 1 byte
    229276
    230277        if (m_sdstate == SD_IDLE)
    231278                m_databuf[0] |= 0x01; // idle
    232279
    233         if ((cmd & 0x40) == 0) {
     280        if ((cmd & 0x40) == 0)
     281    {
    234282                //illegal command
    235283                return;
    236284        }
    237285        cmd &= 0x3f;
    238         if (m_acmd) {
     286
     287    if (m_acmd)
     288    {
    239289#ifdef SOCLIB_MODULE_DEBUG0
    240         std::cout << name() << " new acmd " << std::dec << (int)cmd << " args " << std::hex << data << " crc " << (int)cmdcrc << std::endl;
     290std::cout << name() << " new acmd " << std::dec << (int)cmd << " args " << std::hex << data << " crc " << (int)cmdcrc << std::endl;
    241291#endif
    242292            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                 // send SCR
    251                 m_databuf[ 0] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1
    252                 m_databuf[ 1] = 0xfe; // data token
    253                 m_databuf[ 2] = 0x00; // SCR_STRUCTURE / SD_SPEC
    254                 m_databuf[ 3] = 0x05; // DATA_STAT_AFTER_ERASE, SD_SECURITY, SD_BUS_WIDTHS
    255                 m_databuf[ 4] = 0;    // SD_SPEC3, EX_SECURITY, SD_SPEC4
    256                 m_databuf[ 5] = 0;    // CMD_SUPPORT
    257                 m_databuf[ 6] = 0;    // vendor specific
    258                 m_databuf[ 7] = 0;    // vendor specific
    259                 m_databuf[ 8] = 0;    // vendor specific
    260                 m_databuf[ 9] = 0;    // vendor specific
    261                 m_databuf[10] = 0x0;  // CRC16
    262                 m_databuf[11] = 0x0;  // CRC16
    263                 m_datalen_snd = 12;
    264                 break;
    265             default:
    266                 std::cout << name() << " unknown acmd " << std::dec
    267                     << (int)cmd << std::endl;
    268                 break; // return illegal command
     293            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
    269319            }
    270         } else {
     320        }
     321    else
     322    {
    271323#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                 }
     324std::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                }
    392451#ifdef SOCLIB_MODULE_DEBUG
    393452        std::cout << name() << " new cmd write " << std::dec << (int)cmd << " args " << std::hex << data << std::endl;
    394453#endif
    395                 m_databuf[0] = 0x0; // R1
    396                 m_datalen_snd = 1;
    397                 m_datalen_rcv = 512 + 2 + 1; // data + tocken + CRC
    398                 break;
    399               }
    400             case 55:
    401                 // app-specific command follow
    402                 m_acmd = true;
    403                 m_databuf[0] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0;
    404                 m_datalen_snd = 1;
    405                 break;
    406             case 58:
    407                 // send OCR
    408                 m_databuf[4] = (m_sdstate == SD_IDLE) ? 0x1 : 0x0; // R1
    409                 m_databuf[3] = 0x80; // power up complete, SDSC
    410                 m_databuf[2] = 0xff; // all voltages supported
    411                 m_databuf[1] = 0x00;
    412                 m_databuf[0] = 0x00;
    413                 m_datalen_snd = 5;
    414                 break;
    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;
    419478            }
    420479        }
    421 }
    422 
     480}  // end  handle_sdmmc_cmd()
     481
     482///////////////////////////////////////////////////////////
    423483void SdMMC::handle_sdmmc_write(uint8_t cmd, uint32_t data)
    424484{
     
    428488        std::cout << name() << " cmd write " << std::dec << (int)cmd << " args " << std::hex << data << std::endl;
    429489#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            }
    463527                break;
    464               }
    465528            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        }
    470534        }
    471535        return;
    472536}
    473537
    474 //////////////////////////////////////////////////////////////////////////////
     538//////////////////////////////////////////////////////////////
    475539SdMMC::SdMMC( sc_core::sc_module_name              name,
    476                                 const std::string                    &filename,
    477                                 const uint32_t                       latency)
     540              const std::string                    &filename,
     541              const uint32_t                       latency)
    478542
    479543: caba::BaseModule(name),
     
    516580        const char* spi_str[] =
    517581    {
    518                 "S_IDLE",
    519                 "S_RECEIVE_CMD",
    520                 "S_RECEIVE_ARGS_START",
    521                 "S_RECEIVE_ARGS",
    522                 "S_RECEIVE_CRC",
    523                 "S_RECEIVE_DATA_START",
    524                 "S_RECEIVE_DATA",
    525                 "S_SEND_DATA",
    526                 "S_NOP",
     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",
    527591        };
    528592        if (spi_clk != p_spi_clk.read()) {
  • trunk/modules/vci_block_device_tsar/caba/source/src/vci_block_device_tsar.cpp

    r1017 r1052  
    875875    const char* target_str[] =
    876876    {
    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
    894894    };
    895895
  • trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp

    r1039 r1052  
    47614761                    {
    47624762                        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
    47654766                                  << " / set = " << set
    47664767                                  << " / inval_required = " << inval << std::endl;
  • trunk/modules/vci_mem_cache/include/soclib/mem_cache.h

    r912 r1052  
    178178enum SoclibMemCacheRerrorRegs
    179179{
    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,
    185185};
    186186
  • trunk/modules/vci_spi/caba/source/include/vci_spi.h

    r595 r1052  
    6868
    6969    // Registers
    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;
     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;
    9191    sc_signal<bool>                    r_spi_clk;
    9292    sc_signal<bool>                    r_spi_clk_previous;
     
    189189    soclib::caba::VciInitiator<vci_param> p_vci_initiator;
    190190    soclib::caba::VciTarget<vci_param>    p_vci_target;
     191
    191192    sc_out<bool>                                              p_spi_ss;
    192193    sc_out<bool>                                              p_spi_clk;
  • trunk/modules/vci_spi/caba/source/src/vci_spi.cpp

    r595 r1052  
    4646
    4747    bool s_dma_bsy = (r_initiator_fsm != M_IDLE);
     48
    4849    if(p_resetn.read() == false)
    4950    {
    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;
    7374    }
    7475
    7576    //////////////////////////////////////////////////////////////////////////////
    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
    7878    //////////////////////////////////////////////////////////////////////////////
    7979
     
    8181        r_spi_bsy = false;
    8282
    83     switch(r_target_fsm) {
     83    switch(r_target_fsm)
     84    {
    8485    ////////////
    8586    case T_IDLE:
    8687    {
    87         if ( p_vci_target.cmdval.read() )
    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                }
    101102 
    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            {
    107113                    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
    175180#ifdef SOCLIB_MODULE_DEBUG
    176181                        if ((wdata & SPI_CTRL_GO_BSY) != 0) {
     
    178183                        }
    179184#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
    189197#ifdef SOCLIB_MODULE_DEBUG
    190198                        std::cout << name() << " divider set to " << std::dec << wdata << std::endl;
    191199#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;
    234242    }
    235243    ////////////////////
     
    238246    case T_ERROR_READ:
    239247    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    }
    244252    } // end switch target fsm
    245253
     
    252260    if (r_spi_bsy == false)
    253261        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;
    267318            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    ////////////////
    297322    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                            }
    346381#ifdef SOCLIB_MODULE_DEBUG0
    347382                    std::cout << name() << " end xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl;
    348383#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
    366409    //////////////////////////////////////////////////////////////////////////////
    367410    // The initiator FSM executes a loop, transfering one burst per iteration.
     
    370413    //////////////////////////////////////////////////////////////////////////////
    371414
    372     switch( r_initiator_fsm.read() ) {
     415    switch( r_initiator_fsm.read() )
     416    {
    373417    ////////////
    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    /////////////////
    384429    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    }
    390438    ////////////////
    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() )
    396442            {
    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;
    409457    }
    410458    ////////////////
    411459    case M_READ_RSP:    // Wait a single flit VCI WRITE response
    412460    {
    413         if ( p_vci_initiator.rspval.read() )
    414         {
    415             if ( (p_vci_initiator.rerror.read()&0x1) != 0 )
     461            if ( p_vci_initiator.rspval.read() )
    416462            {
    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
    421470#ifdef SOCLIB_MODULE_DEBUG
    422471                std::cout << "vci_bd M_READ_ERROR" << std::endl;
    423472#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
    430481#ifdef SOCLIB_MODULE_DEBUG
    431482                std::cout << "vci_bd M_READ_SUCCESS" << std::endl;
    432483#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;
    441493    }
    442494    ///////////////////
    443495    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    }
    447501    ///////////////////
    448502    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    }
    455512    /////////////////
    456     case M_WRITE_CMD:   // This is actually a single flit VCI READ command
    457     {
    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;
    460517    }
    461518    /////////////////
    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() )
    475522            {
    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
    483542#ifdef SOCLIB_MODULE_DEBUG
    484                     std::cout << "vci_bd M_WRITE_ERROR" << std::endl;
     543                    std::cout << "vci_spi M_WRITE_ERROR" << std::endl;
    485544#endif
    486                 }
    487                 else if ( r_dma_count.read() == 0) // last burst
    488                 {
    489                     r_dma_error = 0;
    490                     r_initiator_fsm  = M_WRITE_END;
    491                 }
    492                 else                                      // not the last burst
    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;
    499558    }
    500559    /////////////////
    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
    509566}  // end transition
    510567
     
    609666    }
    610667
    611     // SPI signals
     668    ////////////// SPI signals
    612669    p_spi_ss = ((r_ss & 0x1) == 0);
    613     switch(r_spi_fsm) {
     670
     671    switch(r_spi_fsm)
     672    {
    614673    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;
    618677    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    }
    633695    }
    634696
     
    638700
    639701//////////////////////////////////////////////////////////////////////////////
    640 tmpl(/**/)::VciSpi( sc_core::sc_module_name           name,
     702tmpl(/**/)::VciSpi( sc_core::sc_module_name              name,
    641703                                const soclib::common::MappingTable   &mt,
    642                                 const soclib::common::IntTab    &srcid,
    643                                 const soclib::common::IntTab    &tgtid,
    644                                 const uint32_t                 burst_size)
     704                                const soclib::common::IntTab        &srcid,
     705                                const soclib::common::IntTab        &tgtid,
     706                                const uint32_t                           burst_size)
    645707
    646708: caba::BaseModule(name),
Note: See TracChangeset for help on using the changeset viewer.