static bool handleRead(int size, const byte *msg, CONTEXT *context) { byte bind = msg[1]; byte *expr = (byte *) &msg[2]; byte slaveAddress = evalWord8Expr(&expr, context); byte byteCount = evalWord8Expr(&expr, context); byte *localMem, *local; int byteAvail; Wire.requestFrom((int) slaveAddress, (int) byteCount); byteAvail = Wire.available(); if (byteCount < byteAvail) { #ifdef DEBUG sendStringf("I2C: M"); #endif } else if (byteCount > byteAvail) { #ifdef DEBUG sendStringf("I2C: F"); #endif } localMem = (byte *) malloc(byteAvail+3); local = &localMem[3]; localMem[0] = EXPR_LIST8; localMem[1] = EXPR_LIT; localMem[2] = byteAvail; for (int i = 0; i < byteAvail; i++) { *local++ = Wire.read(); } if (context && context->bind) { putBindListPtr(context, bind, localMem); } else { sendReply(byteAvail+3, I2C_RESP_READ, localMem, context, bind); free(localMem); } return false; }
static bool handleBootTask(int size, const byte *msg, CONTEXT *context) { TASK *task; byte bind = msg[1]; byte *expr = (byte *) &msg[2]; byte id = evalWord8Expr(&expr, context); byte bootReply[2]; byte status = 0; if ((task = findTask(id)) != NULL) { unsigned int index = BOOT_TASK_INDEX_START; EEPROM[ 0 ] = 'H'; EEPROM[ 1 ] = 'A'; EEPROM[ 2 ] = 'S'; EEPROM[ 3 ] = 'K'; EEPROM[ 4 ] = task->currLen & 0xFF; EEPROM[ 5 ] = task->currLen >> 8; EEPROM[ 6 ] = task->context->bindSize & 0xFF; EEPROM[ 7 ] = task->context->bindSize >> 8; for (unsigned int i=0;i<task->currLen;i++,index++) { EEPROM[ index ] = task->data[i]; } index = BOOT_TASK_INDEX_START; status = 1; for (unsigned int i=0;i<task->currLen;i++,index++) { if (EEPROM[ index ] != task->data[i]) status = 0; } }
static bool handleScheduleTask(int size, const byte *msg, CONTEXT *context) { byte *expr = (byte *) &msg[1]; byte id = evalWord8Expr(&expr, context); unsigned long deltaMillis = evalWord32Expr(&expr, context); return scheduleById(id, deltaMillis); }
static bool handleWrite(int size, const byte *msg, CONTEXT *context) { byte *expr = (byte *) &msg[1]; byte slaveAddress = evalWord8Expr(&expr, context); bool alloc; byte *list = evalList8Expr(&expr, context, &alloc); byte listSize = list[1]; const byte *data = &list[2]; byte byteCount = size; if (byteCount > listSize) byteCount = listSize; if (byteCount > 0) { Wire.beginTransmission(slaveAddress); Wire.write(data, byteCount); Wire.endTransmission(); delayMicroseconds(70); } if (alloc) free(list); return false; }
static bool handleReadRef(int type, int size, const byte *msg, CONTEXT *context) { byte bind = msg[2]; byte *expr = (byte *) &msg[3]; byte refIndex = evalWord8Expr(&expr, context); byte readReply[5]; byte *lVal; // ToDo: Check for param errors switch (type) { case REF_BOOL: readReply[0] = EXPR(EXPR_BOOL, EXPR_LIT); readReply[1] = *((bool *) haskinoRefs[refIndex].ref); sendReply(sizeof(bool)+1, REF_RESP_READ, readReply, context, bind); break; case REF_WORD8: readReply[0] = EXPR(EXPR_WORD8, EXPR_LIT); readReply[1] = *((uint8_t *) haskinoRefs[refIndex].ref); sendReply(sizeof(uint8_t)+1, REF_RESP_READ, readReply, context, bind); break; case REF_WORD16: readReply[0] = EXPR(EXPR_WORD16, EXPR_LIT); memcpy(&readReply[1], (byte *) haskinoRefs[refIndex].ref, sizeof(uint16_t)); sendReply(sizeof(uint16_t)+1, REF_RESP_READ, readReply, context, bind); break; case REF_WORD32: readReply[0] = EXPR(EXPR_WORD32, EXPR_LIT); memcpy(&readReply[1], (byte *) haskinoRefs[refIndex].ref, sizeof(uint32_t)); sendReply(sizeof(uint32_t)+1, REF_RESP_READ, readReply, context, bind); break; case REF_INT8: readReply[0] = EXPR(EXPR_INT8, EXPR_LIT); readReply[1] = *((int8_t *) haskinoRefs[refIndex].ref); sendReply(sizeof(int8_t)+1, REF_RESP_READ, readReply, context, bind); break; case REF_INT16: readReply[0] = EXPR(EXPR_INT16, EXPR_LIT); memcpy(&readReply[1], (byte *) haskinoRefs[refIndex].ref, sizeof(int16_t)); sendReply(sizeof(int16_t)+1, REF_RESP_READ, readReply, context, bind); break; case REF_INT32: readReply[0] = EXPR(EXPR_INT32, EXPR_LIT); memcpy(&readReply[1], (byte *) haskinoRefs[refIndex].ref, sizeof(int32_t)); sendReply(sizeof(int32_t)+1, REF_RESP_READ, readReply, context, bind); break; case REF_LIST8: lVal = (byte *) haskinoRefs[refIndex].ref; sendReply(lVal[1]+2, REF_RESP_READ, lVal, context, bind); break; case REF_FLOAT: readReply[0] = EXPR_F(EXPR_LIT); memcpy(&readReply[1], (byte *) haskinoRefs[refIndex].ref, sizeof(float)); sendReply(sizeof(float)+1, REF_RESP_READ, readReply, context, bind); break; } return false; }
static bool handleSetSpeed(int size, const byte *msg, CONTEXT *context) { byte *expr = (byte *) &msg[1]; byte stepperId = evalWord8Expr(&expr, context); uint32_t speed = evalWord32Expr(&expr, context); steppers[stepperId]->setSpeed(speed); return false; }
static bool handleAddToTask(int size, const byte *msg, CONTEXT *context) { byte *expr = (byte *) &msg[1]; byte id = evalWord8Expr(&expr, context); byte addSize = evalWord8Expr(&expr, context); const byte *data = expr; TASK *task; if ((task = findTask(id)) != NULL) { if (addSize + task->currLen <= task->size) { memcpy(&task->data[task->currLen], data, addSize); task->currLen += addSize; } } return false; }
static bool handleCreateTask(int size, const byte *msg, CONTEXT *context) { byte *expr = (byte *) &msg[1]; byte id = evalWord8Expr(&expr, context); unsigned int taskSize = evalWord16Expr(&expr, context); unsigned int bindSize = evalWord16Expr(&expr, context); return createById(id, taskSize, bindSize); }
static bool handle2Pin(int size, const byte *msg, CONTEXT *context) { Stepper *newStepper; byte bind = msg[1]; byte *expr = (byte *) &msg[2]; uint16_t steps = evalWord16Expr(&expr, context); byte pin1No = evalWord8Expr(&expr, context); byte pin2No = evalWord8Expr(&expr, context); byte stepperReply[3]; newStepper = new Stepper(steps, pin1No, pin2No); stepperReply[0] = EXPR_WORD8; stepperReply[1] = EXPR_LIT; stepperReply[2] = nextStepper; steppers[nextStepper++] = newStepper; sendReply(sizeof(stepperReply), STEP_RESP_2PIN, stepperReply, context, bind); return false; }
static bool handleDeleteTask(int size, const byte *msg, CONTEXT *context) { byte *expr = (byte *) &msg[1]; byte id = evalWord8Expr(&expr, context); TASK *task; if ((task = findTask(id)) != NULL) { deleteTask(task); } return false; }
static bool handleStep(int size, const byte *msg, CONTEXT *context) { byte bind = msg[1]; byte *expr = (byte *) &msg[2]; byte stepperId = evalWord8Expr(&expr, context); int16_t steps = evalInt16Expr(&expr, context); steppers[stepperId]->step(steps); if (context->currBlockLevel <= 0) { sendReply(0, STEP_RESP_STEP, NULL, context, bind); } return false; }
static bool handleWriteRef(int type, int size, const byte *msg, CONTEXT *context) { byte *expr = (byte *) &msg[2]; byte refIndex = evalWord8Expr(&expr, context); // ToDo: Check for param errors switch (type) { case REF_BOOL: storeBoolRef(expr, context, refIndex); break; case REF_WORD8: storeWord8Ref(expr, context, refIndex); break; case REF_WORD16: storeWord16Ref(expr, context, refIndex); break; case REF_WORD32: storeWord32Ref(expr, context, refIndex); break; case REF_INT8: storeInt8Ref(expr, context, refIndex); break; case REF_INT16: storeInt16Ref(expr, context, refIndex); break; case REF_INT32: storeInt32Ref(expr, context, refIndex); break; case REF_LIST8: storeList8Ref(expr, context, refIndex); break; case REF_FLOAT: storeFloatRef(expr, context, refIndex); break; } return false; }
static bool handleQuery(int size, const byte *msg, CONTEXT *context) { byte *expr = (byte *) &msg[2]; byte id = evalWord8Expr(&expr, context); byte queryReply[10]; uint16_t *sizeReply = (uint16_t *) queryReply; uint16_t *lenReply = (uint16_t *) &queryReply[2]; uint16_t *posReply = (uint16_t *) &queryReply[4]; uint32_t *millisReply = (uint32_t *) &queryReply[6]; TASK *task; if ((task = findTask(id)) != NULL) { *sizeReply = task->size; *lenReply = task->currLen; *posReply = task->currPos; *millisReply = task->millis - millis(); sendReply(sizeof(queryReply), SCHED_RESP_QUERY, queryReply, context, 0); } else { sendReply(0, SCHED_RESP_QUERY, queryReply, context, 0); } return false; }
void storeWord8Ref(byte *expr, CONTEXT *context, byte refIndex) { uint8_t w8Val = evalWord8Expr(&expr, context); *((uint8_t *) haskinoRefs[refIndex].ref) = w8Val; }