/* * Restore the previous mode (if there is one) and clear the previous mode */ void restore_mode(uint8_t place) { set_mode(place, previous_modes[place]); previous_modes[place] = MODE_NONE; DEBUG4_VALUE("Restored mode ", place); DEBUG4_VALUELN("=", current_modes[place]); }
/* * Process a program configuration message */ boolean ProgramManager::handle_msg(msg_program_t *msg) { DEBUG4_VALUE("handle_msg: program=", msg->type); DEBUG4_VALUELN(" output=", msg->hdr.output); /* Find the program to be executed */ hmtl_program_t *program = lookup_function(msg->type); if (program == NULL) { DEBUG1_VALUELN("handle_msg: invalid type: ", msg->type); return false; } /* Setup the tracker */ if (msg->hdr.output > num_outputs) { DEBUG1_VALUELN("handle_msg: invalid output: ", msg->hdr.output); return false; } if (outputs[msg->hdr.output] == NULL) { DEBUG1_VALUELN("handle_msg: NULL output: ", msg->hdr.output); return false; } program_tracker_t *tracker = trackers[msg->hdr.output]; if (program->type == HMTL_PROGRAM_NONE) { /* This is a message to clear the existing program so free the tracker */ free_tracker(msg->hdr.output); return true; } if (tracker != NULL) { DEBUG5_PRINTLN("handle_msg: reusing old tracker"); if (tracker->state) { DEBUG5_PRINTLN("handle_msg: deleting old state"); free(tracker->state); } } else { tracker = (program_tracker_t *)malloc(sizeof (program_tracker_t)); trackers[msg->hdr.output] = tracker; } tracker->program = program; tracker->flags = 0x0; tracker->program->setup(msg, tracker); return true; }
/* * Process a command message for a particular output */ int hmtl_handle_output_msg(msg_hdr_t *msg_hdr, byte num_outputs, output_hdr_t *outputs[], void *objects[]) { if (msg_hdr->type != MSG_TYPE_OUTPUT) { DEBUG_ERR("hmtl_handle_msg: incorrect msg type"); return -1; } output_hdr_t *msg = (output_hdr_t *)(msg_hdr + 1); DEBUG4_VALUE("hmtl_handle_msg: type=", msg->type); DEBUG4_VALUELN(" out=", msg->output); if (msg->output >= num_outputs) { DEBUG_ERR("hmtl_handle_msg: output over max"); return -1; } output_hdr_t *out = outputs[msg->output]; void *data = (objects != NULL ? objects[msg->output] : NULL); switch (msg->type) { case HMTL_OUTPUT_VALUE: { msg_value_t *msg2 = (msg_value_t *)msg; uint8_t values[3]; for (byte i = 0; i < 3; i++) { values[i] = msg2->value; } hmtl_set_output_rgb(out, data, values); break; } case HMTL_OUTPUT_RGB: { msg_rgb_t *msg2 = (msg_rgb_t *)msg; hmtl_set_output_rgb(out, data, msg2->values); break; } default: { // Unknown output type DEBUG_ERR("Unhandled output type"); return -1; } } return 0; }
/* * Process a program configuration message */ boolean ProgramManager::handle_msg(msg_program_t *msg) { DEBUG4_VALUE("handle_msg: program=", msg->type); DEBUG4_VALUELN(" output=", msg->hdr.output); /* Find the program to be executed */ byte program = lookup_function(msg->type); if (program == NO_PROGRAM) { DEBUG1_VALUELN("handle_msg: invalid type: ", msg->type); return false; } /* Setup the tracker */ int starting_output, stop_output; if (msg->hdr.output == HMTL_ALL_OUTPUTS) { /* This should be applied to all outputs that can handle the message type */ starting_output = 0; stop_output = num_outputs; } else if (msg->hdr.output > num_outputs) { DEBUG1_VALUELN("handle_msg: invalid output: ", msg->hdr.output); return false; } else if (outputs[msg->hdr.output] == NULL) { DEBUG1_VALUELN("handle_msg: NULL output: ", msg->hdr.output); return false; } else { /* Only apply to the specified output */ starting_output = msg->hdr.output; stop_output = starting_output + 1; } for (int output = starting_output; output < stop_output; output++) { if (outputs[output] == NULL) continue; if (msg->type == HMTL_PROGRAM_NONE) { /* This is a message to clear the existing program so free the tracker */ DEBUG3_VALUELN("handle_msg: clear ", output); free_tracker(output); continue; } program_tracker_t *tracker; if (functions[program].program == NULL) { /* * This is an initialization-only command, set tracker to null */ DEBUG4_PRINTLN("handle_msg: trackerless") tracker = NULL; } else { /* If there was an active program on this output then clear the tracker */ free_tracker(output); /* Setup a tracker for this program */ tracker = get_tracker(output); tracker->program_index = program; tracker->flags = 0x0; } if (tracker) { // Record the output and object in the tracker tracker->output = outputs[output]; tracker->object = objects[output]; } /* Attempt to setup the program */ boolean success = functions[program].setup(msg, tracker, outputs[output], objects[output], this); if (!success) { if (tracker) { DEBUG4_VALUELN("handle_msg: NA on ", output); free_tracker(output); } continue; } DEBUG4_VALUELN("handle_msg: setup on ", output); } return true; }
/* Initialized the pins of an output */ int hmtl_setup_output(config_hdr_t *config, output_hdr_t *hdr, void *data) { DEBUG4_VALUE("hmtl_setup_output: type=", hdr->type); switch (hdr->type) { case HMTL_OUTPUT_VALUE: { config_value_t *out = (config_value_t *)hdr; DEBUG4_PRINT(" value"); pinMode(out->pin, OUTPUT); break; } case HMTL_OUTPUT_RGB: { config_rgb_t *out = (config_rgb_t *)hdr; DEBUG4_PRINT(" rgb"); for (int j = 0; j < 3; j++) { pinMode(out->pins[j], OUTPUT); } break; } case HMTL_OUTPUT_PROGRAM: { // config_program_t *out = (config_program_t *)hdr; DEBUG4_PRINT(" program"); break; } #ifdef USE_PIXELUTIL case HMTL_OUTPUT_PIXELS: { DEBUG4_PRINT(" pixels"); if (data != NULL) { config_pixels_t *out = (config_pixels_t *)hdr; PixelUtil *pixels = (PixelUtil *)data; pixels->init(out->numPixels, out->dataPin, out->clockPin, out->type); } else { DEBUG_ERR("Expected PixelUtil data struct for pixel configs"); return -1; } break; } #endif #ifdef USE_MPR121 case HMTL_OUTPUT_MPR121: { DEBUG4_PRINTLN(" mpr121"); if (data != NULL) { config_mpr121_t *out = (config_mpr121_t *)hdr; MPR121 *capSensor = (MPR121 *)data; capSensor->init(out->irqPin, out->useInterrupt, START_ADDRESS, // XXX - Only single address false, // XXX - No touch times false); // XXX - No auto enable for (int i = 0; i < MAX_MPR121_PINS; i++) { byte touch = out->thresholds[i] & 0x0F; byte release = (out->thresholds[i] & 0xF0) >> 4; if (touch || release) { capSensor->setThreshold(i, touch, release); } } } else { DEBUG_ERR("Expected MPR121 data struct for mpr121 configs"); return -1; } break; }