master/fsm.c
changeset 304 558a6669da90
parent 301 dfe8192a7e19
child 306 45886de3db87
equal deleted inserted replaced
303:03fd45bc13ef 304:558a6669da90
    44 
    44 
    45 /*****************************************************************************/
    45 /*****************************************************************************/
    46 
    46 
    47 void ec_fsm_master_start(ec_fsm_t *);
    47 void ec_fsm_master_start(ec_fsm_t *);
    48 void ec_fsm_master_broadcast(ec_fsm_t *);
    48 void ec_fsm_master_broadcast(ec_fsm_t *);
    49 void ec_fsm_master_proc_states(ec_fsm_t *);
    49 void ec_fsm_master_read_states(ec_fsm_t *);
    50 void ec_fsm_master_scan(ec_fsm_t *);
       
    51 void ec_fsm_master_states(ec_fsm_t *);
       
    52 void ec_fsm_master_validate_vendor(ec_fsm_t *);
    50 void ec_fsm_master_validate_vendor(ec_fsm_t *);
    53 void ec_fsm_master_validate_product(ec_fsm_t *);
    51 void ec_fsm_master_validate_product(ec_fsm_t *);
    54 void ec_fsm_master_reconfigure(ec_fsm_t *);
    52 void ec_fsm_master_rewrite_addresses(ec_fsm_t *);
    55 void ec_fsm_master_address(ec_fsm_t *);
    53 void ec_fsm_master_configure_slave(ec_fsm_t *);
    56 void ec_fsm_master_conf(ec_fsm_t *);
    54 void ec_fsm_master_scan_slaves(ec_fsm_t *);
    57 void ec_fsm_master_eeprom(ec_fsm_t *);
    55 void ec_fsm_master_write_eeprom(ec_fsm_t *);
    58 
    56 
    59 void ec_fsm_slave_start_reading(ec_fsm_t *);
    57 void ec_fsm_slave_start_reading(ec_fsm_t *);
    60 void ec_fsm_slave_read_state(ec_fsm_t *);
    58 void ec_fsm_slave_read_state(ec_fsm_t *);
    61 void ec_fsm_slave_read_base(ec_fsm_t *);
    59 void ec_fsm_slave_read_base(ec_fsm_t *);
    62 void ec_fsm_slave_read_dl(ec_fsm_t *);
    60 void ec_fsm_slave_read_dl(ec_fsm_t *);
   263         }
   261         }
   264 
   262 
   265         // begin scanning of slaves
   263         // begin scanning of slaves
   266         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   264         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   267         fsm->slave_state = ec_fsm_slave_start_reading;
   265         fsm->slave_state = ec_fsm_slave_start_reading;
   268         fsm->master_state = ec_fsm_master_scan;
   266         fsm->master_state = ec_fsm_master_scan_slaves;
   269         fsm->master_state(fsm); // execute immediately
   267         fsm->master_state(fsm); // execute immediately
   270         return;
   268         return;
   271     }
   269     }
   272 
   270 
   273     // fetch state from each slave
   271     // fetch state from each slave
   274     fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   272     fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   275     ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address, 0x0130, 2);
   273     ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address, 0x0130, 2);
   276     ec_master_queue_datagram(master, &fsm->datagram);
   274     ec_master_queue_datagram(master, &fsm->datagram);
   277     fsm->master_state = ec_fsm_master_states;
   275     fsm->master_state = ec_fsm_master_read_states;
       
   276 }
       
   277 
       
   278 /*****************************************************************************/
       
   279 
       
   280 /**
       
   281    Master action: PROC_STATES.
       
   282    Processes the slave states.
       
   283 */
       
   284 
       
   285 void ec_fsm_master_action_process_states(ec_fsm_t *fsm
       
   286                                          /**< finite state machine */
       
   287                                          )
       
   288 {
       
   289     ec_master_t *master = fsm->master;
       
   290     ec_slave_t *slave;
       
   291 
       
   292     // check if any slaves are not in the state, they're supposed to be
       
   293     list_for_each_entry(slave, &master->slaves, list) {
       
   294         if (slave->error_flag ||
       
   295             !slave->online ||
       
   296             slave->requested_state == EC_SLAVE_STATE_UNKNOWN ||
       
   297             slave->current_state == slave->requested_state) continue;
       
   298 
       
   299         EC_INFO("Changing state of slave %i from ", slave->ring_position);
       
   300         ec_print_states(slave->current_state);
       
   301         printk(" to ");
       
   302         ec_print_states(slave->requested_state);
       
   303         printk(".\n");
       
   304 
       
   305         fsm->slave = slave;
       
   306         fsm->slave_state = ec_fsm_slave_conf;
       
   307         fsm->change_new = EC_SLAVE_STATE_INIT;
       
   308         fsm->change_state = ec_fsm_change_start;
       
   309         fsm->master_state = ec_fsm_master_configure_slave;
       
   310         fsm->master_state(fsm); // execute immediately
       
   311         return;
       
   312     }
       
   313 
       
   314     if (master->mode == EC_MASTER_MODE_FREERUN) {
       
   315         // nothing to configure. check for pending EEPROM write operations.
       
   316         list_for_each_entry(slave, &master->slaves, list) {
       
   317             if (!slave->new_eeprom_data) continue;
       
   318 
       
   319             if (!slave->online || slave->error_flag) {
       
   320                 kfree(slave->new_eeprom_data);
       
   321                 slave->new_eeprom_data = NULL;
       
   322                 EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
       
   323                        slave->ring_position);
       
   324                 continue;
       
   325             }
       
   326 
       
   327             // found pending EEPROM write operation. execute it!
       
   328             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
       
   329             fsm->sii_offset = 0x0000;
       
   330             memcpy(fsm->sii_value, slave->new_eeprom_data, 2);
       
   331             fsm->sii_mode = 1;
       
   332             fsm->sii_state = ec_fsm_sii_start_writing;
       
   333             fsm->slave = slave;
       
   334             fsm->master_state = ec_fsm_master_write_eeprom;
       
   335             fsm->master_state(fsm); // execute immediately
       
   336             return;
       
   337         }
       
   338     }
       
   339 
       
   340     // nothing to do. restart master state machine.
       
   341     fsm->master_state = ec_fsm_master_start;
       
   342     fsm->master_state(fsm); // execute immediately
   278 }
   343 }
   279 
   344 
   280 /*****************************************************************************/
   345 /*****************************************************************************/
   281 
   346 
   282 /**
   347 /**
   287                                            /**< finite state machine */)
   352                                            /**< finite state machine */)
   288 {
   353 {
   289     ec_master_t *master = fsm->master;
   354     ec_master_t *master = fsm->master;
   290     ec_slave_t *slave = fsm->slave;
   355     ec_slave_t *slave = fsm->slave;
   291 
   356 
   292     // have all states been read?
   357     // is there another slave to query?
   293     if (slave->list.next != &master->slaves) {
   358     if (slave->list.next != &master->slaves) {
   294         // process next slave
   359         // process next slave
   295         fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   360         fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   296         ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address,
   361         ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address,
   297                          0x0130, 2);
   362                          0x0130, 2);
   298         ec_master_queue_datagram(master, &fsm->datagram);
   363         ec_master_queue_datagram(master, &fsm->datagram);
   299         fsm->master_state = ec_fsm_master_states;
   364         fsm->master_state = ec_fsm_master_read_states;
   300         return;
   365         return;
   301     }
   366     }
   302 
   367 
   303     // all slave stated read; check, if a bus validation has to be done
   368     // all slave states read
       
   369 
       
   370     // check, if a bus validation has to be done
   304     if (fsm->master_validation) {
   371     if (fsm->master_validation) {
   305         fsm->master_validation = 0;
   372         fsm->master_validation = 0;
   306         list_for_each_entry(slave, &master->slaves, list) {
   373         list_for_each_entry(slave, &master->slaves, list) {
   307             if (slave->online) continue;
   374             if (slave->online) continue;
   308 
   375 
   316             fsm->sii_state(fsm); // execute immediately
   383             fsm->sii_state(fsm); // execute immediately
   317             return;
   384             return;
   318         }
   385         }
   319     }
   386     }
   320 
   387 
   321     fsm->master_state = ec_fsm_master_proc_states;
   388     ec_fsm_master_action_process_states(fsm);
   322     fsm->master_state(fsm); // execute immediately
       
   323 }
   389 }
   324 
   390 
   325 /*****************************************************************************/
   391 /*****************************************************************************/
   326 
   392 
   327 /**
   393 /**
   328    Master state: STATES.
   394    Master state: STATES.
   329    Fetches the AL- and online state of a slave.
   395    Fetches the AL- and online state of a slave.
   330 */
   396 */
   331 
   397 
   332 void ec_fsm_master_states(ec_fsm_t *fsm /**< finite state machine */)
   398 void ec_fsm_master_read_states(ec_fsm_t *fsm /**< finite state machine */)
   333 {
   399 {
   334     ec_slave_t *slave = fsm->slave;
   400     ec_slave_t *slave = fsm->slave;
   335     ec_datagram_t *datagram = &fsm->datagram;
   401     ec_datagram_t *datagram = &fsm->datagram;
   336     uint8_t new_state;
   402     uint8_t new_state;
   337 
   403 
   374 }
   440 }
   375 
   441 
   376 /*****************************************************************************/
   442 /*****************************************************************************/
   377 
   443 
   378 /**
   444 /**
   379    Master state: PROC_STATES.
       
   380    Processes the slave states.
       
   381 */
       
   382 
       
   383 void ec_fsm_master_proc_states(ec_fsm_t *fsm /**< finite state machine */)
       
   384 {
       
   385     ec_master_t *master = fsm->master;
       
   386     ec_slave_t *slave;
       
   387 
       
   388     // check if any slaves are not in the state, they're supposed to be
       
   389     list_for_each_entry(slave, &master->slaves, list) {
       
   390         if (slave->error_flag ||
       
   391             !slave->online ||
       
   392             slave->requested_state == EC_SLAVE_STATE_UNKNOWN ||
       
   393             slave->current_state == slave->requested_state) continue;
       
   394 
       
   395         EC_INFO("Changing state of slave %i from ", slave->ring_position);
       
   396         ec_print_states(slave->current_state);
       
   397         printk(" to ");
       
   398         ec_print_states(slave->requested_state);
       
   399         printk(".\n");
       
   400 
       
   401         fsm->slave = slave;
       
   402         fsm->slave_state = ec_fsm_slave_conf;
       
   403         fsm->change_new = EC_SLAVE_STATE_INIT;
       
   404         fsm->change_state = ec_fsm_change_start;
       
   405         fsm->master_state = ec_fsm_master_conf;
       
   406         fsm->master_state(fsm); // execute immediately
       
   407         return;
       
   408     }
       
   409 
       
   410     if (master->mode == EC_MASTER_MODE_FREERUN) {
       
   411         // nothing to configure. check for pending EEPROM write operations.
       
   412         list_for_each_entry(slave, &master->slaves, list) {
       
   413             if (!slave->new_eeprom_data) continue;
       
   414 
       
   415             if (!slave->online || slave->error_flag) {
       
   416                 kfree(slave->new_eeprom_data);
       
   417                 slave->new_eeprom_data = NULL;
       
   418                 EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
       
   419                        slave->ring_position);
       
   420                 continue;
       
   421             }
       
   422 
       
   423             // found pending EEPROM write operation. execute it!
       
   424             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
       
   425             fsm->sii_offset = 0x0000;
       
   426             memcpy(fsm->sii_value, slave->new_eeprom_data, 2);
       
   427             fsm->sii_mode = 1;
       
   428             fsm->sii_state = ec_fsm_sii_start_writing;
       
   429             fsm->slave = slave;
       
   430             fsm->master_state = ec_fsm_master_eeprom;
       
   431             fsm->master_state(fsm); // execute immediately
       
   432             return;
       
   433         }
       
   434     }
       
   435 
       
   436     // nothing to do. restart master state machine.
       
   437     fsm->master_state = ec_fsm_master_start;
       
   438     fsm->master_state(fsm); // execute immediately
       
   439 }
       
   440 
       
   441 /*****************************************************************************/
       
   442 
       
   443 /**
       
   444    Master state: VALIDATE_VENDOR.
   445    Master state: VALIDATE_VENDOR.
   445    Validates the vendor ID of a slave.
   446    Validates the vendor ID of a slave.
   446 */
   447 */
   447 
   448 
   448 void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
   449 void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
   478 }
   479 }
   479 
   480 
   480 /*****************************************************************************/
   481 /*****************************************************************************/
   481 
   482 
   482 /**
   483 /**
   483    Master state: VALIDATE_PRODUCT.
   484    Master action: ADDRESS.
   484    Validates the product ID of a slave.
       
   485 */
       
   486 
       
   487 void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
       
   488 {
       
   489     ec_slave_t *slave = fsm->slave;
       
   490 
       
   491     fsm->sii_state(fsm); // execute SII state machine
       
   492 
       
   493     if (fsm->sii_state == ec_fsm_sii_error) {
       
   494         fsm->slave->error_flag = 1;
       
   495         EC_ERR("Failed to validate product code of slave %i.\n",
       
   496                slave->ring_position);
       
   497         fsm->master_state = ec_fsm_master_start;
       
   498         fsm->master_state(fsm); // execute immediately
       
   499         return;
       
   500     }
       
   501 
       
   502     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   503 
       
   504     if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
       
   505         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
       
   506         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
       
   507                EC_READ_U32(fsm->sii_value));
       
   508         fsm->master_state = ec_fsm_master_start;
       
   509         fsm->master_state(fsm); // execute immediately
       
   510         return;
       
   511     }
       
   512 
       
   513     // have all states been validated?
       
   514     if (slave->list.next == &fsm->master->slaves) {
       
   515         fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
       
   516         fsm->master_state = ec_fsm_master_reconfigure;
       
   517         return;
       
   518     }
       
   519 
       
   520     // validate next slave
       
   521     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   522     fsm->master_state = ec_fsm_master_validate_vendor;
       
   523     fsm->sii_offset = 0x0008; // vendor ID
       
   524     fsm->sii_mode = 0;
       
   525     fsm->sii_state = ec_fsm_sii_start_reading;
       
   526     fsm->sii_state(fsm); // execute immediately
       
   527 }
       
   528 
       
   529 /*****************************************************************************/
       
   530 
       
   531 /**
       
   532    Master state: RECONFIGURE.
       
   533    Looks for slave, that have lost their configuration and writes
   485    Looks for slave, that have lost their configuration and writes
   534    their station address, so that they can be reconfigured later.
   486    their station address, so that they can be reconfigured later.
   535 */
   487 */
   536 
   488 
   537 void ec_fsm_master_reconfigure(ec_fsm_t *fsm /**< finite state machine */)
   489 void ec_fsm_master_action_addresses(ec_fsm_t *fsm /**< finite state machine */)
   538 {
   490 {
   539     ec_datagram_t *datagram = &fsm->datagram;
   491     ec_datagram_t *datagram = &fsm->datagram;
   540 
   492 
   541     while (fsm->slave->online) {
   493     while (fsm->slave->online) {
   542         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
   494         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
   552 
   504 
   553     // write station address
   505     // write station address
   554     ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
   506     ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
   555     EC_WRITE_U16(datagram->data, fsm->slave->station_address);
   507     EC_WRITE_U16(datagram->data, fsm->slave->station_address);
   556     ec_master_queue_datagram(fsm->master, datagram);
   508     ec_master_queue_datagram(fsm->master, datagram);
   557     fsm->master_state = ec_fsm_master_address;
   509     fsm->master_state = ec_fsm_master_rewrite_addresses;
       
   510 }
       
   511 
       
   512 /*****************************************************************************/
       
   513 
       
   514 /**
       
   515    Master state: VALIDATE_PRODUCT.
       
   516    Validates the product ID of a slave.
       
   517 */
       
   518 
       
   519 void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
       
   520 {
       
   521     ec_slave_t *slave = fsm->slave;
       
   522 
       
   523     fsm->sii_state(fsm); // execute SII state machine
       
   524 
       
   525     if (fsm->sii_state == ec_fsm_sii_error) {
       
   526         fsm->slave->error_flag = 1;
       
   527         EC_ERR("Failed to validate product code of slave %i.\n",
       
   528                slave->ring_position);
       
   529         fsm->master_state = ec_fsm_master_start;
       
   530         fsm->master_state(fsm); // execute immediately
       
   531         return;
       
   532     }
       
   533 
       
   534     if (fsm->sii_state != ec_fsm_sii_end) return;
       
   535 
       
   536     if (EC_READ_U32(fsm->sii_value) != slave->sii_product_code) {
       
   537         EC_ERR("Slave %i: invalid product code!\n", slave->ring_position);
       
   538         EC_ERR("expected 0x%08X, got 0x%08X.\n", slave->sii_product_code,
       
   539                EC_READ_U32(fsm->sii_value));
       
   540         fsm->master_state = ec_fsm_master_start;
       
   541         fsm->master_state(fsm); // execute immediately
       
   542         return;
       
   543     }
       
   544 
       
   545     // have all states been validated?
       
   546     if (slave->list.next == &fsm->master->slaves) {
       
   547         fsm->slave = list_entry(fsm->master->slaves.next, ec_slave_t, list);
       
   548         // start writing addresses to offline slaves
       
   549         ec_fsm_master_action_addresses(fsm);
       
   550         return;
       
   551     }
       
   552 
       
   553     // validate next slave
       
   554     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
       
   555     fsm->master_state = ec_fsm_master_validate_vendor;
       
   556     fsm->sii_offset = 0x0008; // vendor ID
       
   557     fsm->sii_mode = 0;
       
   558     fsm->sii_state = ec_fsm_sii_start_reading;
       
   559     fsm->sii_state(fsm); // execute immediately
   558 }
   560 }
   559 
   561 
   560 /*****************************************************************************/
   562 /*****************************************************************************/
   561 
   563 
   562 /**
   564 /**
   563    Master state: ADDRESS.
   565    Master state: ADDRESS.
   564    Checks, if the new station address has been written to the slave.
   566    Checks, if the new station address has been written to the slave.
   565 */
   567 */
   566 
   568 
   567 void ec_fsm_master_address(ec_fsm_t *fsm /**< finite state machine */)
   569 void ec_fsm_master_rewrite_addresses(ec_fsm_t *fsm
       
   570                                      /**< finite state machine */
       
   571                                      )
   568 {
   572 {
   569     ec_slave_t *slave = fsm->slave;
   573     ec_slave_t *slave = fsm->slave;
   570     ec_datagram_t *datagram = &fsm->datagram;
   574     ec_datagram_t *datagram = &fsm->datagram;
   571 
   575 
   572     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   576     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   580         return;
   584         return;
   581     }
   585     }
   582 
   586 
   583     // check next slave
   587     // check next slave
   584     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   588     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   585     fsm->master_state = ec_fsm_master_reconfigure;
   589     // Write new station address to slave
   586     fsm->master_state(fsm); // execute immediately
   590     ec_fsm_master_action_addresses(fsm);
   587 }
   591 }
   588 
   592 
   589 /*****************************************************************************/
   593 /*****************************************************************************/
   590 
   594 
   591 /**
   595 /**
   592    Master state: SCAN.
   596    Master state: SCAN.
   593    Executes the sub-statemachine for the scanning of a slave.
   597    Executes the sub-statemachine for the scanning of a slave.
   594 */
   598 */
   595 
   599 
   596 void ec_fsm_master_scan(ec_fsm_t *fsm /**< finite state machine */)
   600 void ec_fsm_master_scan_slaves(ec_fsm_t *fsm /**< finite state machine */)
   597 {
   601 {
   598     ec_master_t *master = fsm->master;
   602     ec_master_t *master = fsm->master;
   599     ec_slave_t *slave = fsm->slave;
   603     ec_slave_t *slave = fsm->slave;
   600     uint16_t coupler_index, coupler_subindex;
   604     uint16_t coupler_index, coupler_subindex;
   601     uint16_t reverse_coupler_index, current_coupler_index;
   605     uint16_t reverse_coupler_index, current_coupler_index;
   687 /**
   691 /**
   688    Master state: CONF.
   692    Master state: CONF.
   689    Starts configuring a slave.
   693    Starts configuring a slave.
   690 */
   694 */
   691 
   695 
   692 void ec_fsm_master_conf(ec_fsm_t *fsm /**< finite state machine */)
   696 void ec_fsm_master_configure_slave(ec_fsm_t *fsm
       
   697                                    /**< finite state machine */
       
   698                                    )
   693 {
   699 {
   694     fsm->slave_state(fsm); // execute slave's state machine
   700     fsm->slave_state(fsm); // execute slave's state machine
   695     if (fsm->slave_state != ec_fsm_slave_end) return;
   701     if (fsm->slave_state != ec_fsm_slave_end) return;
   696     fsm->master_state = ec_fsm_master_proc_states;
   702 
   697     fsm->master_state(fsm); // execute immediately
   703     ec_fsm_master_action_process_states(fsm);
   698 }
   704 }
   699 
   705 
   700 /*****************************************************************************/
   706 /*****************************************************************************/
   701 
   707 
   702 /**
   708 /**
   703    Master state: EEPROM.
   709    Master state: EEPROM.
   704 */
   710 */
   705 
   711 
   706 void ec_fsm_master_eeprom(ec_fsm_t *fsm /**< finite state machine */)
   712 void ec_fsm_master_write_eeprom(ec_fsm_t *fsm /**< finite state machine */)
   707 {
   713 {
   708     ec_slave_t *slave = fsm->slave;
   714     ec_slave_t *slave = fsm->slave;
   709 
   715 
   710     fsm->sii_state(fsm); // execute SII state machine
   716     fsm->sii_state(fsm); // execute SII state machine
   711 
   717 
   734     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
   740     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
   735     kfree(slave->new_eeprom_data);
   741     kfree(slave->new_eeprom_data);
   736     slave->new_eeprom_data = NULL;
   742     slave->new_eeprom_data = NULL;
   737 
   743 
   738     // restart master state machine.
   744     // restart master state machine.
   739     fsm->master_state = ec_fsm_master_start;
   745     fsm->master_state = ec_fsm_master_start; // TODO: Scan slaves!
   740     fsm->master_state(fsm); // execute immediately
   746     fsm->master_state(fsm); // execute immediately
   741     return;
   747     return;
   742 }
   748 }
   743 
   749 
   744 /******************************************************************************
   750 /******************************************************************************