255 lines
6.4 KiB
C
255 lines
6.4 KiB
C
/* initial work done by jdolinay */
|
||
#include "MKL25Z4.h"
|
||
|
||
/* go-button PTA4 */
|
||
#define SWITCH_PIN (4)
|
||
/* coffeebutton (PTA16) */
|
||
#define SWITCH_PIN_COFFEE (16)
|
||
/* sugarbutton (PTA5) */
|
||
#define SWITCH_PIN_SUGAR (5)
|
||
/* E5 */
|
||
#define SV1_PIN (11)
|
||
/* C1 */
|
||
#define SV2_PIN (12)
|
||
/* E0 */
|
||
#define SV4_PIN (15)
|
||
/* E1 */
|
||
#define SV5_PIN (16)
|
||
/* E4 */
|
||
#define SV3_PIN (13)
|
||
/* D3 */
|
||
#define H1_PIN (24)
|
||
/* C16 */
|
||
#define H2_PIN (28)
|
||
/* D2 */
|
||
#define H3_PIN (23)
|
||
/* C5 */
|
||
#define H4_PIN (34)
|
||
/* D4 */
|
||
#define H5_PIN (26)
|
||
/* PTC7 */
|
||
#define H6_PIN (36)
|
||
/* PTD5 */
|
||
#define H7_PIN (25)
|
||
/* C6 */
|
||
#define H8_PIN (33)
|
||
/* D0 */
|
||
#define D0_PIN (22)
|
||
|
||
static int i = 0;
|
||
|
||
void init(void);
|
||
void delay(void);
|
||
static inline int is_key_pressed(int pin);
|
||
typedef enum {WAITING, PREPARATION, TANKFILLING, MIXING, SERVING} state;
|
||
typedef enum {WEAK, MED, STRONG, COFFEESTRENGTHOPTIONSCOUNT} keypresscoffeestrength;
|
||
typedef enum {L, S, WATERLEVEL} keypresswaterlevel;
|
||
typedef enum {NOTHANKS, YESPLEASE, GIMMEMOAR, ALLTHESUGARINTHEWORLD, HOWMUCHSUGAR} keypresssugar;
|
||
state currentstatepls = WAITING;
|
||
keypresscoffeestrength coffeestrength = WEAK;
|
||
keypresswaterlevel coffeesize = L;
|
||
keypresssugar howmuchsugar = NOTHANKS;
|
||
|
||
|
||
void fakecoffee(){
|
||
/* Fill TANK1 to the level H3 (really weak distillant) */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV1_PIN);
|
||
while ( (PTC->PDIR & (1 << H3_PIN )) == 0 )
|
||
;
|
||
PTE->PCOR = PTE->PCOR | (1 << SV1_PIN);
|
||
}
|
||
|
||
void mediumstrongcoffee(){
|
||
/* Fill TANK1 to the level H2 (medium strong coffee). */
|
||
/* Open valve SV1 */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV1_PIN);
|
||
/* while ( H2 is not HIGH ) do nothing; */
|
||
while ( (PTC->PDIR & (1 << H2_PIN )) == 0 )
|
||
;
|
||
/* Close SV1 */
|
||
PTE->PCOR = PTE->PCOR | (1 << SV1_PIN);
|
||
}
|
||
|
||
void strongcoffee(){
|
||
/* Fill TANK1 to the level H1 */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV1_PIN);
|
||
while ( (PTC->PDIR & (1 << H1_PIN )) == 0 )
|
||
;
|
||
PTE->PCOR = PTE->PCOR | (1 << SV1_PIN);
|
||
}
|
||
|
||
|
||
void handlepreparation(){
|
||
switch(howmuchsugar){
|
||
case NOTHANKS:
|
||
break;
|
||
case YESPLEASE:
|
||
/* Fill TANK3 to H8 (little sugar). */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV3_PIN);
|
||
while ( (PTC->PDIR & (1 << H8_PIN )) == 0 ) {;}
|
||
PTE->PCOR = PTE->PCOR | (1 << SV3_PIN);
|
||
break;
|
||
case GIMMEMOAR:
|
||
/* as in medium sugar pls */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV3_PIN);
|
||
while ( (PTC->PDIR & (1 << H7_PIN )) == 0 ) {;}
|
||
PTE->PCOR = PTE->PCOR | (1 << SV3_PIN);
|
||
break;
|
||
case ALLTHESUGARINTHEWORLD:
|
||
/* as title */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV3_PIN);
|
||
while ( (PTC->PDIR & (1 << H6_PIN )) == 0 ) {;}
|
||
PTE->PCOR = PTE->PCOR | (1 << SV3_PIN);
|
||
break;
|
||
}
|
||
switch(coffeestrength){
|
||
case WEAK:
|
||
fakecoffee();
|
||
break;
|
||
case MED:
|
||
mediumstrongcoffee();
|
||
break;
|
||
case STRONG:
|
||
strongcoffee();
|
||
break;
|
||
}
|
||
switch(coffeesize){
|
||
case L:
|
||
/* Fill TANK2 to H4 (big coffee – full cup). */
|
||
/* Open valve SV2 */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV2_PIN);
|
||
/* Wait for sensor H4 to go HIGH, then close the valve */
|
||
while ( (PTC->PDIR & (1 << H4_PIN )) == 0 ) {;}
|
||
PTE->PCOR = PTE->PCOR | (1 << SV2_PIN);
|
||
break;
|
||
case S:
|
||
/* Fill TANK2 to H5 (small coffee). */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV2_PIN);
|
||
while ( (PTC->PDIR & (1 << H5_PIN )) == 0 ) {;}
|
||
PTE->PCOR = PTE->PCOR | (1 << SV2_PIN);
|
||
break;
|
||
}
|
||
}
|
||
|
||
void tankfilling(){
|
||
/* Fill the mixer (open SV4). */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV4_PIN);
|
||
/* stay open while we see something on our sensors */
|
||
while ( ((PTD->PDIR & (1 << H3_PIN )) != 0) && ((PTD->PDIR & (1 << H5_PIN )) != 0) && ((PTC->PDIR & (1 << H8_PIN )) != 0) ) {;}
|
||
PTE->PCOR = PTE->PCOR | (1 << SV4_PIN);
|
||
}
|
||
|
||
void mixing(){
|
||
/* Mix everything for about 5 seconds. */
|
||
PTE->PSOR = PTE->PSOR | (1 << D0_PIN);
|
||
delay();
|
||
delay();
|
||
PTE->PCOR = PTE->PCOR | (1 << D0_PIN);
|
||
}
|
||
|
||
void serving(){
|
||
/* Fill the cup (empty the mixer) – open SV5. */
|
||
PTE->PSOR = PTE->PSOR | (1 << SV5_PIN);
|
||
/* TODO find out if nothing is left in the tank, only then close */
|
||
delay();
|
||
delay();
|
||
PTE->PCOR = PTE->PCOR | (1 << SV5_PIN);
|
||
}
|
||
|
||
|
||
int main(void)
|
||
{
|
||
/* Initialize the pins */
|
||
init();
|
||
while (1){
|
||
switch(currentstatepls){
|
||
case WAITING:
|
||
if(is_key_pressed(SWITCH_PIN_SUGAR)) {
|
||
howmuchsugar = (keypresssugar)(howmuchsugar + 1) % HOWMUCHSUGAR;
|
||
}
|
||
if(is_key_pressed(SWITCH_PIN_COFFEE)) {
|
||
coffeestrength = (keypresscoffeestrength)(coffeestrength + 1) % COFFEESTRENGTHOPTIONSCOUNT;
|
||
}
|
||
if(is_key_pressed(SWITCH_PIN_WATERLEVEL)) {
|
||
coffeesize = (keypresswaterlevel)(coffeesize + 1) % WATERLEVEL;
|
||
}
|
||
if(is_key_pressed(SWITCH_PIN)) currentstatepls = PREPARATION;
|
||
break;
|
||
case PREPARATION:
|
||
handlepreparation();
|
||
currentstatepls = TANKFILLING;
|
||
case TANKFILLING:
|
||
tankfilling();
|
||
currentstatepls = MIXING;
|
||
break;
|
||
case MIXING:
|
||
mixing();
|
||
currentstatepls = SERVING;
|
||
break;
|
||
case SERVING:
|
||
serving();
|
||
currentstatepls = WAITING;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
void init(void)
|
||
{
|
||
// Enable clock for ports A, B, C, D, E
|
||
SIM->SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK |
|
||
SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK );
|
||
// Set pin function to GPIO
|
||
/* TODO set proper pin ports */
|
||
PORTA->PCR[SWITCH_PIN] = PORT_PCR_MUX(1);
|
||
PORTE->PCR[SV1_PIN] = PORT_PCR_MUX(1);
|
||
PORTC->PCR[SV2_PIN] = PORT_PCR_MUX(1);
|
||
PORTE->PCR[SV3_PIN] = PORT_PCR_MUX(1);
|
||
PORTE->PCR[SV4_PIN] = PORT_PCR_MUX(1);
|
||
PORTE->PCR[SV5_PIN] = PORT_PCR_MUX(1);
|
||
PORTD->PCR[H1_PIN] = PORT_PCR_MUX(1);
|
||
PORTC->PCR[H2_PIN] = PORT_PCR_MUX(1);
|
||
PORTD->PCR[H3_PIN] = PORT_PCR_MUX(1);
|
||
PORTC->PCR[H4_PIN] = PORT_PCR_MUX(1);
|
||
PORTD->PCR[H5_PIN] = PORT_PCR_MUX(1);
|
||
PORTC->PCR[H6_PIN] = PORT_PCR_MUX(1);
|
||
PORTD->PCR[H7_PIN] = PORT_PCR_MUX(1);
|
||
PORTC->PCR[H8_PIN] = PORT_PCR_MUX(1);
|
||
// Set pin direction
|
||
PTE->PDDR |= (1 << SV1_PIN); // SV1 is output - valve 1
|
||
PTC->PDDR |= (1 << SV2_PIN); // SV2 is output - valve 2
|
||
PTE->PDDR |= (1 << SV3_PIN); // SV3 is output - valve 3
|
||
PTE->PDDR |= (1 << SV4_PIN); // SV4 is output - valve 4
|
||
PTE->PDDR |= (1 << SV5_PIN); // SV5 is output - valve 5
|
||
// Hx are inputs (sensors)
|
||
PTD->PDDR &= ~(1 << H1_PIN);
|
||
PTC->PDDR &= ~(1 << H2_PIN);
|
||
PTD->PDDR &= ~(1 << H3_PIN);
|
||
PTC->PDDR &= ~(1 << H4_PIN);
|
||
PTD->PDDR &= ~(1 << H5_PIN);
|
||
PTC->PDDR &= ~(1 << H6_PIN);
|
||
PTD->PDDR &= ~(1 << H7_PIN);
|
||
PTC->PDDR &= ~(1 << H8_PIN);
|
||
|
||
// pull-ups are not needed.
|
||
}
|
||
|
||
/* Return 1 if the switch on given pin is pressed, 0 if not pressed. */
|
||
static inline int is_key_pressed(int pin)
|
||
{
|
||
if ((PTA->PDIR & (1 << pin)) == 0) {
|
||
return 1;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void delay(void)
|
||
{
|
||
unsigned long n = 400000L;
|
||
while ( n-- ) {;}
|
||
}
|