En la línea
return (uint8_t) (time* (val[0] / val[1])) // 11 * (11/12)
la expresión entera (val [0] / val [1]), que se calcula primero debido a los paréntesis, devuelve cero y cualquier cosa multiplicada por cero también es cero.
Si has cambiado esa línea ligeramente para leer
return (uint8_t) ((time* val[0]) / val[1]) // (11*11)/12)
obtendría la respuesta 10, que está muy cerca del valor real de 121/12.
Las reglas normales para la división de enteros en C es truncar, redondear hacia abajo hacia -ve infinito. Si desea mantener la división de enteros, puede hacer que el redondeo ocurra si lo codifica explícitamente, agregando la mitad de su denominador a su numerador antes de la división.
Si tiene el espacio de código y el tiempo de ejecución, podría usar flotantes para obtener números que reconozca sin tener que preocuparse por el orden de cálculo y el truncamiento.
Una casa intermedia es utilizar la aritmética de enteros de punto fijo, si tiene el espacio de RAM para variables más largas. Trabaje en una base grande como 1000 (para una visualización conveniente de fracciones) o 65536 (para un conveniente corte de números en partes enteras y fraccionarias), y use unit16 o uint32s.