MODULE osm$spi_data_collector;
?? PUSH (LISTEXT := ON) ??
*copyc amp$get_segment_pointer
*copyc amp$set_segment_eoi
*copyc amp$set_segment_position
*copyc clt$parameter_list
*copyc fsp$close_file
*copyc fsp$open_file
*copyc osd$default_pragmats
*copyc osp$collect_spi_data
*copyc osp$disestablish_cond_handler
*copyc osp$establish_condition_handler
*copyc osp$free_spi_environment
*copyc osp$initialize_spi_environment
*copyc ost$spi_control
*copyc ost$spi_data_header
*copyc ost$status
*copyc pmp$get_legible_date_time
*copyc pmp$long_term_wait
?? POP ??

?? TITLE := 'PROCEDURE osp$spi_data_collector', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$spi_data_collector
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

    VAR
      collection_file_id: amt$file_identifier,
      collection_file_is_open: boolean,
      collection_file_pointer: amt$segment_pointer,
      end_of_information_set: boolean,
      file_header_information: ^ost$spi_data_header,
      first_time: boolean,
      local_status: ost$status,
      spi_collection_running: boolean,
      spi_control: ost$spi_control,
      spi_environment_is_free: boolean;

?? TITLE := 'PROCEDURE handler', EJECT ??

    PROCEDURE handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           stack_frame_save: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

{
{ This procedure is the block exit handler for the SPI data collector.
{ It will try to clean up the SPI collector environment if the collector
{ task abnormally terminates.
{
{ All statements are executed in order. Status is not checked since
{ we are trying to clean up the environment and all procedures must
{ be called.
{
      IF spi_collection_running THEN
        osp$collect_spi_data (collection_file_pointer.cell_pointer,
              spi_collection_running, status);
        amp$set_segment_position (collection_file_id, collection_file_pointer,
              status);
        IF NOT end_of_information_set THEN
          amp$set_segment_eoi (collection_file_id, collection_file_pointer,
                status);
          end_of_information_set := TRUE;
        IFEND;
        spi_collection_running := FALSE;
      IFEND;

      IF collection_file_is_open THEN
        fsp$close_file (collection_file_id, status);
        collection_file_is_open := FALSE;
      IFEND;

      IF NOT spi_environment_is_free THEN
        osp$free_spi_environment (status);
        spi_environment_is_free := FALSE;
      IFEND;
      handler_status.normal := TRUE;

    PROCEND handler;

?? TITLE := 'PROCEDURE osp$spi_data_collector', EJECT ??
{
{ This procedure is the main control procedure for collecting SPI data.
{ This task is an asynchronous task. It gets data from the parent task and
{ gives it to the PP and takes the PP driver data and places it into a segment
{ access file.
{
    collection_file_is_open := FALSE;
    end_of_information_set := FALSE;
    spi_collection_running := FALSE;
    spi_environment_is_free := FALSE;

    osp$establish_condition_handler (^handler, TRUE);
    osp$initialize_spi_environment (spi_control, status);
    IF NOT status.normal THEN
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

    fsp$open_file (spi_control.collection_file, amc$segment, NIL, NIL, NIL,
          NIL, NIL, collection_file_id, status);
    IF NOT status.normal THEN
      fsp$close_file (collection_file_id, local_status);
      osp$free_spi_environment (local_status);
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;
    collection_file_is_open := TRUE;

    amp$get_segment_pointer (collection_file_id, amc$cell_pointer,
          collection_file_pointer, status);
    IF NOT status.normal THEN
      fsp$close_file (collection_file_id, local_status);
      osp$free_spi_environment (local_status);
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

{ Set up the header information for the SPI collection file.

    file_header_information := collection_file_pointer.cell_pointer;
    file_header_information^.number_of_spi_samples :=
          spi_control.number_of_spi_samples;
    file_header_information^.spi_sampling_interval :=
          spi_control.spi_sampling_interval;
    file_header_information^.spi_identifier := spi_control.spi_identifier;
    file_header_information^.run_comments := spi_control.data_string;
    file_header_information^.number_of_samples_collected := 0;
    pmp$get_legible_date_time (osc$month_date,
          file_header_information^.sample_date, osc$ampm_time,
          file_header_information^.sample_time, status);
    collection_file_pointer.cell_pointer :=
          #ADDRESS (#RING (collection_file_pointer.cell_pointer),
          #SEGMENT (collection_file_pointer.cell_pointer),
          #OFFSET (collection_file_pointer.cell_pointer) +
          #SIZE (ost$spi_data_buffer));

{
{ This loop is the main collection loop for the collection of SPI data.
{ It is taken out of wait by interrupts from the SPI PP driver or by
{ the parent task issuing a ready task in response to a SPI command.
{
    spi_collection_running := TRUE;

  /data_collection_loop/
    WHILE TRUE DO
      osp$collect_spi_data (collection_file_pointer.cell_pointer,
            spi_collection_running, status);
      amp$set_segment_position (collection_file_id, collection_file_pointer,
            status);
      IF NOT spi_collection_running THEN
        EXIT /data_collection_loop/;
      IFEND;
      pmp$long_term_wait (30000, 30000);
    WHILEND /data_collection_loop/;
{
{ Now the collection of SPI data has finished. Close the collection file
{ and free the SPI environment for the next user.
{
    amp$set_segment_eoi (collection_file_id, collection_file_pointer, status);
    end_of_information_set := TRUE;
    fsp$close_file (collection_file_id, status);
    collection_file_is_open := FALSE;
    osp$free_spi_environment (status);
    spi_environment_is_free := TRUE;
    osp$disestablish_cond_handler;

  PROCEND osp$spi_data_collector;

MODEND osm$spi_data_collector;

