master/mailbox.c
changeset 1313 ed15eef57d5c
parent 1225 4d5b739edcb5
child 1326 ef907b0b5125
equal deleted inserted replaced
1312:74853e018898 1313:ed15eef57d5c
    47 
    47 
    48 /*****************************************************************************/
    48 /*****************************************************************************/
    49 
    49 
    50 /**
    50 /**
    51    Prepares a mailbox-send datagram.
    51    Prepares a mailbox-send datagram.
    52    \return pointer to mailbox datagram data
    52    \return Pointer to mailbox datagram data, or ERR_PTR() code.
    53 */
    53 */
    54 
    54 
    55 uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
    55 uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
    56                                     ec_datagram_t *datagram, /**< datagram */
    56                                     ec_datagram_t *datagram, /**< datagram */
    57                                     uint8_t type, /**< mailbox protocol */
    57                                     uint8_t type, /**< mailbox protocol */
    58                                     size_t size /**< size of the data */
    58                                     size_t size /**< size of the data */
    59                                     )
    59                                     )
    60 {
    60 {
    61     size_t total_size;
    61     size_t total_size;
       
    62     int ret;
    62 
    63 
    63     if (unlikely(!slave->sii.mailbox_protocols)) {
    64     if (unlikely(!slave->sii.mailbox_protocols)) {
    64         EC_ERR("Slave %u does not support mailbox communication!\n",
    65         EC_ERR("Slave %u does not support mailbox communication!\n",
    65                slave->ring_position);
    66                slave->ring_position);
    66         return NULL;
    67         return ERR_PTR(-EPROTONOSUPPORT);
    67     }
    68     }
    68 
    69 
    69     total_size = EC_MBOX_HEADER_SIZE + size;
    70     total_size = EC_MBOX_HEADER_SIZE + size;
    70     if (unlikely(total_size > slave->sii.rx_mailbox_size)) {
    71     if (unlikely(total_size > slave->sii.rx_mailbox_size)) {
    71         EC_ERR("Data size does not fit in mailbox!\n");
    72         EC_ERR("Data size does not fit in mailbox!\n");
    72         return NULL;
    73         return ERR_PTR(-EOVERFLOW);
    73     }
    74     }
    74 
    75 
    75     if (ec_datagram_fpwr(datagram, slave->station_address,
    76     ret = ec_datagram_fpwr(datagram, slave->station_address,
    76                          slave->sii.rx_mailbox_offset,
    77                          slave->sii.rx_mailbox_offset,
    77                          slave->sii.rx_mailbox_size))
    78                          slave->sii.rx_mailbox_size);
    78         return NULL;
    79     if (ret)
       
    80         return ERR_PTR(ret);
    79 
    81 
    80     EC_WRITE_U16(datagram->data,     size); // mailbox service data length
    82     EC_WRITE_U16(datagram->data,     size); // mailbox service data length
    81     EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr.
    83     EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr.
    82     EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority
    84     EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority
    83     EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type
    85     EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type
    95 
    97 
    96 int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */
    98 int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */
    97                                 ec_datagram_t *datagram /**< datagram */
    99                                 ec_datagram_t *datagram /**< datagram */
    98                                 )
   100                                 )
    99 {
   101 {
   100     if (ec_datagram_fprd(datagram, slave->station_address, 0x808, 8))
   102     int ret = ec_datagram_fprd(datagram, slave->station_address, 0x808, 8);
   101         return -1;
   103     if (ret)
       
   104         return ret;
   102 
   105 
   103     ec_datagram_zero(datagram);
   106     ec_datagram_zero(datagram);
   104     return 0;
   107     return 0;
   105 }
   108 }
   106 
   109 
   125 
   128 
   126 int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
   129 int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
   127                                 ec_datagram_t *datagram /**< datagram */
   130                                 ec_datagram_t *datagram /**< datagram */
   128                                 )
   131                                 )
   129 {
   132 {
   130     if (ec_datagram_fprd(datagram, slave->station_address,
   133     int ret = ec_datagram_fprd(datagram, slave->station_address,
   131                          slave->sii.tx_mailbox_offset,
   134                          slave->sii.tx_mailbox_offset,
   132                          slave->sii.tx_mailbox_size))
   135                          slave->sii.tx_mailbox_size);
   133         return -1;
   136     if (ret)
       
   137         return ret;
   134 
   138 
   135     ec_datagram_zero(datagram);
   139     ec_datagram_zero(datagram);
   136     return 0;
   140     return 0;
   137 }
   141 }
   138 
   142 
   154     {}
   158     {}
   155 };
   159 };
   156 
   160 
   157 /*****************************************************************************/
   161 /*****************************************************************************/
   158 
   162 
   159 /**
   163 /** Processes received mailbox data.
   160    Processes received mailbox data.
   164  *
   161    \return pointer to the received data
   165  * \return Pointer to the received data, or ERR_PTR() code.
   162 */
   166  */
   163 
       
   164 uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
   167 uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
   165                              ec_datagram_t *datagram, /**< datagram */
   168                              ec_datagram_t *datagram, /**< datagram */
   166                              uint8_t *type, /**< expected mailbox protocol */
   169                              uint8_t *type, /**< expected mailbox protocol */
   167                              size_t *size /**< size of the received data */
   170                              size_t *size /**< size of the received data */
   168                              )
   171                              )
   173 
   176 
   174     if (data_size + EC_MBOX_HEADER_SIZE > slave->sii.tx_mailbox_size) {
   177     if (data_size + EC_MBOX_HEADER_SIZE > slave->sii.tx_mailbox_size) {
   175         EC_ERR("Corrupt mailbox response received from slave %u!\n",
   178         EC_ERR("Corrupt mailbox response received from slave %u!\n",
   176                slave->ring_position);
   179                slave->ring_position);
   177         ec_print_data(datagram->data, slave->sii.tx_mailbox_size);
   180         ec_print_data(datagram->data, slave->sii.tx_mailbox_size);
   178         return NULL;
   181         return ERR_PTR(-EPROTO);
   179     }
   182     }
   180 
   183 
   181     *type = EC_READ_U8(datagram->data + 5) & 0x0F;
   184     *type = EC_READ_U8(datagram->data + 5) & 0x0F;
   182     *size = data_size;
   185     *size = data_size;
   183 
   186 
   199             printk("Unknown error reply code 0x%04X.\n", code);
   202             printk("Unknown error reply code 0x%04X.\n", code);
   200 
   203 
   201         if (slave->master->debug_level)
   204         if (slave->master->debug_level)
   202             ec_print_data(datagram->data + EC_MBOX_HEADER_SIZE, data_size);
   205             ec_print_data(datagram->data + EC_MBOX_HEADER_SIZE, data_size);
   203 
   206 
   204         return NULL;
   207         return ERR_PTR(-EPROTO);
   205     }
   208     }
   206 
   209 
   207     return datagram->data + EC_MBOX_HEADER_SIZE;
   210     return datagram->data + EC_MBOX_HEADER_SIZE;
   208 }
   211 }
   209 
   212