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(); } }
void Player::on_halt(void* argument) { if(argument == nullptr && this->playing_file ) { abort_command("1", &(StreamOutput::NullStream)); } }
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; } } } }
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; }
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; } } }
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; } } } }