Example #1
0
void Player::on_set_public_data(void* argument) {
    PublicDataRequest* pdr = static_cast<PublicDataRequest*>(argument);

    if(!pdr->starts_with(player_checksum)) return;

    if(pdr->second_element_is(abort_play_checksum)) {
        abort_command("", &(StreamOutput::NullStream));
        pdr->set_taken();
    }
}
Example #2
0
void Player::on_halt(void* argument)
{
    if(argument == nullptr && this->playing_file ) {
        abort_command("1", &(StreamOutput::NullStream));
    }
}
Example #3
0
void Player::on_gcode_received(void *argument)
{
    Gcode *gcode = static_cast<Gcode *>(argument);
    string args = get_arguments(gcode->get_command());
    if (gcode->has_m) {
        if (gcode->m == 21) { // Dummy code; makes Octoprint happy -- supposed to initialize SD card
            mounter.remount();
            gcode->stream->printf("SD card ok\r\n");

        } else if (gcode->m == 23) { // select file
            this->filename = "/sd/" + args; // filename is whatever is in args
            this->current_stream = nullptr;

            if(this->current_file_handler != NULL) {
                this->playing_file = false;
                fclose(this->current_file_handler);
            }
            this->current_file_handler = fopen( this->filename.c_str(), "r");

            if(this->current_file_handler == NULL) {
                gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str());
                return;

            } else {
                // get size of file
                int result = fseek(this->current_file_handler, 0, SEEK_END);
                if (0 != result) {
                    this->file_size = 0;
                } else {
                    this->file_size = ftell(this->current_file_handler);
                    fseek(this->current_file_handler, 0, SEEK_SET);
                }
                gcode->stream->printf("File opened:%s Size:%ld\r\n", this->filename.c_str(), this->file_size);
                gcode->stream->printf("File selected\r\n");
            }


            this->played_cnt = 0;
            this->elapsed_secs = 0;

        } else if (gcode->m == 24) { // start print
            if (this->current_file_handler != NULL) {
                this->playing_file = true;
                // this would be a problem if the stream goes away before the file has finished,
                // so we attach it to the kernel stream, however network connections from pronterface
                // do not connect to the kernel streams so won't see this FIXME
                this->reply_stream = THEKERNEL->streams;
            }

        } else if (gcode->m == 25) { // pause print
            this->playing_file = false;

        } else if (gcode->m == 26) { // Reset print. Slightly different than M26 in Marlin and the rest
            if(this->current_file_handler != NULL) {
                string currentfn = this->filename.c_str();
                unsigned long old_size = this->file_size;

                // abort the print
                abort_command("", gcode->stream);

                if(!currentfn.empty()) {
                    // reload the last file opened
                    this->current_file_handler = fopen(currentfn.c_str() , "r");

                    if(this->current_file_handler == NULL) {
                        gcode->stream->printf("file.open failed: %s\r\n", currentfn.c_str());
                    } else {
                        this->filename = currentfn;
                        this->file_size = old_size;
                        this->current_stream = nullptr;
                    }
                }
            } else {
                gcode->stream->printf("No file loaded\r\n");
            }

        } else if (gcode->m == 27) { // report print progress, in format used by Marlin
            progress_command("-b", gcode->stream);

        } else if (gcode->m == 32) { // select file and start print
            // Get filename
            this->filename = "/sd/" + args; // filename is whatever is in args including spaces
            this->current_stream = nullptr;

            if(this->current_file_handler != NULL) {
                this->playing_file = false;
                fclose(this->current_file_handler);
            }

            this->current_file_handler = fopen( this->filename.c_str(), "r");
            if(this->current_file_handler == NULL) {
                gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str());
            } else {
                this->playing_file = true;

                // get size of file
                int result = fseek(this->current_file_handler, 0, SEEK_END);
                if (0 != result) {
                        file_size = 0;
                } else {
                        file_size = ftell(this->current_file_handler);
                        fseek(this->current_file_handler, 0, SEEK_SET);
                }
            }

            this->played_cnt = 0;
            this->elapsed_secs = 0;

        } else if (gcode->m == 600) { // suspend print, Not entirely Marlin compliant, M600.1 will leave the heaters on
            this->suspend_command((gcode->subcode == 1)?"h":"", gcode->stream);

        } else if (gcode->m == 601) { // resume print
            this->resume_command("", gcode->stream);
        }

    }else if(gcode->has_g) {
        if(gcode->g == 28) { // homing cancels suspend
            if(this->suspended) {
                // clean up
                this->suspended= false;
                THEROBOT->pop_state();
                this->saved_temperatures.clear();
                this->was_playing_file= false;
                this->suspend_loops= 0;
            }
        }
    }
}
Example #4
0
void process_sq(NVMEState *n, uint16_t sq_id)
{
    target_phys_addr_t addr;
    uint16_t cq_id;
    NVMECmd sqe;
    NVMECQE cqe;
    NVMEStatusField *sf = (NVMEStatusField *) &cqe.status;

    if (n->sq[sq_id].dma_addr == 0 || n->cq[n->sq[sq_id].cq_id].dma_addr
        == 0) {
        LOG_ERR("Required Submission/Completion Queue does not exist");
        n->sq[sq_id].head = n->sq[sq_id].tail = 0;
        goto exit;
    }
    cq_id = n->sq[sq_id].cq_id;
    if (is_cq_full(n, cq_id)) {
        return;
    }
    memset(&cqe, 0, sizeof(cqe));

    LOG_DBG("%s(): called", __func__);

    /* Process SQE */
    if (sq_id == ASQ_ID || n->sq[sq_id].phys_contig) {
        addr = n->sq[sq_id].dma_addr + n->sq[sq_id].head * sizeof(sqe);
    } else {
        /* PRP implementation */
        addr = find_discontig_queue_entry(n->page_size, n->sq[sq_id].head,
            sizeof(sqe), n->sq[sq_id].dma_addr);
    }
    nvme_dma_mem_read(addr, (uint8_t *)&sqe, sizeof(sqe));

    if (n->abort) {
        if (abort_command(n, sq_id, &sqe)) {
            incr_sq_head(&n->sq[sq_id]);
            return;
        }
    }

    incr_sq_head(&n->sq[sq_id]);

    if (sq_id == ASQ_ID) {
        nvme_admin_command(n, &sqe, &cqe);
    } else {
       /* TODO add support for IO commands with different sizes of Q elements */
        nvme_io_command(n, &sqe, &cqe);
    }

    /* Filling up the CQ entry */
    cqe.sq_id = sq_id;
    cqe.sq_head = n->sq[sq_id].head;
    cqe.command_id = sqe.cid;

    sf->p = n->cq[cq_id].phase_tag;
    sf->m = 0;
    sf->dnr = 0; /* TODO add support for dnr */

    /* write cqe to completion queue */
    if (cq_id == ACQ_ID || n->cq[cq_id].phys_contig) {
        addr = n->cq[cq_id].dma_addr + n->cq[cq_id].tail * sizeof(cqe);
    } else {
        /* PRP implementation */
        addr = find_discontig_queue_entry(n->page_size, n->cq[cq_id].tail,
            sizeof(cqe), n->cq[cq_id].dma_addr);
    }
    nvme_dma_mem_write(addr, (uint8_t *)&cqe, sizeof(cqe));

    incr_cq_tail(&n->cq[cq_id]);

    if (cq_id == ACQ_ID) {
        /*
         3.1.9 says: "This queue is always associated
                 with interrupt vector 0"
        */
        msix_notify(&(n->dev), 0);
        return;
    }

    if (n->cq[cq_id].irq_enabled) {
        msix_notify(&(n->dev), n->cq[cq_id].vector);
    } else {
        LOG_NORM("kw q: IRQ not enabled for CQ: %d", cq_id);
    }

exit:
    return;

}
Example #5
0
void Player::on_main_loop(void *argument)
{
    if(suspended && suspend_loops > 0) {
        // if we are suspended we need to allow main loop to cycle a few times then finish off the suspend processing
        if(--suspend_loops == 0) {
            suspend_part2();
            return;
        }
    }

    if( !this->booted ) {
        this->booted = true;
        if( this->on_boot_gcode_enable ) {
            this->play_command(this->on_boot_gcode, THEKERNEL->serial);
        } else {
            //THEKERNEL->serial->printf("On boot gcode disabled! skipping...\n");
        }
    }

    if( this->playing_file ) {
        if(THEKERNEL->is_halted()) {
            abort_command("1", &(StreamOutput::NullStream));
            return;
        }

        char buf[130]; // lines upto 128 characters are allowed, anything longer is discarded
        bool discard = false;

        while(fgets(buf, sizeof(buf), this->current_file_handler) != NULL) {
            int len = strlen(buf);
            if(len == 0) continue; // empty line? should not be possible
            if(buf[len - 1] == '\n' || feof(this->current_file_handler)) {
                if(discard) { // we are discarding a long line
                    discard = false;
                    continue;
                }
                if(len == 1) continue; // empty line

                this->current_stream->printf("%s", buf);
                struct SerialMessage message;
                message.message = buf;
                message.stream = this->current_stream;

                // waits for the queue to have enough room
                THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message);
                played_cnt += len;
                return; // we feed one line per main loop

            } else {
                // discard long line
                this->current_stream->printf("Warning: Discarded long line\n");
                discard = true;
            }
        }

        this->playing_file = false;
        this->filename = "";
        played_cnt = 0;
        file_size = 0;
        fclose(this->current_file_handler);
        current_file_handler = NULL;
        this->current_stream = NULL;

        if(this->reply_stream != NULL) {
            // if we were printing from an M command from pronterface we need to send this back
            this->reply_stream->printf("Done printing file\r\n");
            this->reply_stream = NULL;
        }
    }
}
Example #6
0
void Player::on_gcode_received(void *argument) {
    Gcode *gcode = static_cast<Gcode*>(argument);
    string args= get_arguments(gcode->command);
    if (gcode->has_m) {
        if (gcode->m == 21) { // Dummy code; makes Octoprint happy -- supposed to initialize SD card
            gcode->mark_as_taken();
            gcode->stream->printf("SD card ok\r\n");

        }else if (gcode->m == 23) { // select file
            gcode->mark_as_taken();
            // Get filename
            this->filename= "/sd/" + this->absolute_from_relative(shift_parameter( args ));
            this->current_stream = &(StreamOutput::NullStream);

            if(this->current_file_handler != NULL) {
                this->playing_file = false;
                fclose(this->current_file_handler);
            }
            this->current_file_handler = fopen( this->filename.c_str(), "r");
            // get size of file
            int result = fseek(this->current_file_handler, 0, SEEK_END);
            if (0 != result){
                    gcode->stream->printf("WARNING - Could not get file size\r\n");
                    file_size= -1;
            }else{
                    file_size= ftell(this->current_file_handler);
                    fseek(this->current_file_handler, 0, SEEK_SET);
            }

            if(this->current_file_handler == NULL){
                gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str());
            }else{
                gcode->stream->printf("File opened:%s Size:%ld\r\n", this->filename.c_str(),file_size);
                gcode->stream->printf("File selected\r\n");
            }

            this->played_cnt= 0;
            this->elapsed_secs= 0;

        }else if (gcode->m == 24) { // start print
            gcode->mark_as_taken();
            if (this->current_file_handler != NULL) {
                this->playing_file = true;
                this->reply_stream= gcode->stream;
            }

        }else if (gcode->m == 25) { // pause print
            gcode->mark_as_taken();
            this->playing_file = false;

        }else if (gcode->m == 26) { // Reset print. Slightly different than M26 in Marlin and the rest
            gcode->mark_as_taken();
            if(this->current_file_handler != NULL){
                // abort the print
                abort_command("", gcode->stream);

                // reload the last file opened
                this->current_file_handler = fopen( this->filename.c_str(), "r");

                if(this->current_file_handler == NULL){
                    gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str());
                }else{
                    // get size of file
                    int result = fseek(this->current_file_handler, 0, SEEK_END);
                    if (0 != result){
                            gcode->stream->printf("WARNING - Could not get file size\r\n");
                            file_size= 0;
                    }else{
                            file_size= ftell(this->current_file_handler);
                            fseek(this->current_file_handler, 0, SEEK_SET);
                    }
                }
            }else{
                gcode->stream->printf("No file loaded\r\n");
            }

        }else if (gcode->m == 27) { // report print progress, in format used by Marlin
            gcode->mark_as_taken();
            progress_command("-b", gcode->stream);

        }else if (gcode->m == 32) { // select file and start print
            gcode->mark_as_taken();
            // Get filename
            this->filename= "/sd/" + this->absolute_from_relative(shift_parameter( args ));
            this->current_stream = &(StreamOutput::NullStream);

            if(this->current_file_handler != NULL) {
                this->playing_file = false;
                fclose(this->current_file_handler);
            }

            this->current_file_handler = fopen( this->filename.c_str(), "r");
            if(this->current_file_handler == NULL){
                gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str());
            }else{
                this->playing_file = true;
            }
        }
    }
}