0

I am trying to implement a program with the following functionality.

An SPI-Master sends 3 bytes of data to an SPI-Slave. For certain value of these data bytes, certain functions are to be called. For example FF FF FF calls the function A, FF FF FE calls the function B, and so on.

One possible solution might be using switch case statement, however switching each possible case would be too long. Is there any other way to do this?

For example the last data byte has to set the PWM Dutycycle.

10 = 0000 1010
20 = 0001 0100
30 = 0001 1110
40 = 0010 1000
50 = 0011 0010
60 = 0011 1100
70 = 0100 0110
80 = 0101 0000
90 = 0101 1010 

The Slave receives the last Byte and for each of these cases it has to set the duty cycle. The Second Byte determines prescaler. For example:

0000 00001 0000 1010 sets the prescaler to 1 and duty cycle to 10
0000 00010 0000 1010 would set prescaler to 8 and duty cycle to 10

and so on.

So there are like many different combinations possible, what is the best way to handle all the possible cases?

ryyker
  • 22,849
  • 3
  • 43
  • 87
ichherzcplusplus
  • 321
  • 1
  • 13
  • 1
    There's not enough information to answer. What are the possibilities? If they're just two an `if` statement would suffice, for example. If there's a pattern you can use bitwise operators. Help us so we can help you. – Federico klez Culloca Oct 28 '19 at 11:44
  • 1
    Why would it be "too long"? You have to handle each case, so any handling will be of length O(N). (That is: on the other of the number of cases). – L. Scott Johnson Oct 28 '19 at 11:45
  • 1
    Please explain "each possible case". How many are there? What is the format? – Paul Ogilvie Oct 28 '19 at 11:45
  • 1
    If possible, could you please provide some code you have so far? – RobertS supports Monica Cellio Oct 28 '19 at 11:45
  • 1
    Depending on the format, you can use masks to get the relevant bits and use switch/case for these (now limited) number of cases. – Paul Ogilvie Oct 28 '19 at 11:46
  • 1
    Yes, there are alternatives to switch, but not necessarily an alternative that won't be equally long. – klutt Oct 28 '19 at 11:50
  • 1
    If the prototypes of the functions are the same, and the distinctions necessary inside the function can be derived from the unique values of inputs, you do not need a state machine at all. Use an array of _[function pointers](https://beginnersbook.com/2014/01/c-function-pointers/)_. – ryyker Oct 28 '19 at 11:52
  • You need a call for each function. so what could be shorter than a `switch`statemant? Maybe `if / else if`? – Mike Oct 28 '19 at 11:53
  • This question is unclear to me. First it seems that you have 3 bytes to determine which function to call. Later is seems that the last two bytes are data values which leaves just one byte for function opcode. Please clarify... – Support Ukraine Oct 28 '19 at 12:00
  • @L.ScottJohnson: Dispatching between N cases does not generally require O(N). A binary search is O(log N), and indexed look-up is O(1) in practice. – Eric Postpischil Oct 28 '19 at 12:05
  • @EricPostpischil you're referring to execution time, whereas I'm reading the OP as referring to code size. – L. Scott Johnson Oct 28 '19 at 12:07
  • Edits to this question have improved its quality to have arguably risen above the need for down votes or close votes. – ryyker Oct 28 '19 at 13:24

2 Answers2

1

Simple state machines?

Read byte by byte. If the first byte is 0xff then enter a specific state. If the next byte is also 0xff then enter another state. And if the next byte is 0xff then call function A, else if it's 0xfe call function B etc. After the third byte, go back to the original starting state.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

"...One possible solution might be using switch case statement, however switching each possible case would be too long. Is there any other way to do this?"

For each distinct but required functionality required by the process you are automating, you will need exactly one distinct method (or family of methods) to accomplish it. 100 distinct requirements will require 100 distinct methods implemented to satisfy the requirements. The construct used is up to the developer. A State Machine, ( such as a switch statement within a while loop ) is a common construct with which to control the execution flow through many distinct operations. If using this construct, it will likely require 100 case: sections.

If a switch statement is not acceptable for whatever reason, a different option might be an array of function pointers. Note however that this method, although it may be preferable over a switch/while combination, will still require a 1:1 correlation between unique functions : requirements:

int op0(int b1, int b2, int b3);
int op1(int b1, int b2, int b3);
int op2(int b1, int b2, int b3);
int op3(int b1, int b2, int b3);
//.... and so on depending on how many operations needed

enum {  // mnemonics with which to call array of function pointers.
   OP0,
   OP1,
   OP2,
   OP3,
   ....
};



int (*op[4]) (int b1, int b2, int b3);

int main(void) //or (int argc, char *argv[])
{
   //initialize function pointer address to implementations:
   op[0] = &op0;   
   op[1] = &op0;   
   op[2] = &op0;   
   op[3] = &op0;
   // and so on for every operation needed
   // other code in main
   return 0;
}

int op0(int b1, int b2, int b3)
{
    // code using b3 to set duty cycle
    // ...
    // code using b2 to set pre-scaler
    // ...
    // implement unique requirement of op0
    return 0;
}

int op1(int b1, int b2, int b3)
{
    // code using b3 to set duty cycle
    // ...
    // code using b2 to set pre-scaler
    // ...
    // implement unique requirement of op1
    return 0;
}

/// and so on...
ryyker
  • 22,849
  • 3
  • 43
  • 87