Topic: tech dcc pc src prev next
tech dcc pc src > program_loco.c
#include "program_loco.h"
#include "dcc.h"
#include "lcd.h"
#include "menu.h"
#include "packet.h"
#include "pins.h"
#define SIZEOF_ARRAY(a) (sizeof(a)/sizeof(a[0]))
typedef unsigned char index_type;
bool cv_valid(cv_type cv)
{
return (cv > 0 && cv <= 1024);
}
void program_loco()
{
static const char *items[] = {
"Address",
"Acceleration",
"Deceleration",
"VStart",
"VHigh",
"Custom (Paged)",
"Custom (Direct)",
"Hard Reset"
};
index_type index = 0;
void button(void *v, const switch_type sw)
{
index_type *index_ = (index_type*)v;
if(HERMES_SWITCH_NO(sw) == HERMES_SWITCH_BACK)
Menu_Finish();
if(HERMES_SWITCH_NO(sw) == HERMES_RE_ACW)
{
*index_ = (unsigned char)((unsigned char)(SIZEOF_ARRAY(items) + *index_ - 1) % SIZEOF_ARRAY(items));
Menu_Redraw();
}
if(HERMES_SWITCH_NO(sw) == HERMES_RE_CW)
{
*index_ = (unsigned char)((unsigned char)(*index_ + 1) % SIZEOF_ARRAY(items));
Menu_Redraw();
}
if(HERMES_SWITCH_NO(sw) == HERMES_RE_SEL)
{
// Program a CV using the mode appropriate mode for the CV number.
// Return true if the CV was written, false if there was a problem
// (e.g. the operation was cancelled by the user).
bool program_cv(cv_type cv, const char *name)
{
int value = Menu_GetInt(name, -1, HERMES_MAX_CV_VALUE);
if(value != -1)
{
DCC_AutoCvWrite(cv, (unsigned char)value);
return true;
}
return false;
}
switch(*index_)
{
case 0:
// Program address.
if(program_cv(1, items[0]))
Menu_Notice("Address written");
break;
case 1:
// Program acceleration.
if(program_cv(3, items[1]))
Menu_Notice("Accel. written");
break;
case 2:
// Program deceleration.
if(program_cv(4, items[2]))
Menu_Notice("Decel. written");
break;
case 3:
// Program VStart.
if(program_cv(2, items[3]))
Menu_Notice("VStart written");
break;
case 4:
// Program VHigh.
if(program_cv(5, items[4]))
Menu_Notice("VHigh written");
break;
case 5:
{
// Custom (paged).
int cv = Menu_GetInt("CV No.", -1, HERMES_MAX_CV_NO);
if(!cv_valid(cv))
{
Menu_Notice("Invalid CV");
break;
}
if(cv == -1)
break;
int value = Menu_GetInt("Value", -1, HERMES_MAX_CV_VALUE);
if(value > 255)
{
Menu_Notice("Invalid value");
break;
}
if(value == -1)
break;
// Write the CV.
DCC_PagedCvWrite((cv_type)cv, (unsigned char)value);
Menu_Notice("CV Written");
}
break;
case 6:
{
// Custom (direct).
int cv = Menu_GetInt("CV No.", -1, HERMES_MAX_CV_NO);
if(!cv_valid(cv))
{
Menu_Notice("Invalid CV");
break;
}
if(cv == -1)
break;
int value = Menu_GetInt("Value", -1, HERMES_MAX_CV_VALUE);
if(value > 255)
{
Menu_Notice("Invalid value");
break;
}
if(value == -1)
break;
// Write the CV.
DCC_DirectCvWrite((cv_type)cv, (unsigned char)value);
Menu_Notice("CV Written");
}
break;
case 7:
// Hard reset
if(Menu_Question("Reset?"))
DCC_HardReset();
break;
}
}
}
void draw(void *v)
{
index_type *index_ = (index_type*)v;
Menu_DrawList("Loco", items[*index_], *index_, SIZEOF_ARRAY(items));
}
Menu_EventLoop(button, draw, 0, &index);
}