master/mailbox.c
branchstable-1.0
changeset 1621 4bbe090553f7
parent 1619 0d4119024f55
child 1624 9dc190591c0f
equal deleted inserted replaced
1620:9d7453c16ade 1621:4bbe090553f7
    50 /**
    50 /**
    51    Prepares a mailbox-send command.
    51    Prepares a mailbox-send command.
    52    \return pointer to mailbox command data
    52    \return pointer to mailbox command data
    53 */
    53 */
    54 
    54 
    55 uint8_t *ec_slave_mbox_prepare_send(ec_slave_t *slave, /**< slave */
    55 uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
       
    56                                     ec_command_t *command, /**< command */
    56                                     uint8_t type, /**< mailbox protocol */
    57                                     uint8_t type, /**< mailbox protocol */
    57                                     size_t size /**< size of the data */
    58                                     size_t size /**< size of the data */
    58                                     )
    59                                     )
    59 {
    60 {
    60     ec_command_t *command = &slave->mbox_command;
       
    61     size_t total_size;
    61     size_t total_size;
    62 
    62 
    63     if (unlikely(!slave->sii_mailbox_protocols)) {
    63     if (unlikely(!slave->sii_mailbox_protocols)) {
    64         EC_ERR("Slave %i does not support mailbox communication!\n",
    64         EC_ERR("Slave %i does not support mailbox communication!\n",
    65                slave->ring_position);
    65                slave->ring_position);
    77                         slave->sii_rx_mailbox_size))
    77                         slave->sii_rx_mailbox_size))
    78         return NULL;
    78         return NULL;
    79 
    79 
    80     EC_WRITE_U16(command->data,     size); // mailbox service data length
    80     EC_WRITE_U16(command->data,     size); // mailbox service data length
    81     EC_WRITE_U16(command->data + 2, slave->station_address); // station address
    81     EC_WRITE_U16(command->data + 2, slave->station_address); // station address
    82     EC_WRITE_U8 (command->data + 4, 0x00); // hhannel & priority
    82     EC_WRITE_U8 (command->data + 4, 0x00); // channel & priority
    83     EC_WRITE_U8 (command->data + 5, type); // underlying protocol type
    83     EC_WRITE_U8 (command->data + 5, type); // underlying protocol type
    84 
    84 
    85     return command->data + 6;
    85     return command->data + 6;
    86 }
    86 }
    87 
    87 
    90 /**
    90 /**
    91    Prepares a command for checking the mailbox state.
    91    Prepares a command for checking the mailbox state.
    92    \return 0 in case of success, else < 0
    92    \return 0 in case of success, else < 0
    93 */
    93 */
    94 
    94 
    95 int ec_slave_mbox_prepare_check(ec_slave_t *slave /**< slave */)
    95 int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */
    96 {
    96                                 ec_command_t *command /**< command */
    97     ec_command_t *command = &slave->mbox_command;
    97                                 )
    98 
    98 {
    99     // FIXME: second sync manager?
    99     // FIXME: second sync manager?
   100     if (ec_command_nprd(command, slave->station_address, 0x808, 8))
   100     if (ec_command_nprd(command, slave->station_address, 0x808, 8))
   101         return -1;
   101         return -1;
   102 
   102 
   103     return 0;
   103     return 0;
   108 /**
   108 /**
   109    Processes a mailbox state checking command.
   109    Processes a mailbox state checking command.
   110    \return 0 in case of success, else < 0
   110    \return 0 in case of success, else < 0
   111 */
   111 */
   112 
   112 
   113 int ec_slave_mbox_check(const ec_slave_t *slave /**< slave */)
   113 int ec_slave_mbox_check(const ec_command_t *command /**< command */)
   114 {
   114 {
   115     return EC_READ_U8(slave->mbox_command.data + 5) & 8 ? 1 : 0;
   115     return EC_READ_U8(command->data + 5) & 8 ? 1 : 0;
   116 }
   116 }
   117 
   117 
   118 /*****************************************************************************/
   118 /*****************************************************************************/
   119 
   119 
   120 /**
   120 /**
   121    Prepares a command to fetch mailbox data.
   121    Prepares a command to fetch mailbox data.
   122    \return 0 in case of success, else < 0
   122    \return 0 in case of success, else < 0
   123 */
   123 */
   124 
   124 
   125 int ec_slave_mbox_prepare_fetch(ec_slave_t *slave /**< slave */)
   125 int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
   126 {
   126                                 ec_command_t *command /**< command */
   127     ec_command_t *command = &slave->mbox_command;
   127                                 )
   128 
   128 {
   129     if (ec_command_nprd(command, slave->station_address,
   129     if (ec_command_nprd(command, slave->station_address,
   130                         slave->sii_tx_mailbox_offset,
   130                         slave->sii_tx_mailbox_offset,
   131                         slave->sii_tx_mailbox_size)) return -1;
   131                         slave->sii_tx_mailbox_size)) return -1;
   132     return 0;
   132     return 0;
   133 }
   133 }
   137 /**
   137 /**
   138    Processes received mailbox data.
   138    Processes received mailbox data.
   139    \return pointer to the received data
   139    \return pointer to the received data
   140 */
   140 */
   141 
   141 
   142 uint8_t *ec_slave_mbox_fetch(ec_slave_t *slave, /**< slave */
   142 uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
       
   143                              ec_command_t *command, /**< command */
   143                              uint8_t type, /**< expected mailbox protocol */
   144                              uint8_t type, /**< expected mailbox protocol */
   144                              size_t *size /**< size of the received data */
   145                              size_t *size /**< size of the received data */
   145                              )
   146                              )
   146 {
   147 {
   147     ec_command_t *command = &slave->mbox_command;
       
   148     size_t data_size;
   148     size_t data_size;
   149 
   149 
   150     if ((EC_READ_U8(command->data + 5) & 0x0F) != type) {
   150     if ((EC_READ_U8(command->data + 5) & 0x0F) != type) {
   151         EC_ERR("Unexpected mailbox protocol 0x%02X (exp.: 0x%02X) at"
   151         EC_ERR("Unexpected mailbox protocol 0x%02X (exp.: 0x%02X) at"
   152                " slave %i!\n", EC_READ_U8(command->data + 5), type,
   152                " slave %i!\n", EC_READ_U8(command->data + 5), type,
   169 /**
   169 /**
   170    Sends a mailbox command and waits for its reception.
   170    Sends a mailbox command and waits for its reception.
   171    \return pointer to the received data
   171    \return pointer to the received data
   172 */
   172 */
   173 
   173 
   174 uint8_t *ec_slave_mbox_simple_io(ec_slave_t *slave, /**< slave */
   174 uint8_t *ec_slave_mbox_simple_io(const ec_slave_t *slave, /**< slave */
       
   175                                  ec_command_t *command, /**< command */
   175                                  size_t *size /**< size of the received data */
   176                                  size_t *size /**< size of the received data */
   176                                  )
   177                                  )
   177 {
   178 {
   178     uint8_t type;
   179     uint8_t type;
   179     ec_command_t *command;
   180 
   180 
       
   181     command = &slave->mbox_command;
       
   182     type = EC_READ_U8(command->data + 5);
   181     type = EC_READ_U8(command->data + 5);
   183 
   182 
   184     if (unlikely(ec_master_simple_io(slave->master, command))) {
   183     if (unlikely(ec_master_simple_io(slave->master, command))) {
   185         EC_ERR("Mailbox checking failed on slave %i!\n",
   184         EC_ERR("Mailbox checking failed on slave %i!\n",
   186                slave->ring_position);
   185                slave->ring_position);
   187         return NULL;
   186         return NULL;
   188     }
   187     }
   189 
   188 
   190     return ec_slave_mbox_simple_receive(slave, type, size);
   189     return ec_slave_mbox_simple_receive(slave, command, type, size);
   191 }
   190 }
   192 
   191 
   193 /*****************************************************************************/
   192 /*****************************************************************************/
   194 
   193 
   195 /**
   194 /**
   196    Waits for the reception of a mailbox command.
   195    Waits for the reception of a mailbox command.
   197    \return pointer to the received data
   196    \return pointer to the received data
   198 */
   197 */
   199 
   198 
   200 uint8_t *ec_slave_mbox_simple_receive(ec_slave_t *slave, /**< slave */
   199 uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *slave, /**< slave */
       
   200                                       ec_command_t *command, /**< command */
   201                                       uint8_t type, /**< expected protocol */
   201                                       uint8_t type, /**< expected protocol */
   202                                       size_t *size /**< received data size */
   202                                       size_t *size /**< received data size */
   203                                       )
   203                                       )
   204 {
   204 {
   205     cycles_t start, end, timeout;
   205     cycles_t start, end, timeout;
   206     ec_command_t *command;
   206 
   207 
       
   208     command = &slave->mbox_command;
       
   209     start = get_cycles();
   207     start = get_cycles();
   210     timeout = (cycles_t) 100 * cpu_khz; // 100ms
   208     timeout = (cycles_t) 100 * cpu_khz; // 100ms
   211 
   209 
   212     while (1)
   210     while (1)
   213     {
   211     {
   214         if (ec_slave_mbox_prepare_check(slave)) return NULL;
   212         if (ec_slave_mbox_prepare_check(slave, command)) return NULL;
   215         if (unlikely(ec_master_simple_io(slave->master, command))) {
   213         if (unlikely(ec_master_simple_io(slave->master, command))) {
   216             EC_ERR("Mailbox checking failed on slave %i!\n",
   214             EC_ERR("Mailbox checking failed on slave %i!\n",
   217                    slave->ring_position);
   215                    slave->ring_position);
   218             return NULL;
   216             return NULL;
   219         }
   217         }
   220 
   218 
   221         end = get_cycles();
   219         end = get_cycles();
   222 
   220 
   223         if (ec_slave_mbox_check(slave))
   221         if (ec_slave_mbox_check(command))
   224             break; // proceed with receiving data
   222             break; // proceed with receiving data
   225 
   223 
   226         if ((end - start) >= timeout) {
   224         if ((end - start) >= timeout) {
   227             EC_ERR("Mailbox check - Slave %i timed out.\n",
   225             EC_ERR("Mailbox check - Slave %i timed out.\n",
   228                    slave->ring_position);
   226                    slave->ring_position);
   230         }
   228         }
   231 
   229 
   232         udelay(100);
   230         udelay(100);
   233     }
   231     }
   234 
   232 
   235     if (ec_slave_mbox_prepare_fetch(slave)) return NULL;
   233     if (ec_slave_mbox_prepare_fetch(slave, command)) return NULL;
   236     if (unlikely(ec_master_simple_io(slave->master, command))) {
   234     if (unlikely(ec_master_simple_io(slave->master, command))) {
   237         EC_ERR("Mailbox receiving failed on slave %i!\n",
   235         EC_ERR("Mailbox receiving failed on slave %i!\n",
   238                slave->ring_position);
   236                slave->ring_position);
   239         return NULL;
   237         return NULL;
   240     }
   238     }
   241 
   239 
   242     if (unlikely(slave->master->debug_level) > 1)
   240     if (unlikely(slave->master->debug_level) > 1)
   243         EC_DBG("Mailbox receive took %ius.\n", ((u32) (end - start) * 1000
   241         EC_DBG("Mailbox receive took %ius.\n", ((u32) (end - start) * 1000
   244                                                 / cpu_khz));
   242                                                 / cpu_khz));
   245 
   243 
   246     return ec_slave_mbox_fetch(slave, type, size);
   244     return ec_slave_mbox_fetch(slave, command, type, size);
   247 }
   245 }
   248 
   246 
   249 /*****************************************************************************/
   247 /*****************************************************************************/