- fixed baudrate calculation

[Bootloader]
- set baudrate top 115200

[HendiCtrl]
- set baudrate top 115200
- revised and fixed command interpreter
- added new commands: SW_VERSION, SW_IDENTIFIER, DEBUG on/on, Remote enter, Remote exit
- oven is switched off on entering / exiting remote


git-svn-id: http://moon:8086/svn/projects/HendiControl@173 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
2019-03-30 11:48:05 +00:00
parent e1be187d03
commit feaf3666be
8 changed files with 175 additions and 81 deletions
-7
View File
@@ -9,13 +9,6 @@
#ifndef MACHINE_H_ #ifndef MACHINE_H_
#define MACHINE_H_ #define MACHINE_H_
#if ARDUINO_NANO
#define F_CPU (16000000UL) // MHz
#else
#define F_CPU (18432000UL) // MHz #define F_CPU (18432000UL) // MHz
#endif
#endif /* MACHINE_H_ */ #endif /* MACHINE_H_ */
+1 -1
View File
@@ -96,7 +96,7 @@ int main(void)
{ {
bootloader_enter(); bootloader_enter();
led_bsel(1); led_bsel(1);
uart_init(9600); uart_init(115200);
uart_puts("Hendi-Control Bootloader v1.2\n"); uart_puts("Hendi-Control Bootloader v1.2\n");
size_t image_size = 0; size_t image_size = 0;
uint16_t page_addr = 0xFFFF; uint16_t page_addr = 0xFFFF;
+9 -8
View File
@@ -12,14 +12,14 @@
void uart_init(uint32_t baudrate) void uart_init(uint32_t baudrate)
{ {
uint16_t prescale8 = UART_PRESCALE(baudrate, 8UL); uint32_t prescale8 = UART_PRESCALE(baudrate, 8UL);
uint16_t prescale16 = UART_PRESCALE(baudrate, 16UL); uint32_t prescale16 = UART_PRESCALE(baudrate, 16UL);
uint32_t baud8 = ((prescale8+1) * 8); uint32_t fcpu8 = (prescale8 * baudrate * 8);
uint32_t baud16 = ((prescale16+1) * 16); uint32_t fcpu16 = (prescale16 * baudrate * 16);
uint32_t err8 = abs(baudrate - baud8); uint32_t err8 = abs(fcpu8 - F_CPU);
uint32_t err16 = abs(baudrate - baud16); uint32_t err16 = abs(fcpu16 - F_CPU);
uint16_t prescale = prescale16; uint16_t prescale = prescale16;
if (err8 < err16) if (err8 < err16)
@@ -31,8 +31,9 @@ void uart_init(uint32_t baudrate)
} }
// Set baud rate // Set baud rate
UBRR0L = (uint8_t)prescale; uint16_t reg = prescale - 1;
UBRR0H = (uint8_t)(prescale >> 8); UBRR0L = (uint8_t)reg;
UBRR0H = (uint8_t)(reg >> 8);
// Enable receiver and transmitter // Enable receiver and transmitter
UCSR0B = (1<<TXEN0)|(1<<RXEN0); UCSR0B = (1<<TXEN0)|(1<<RXEN0);
+1 -1
View File
@@ -13,7 +13,7 @@
#define XON 17 /* XON Zeichen */ #define XON 17 /* XON Zeichen */
#define XOFF 19 /* XOFF Zeichen */ #define XOFF 19 /* XOFF Zeichen */
#define UART_PRESCALE(baudrate, smpPerBit) ((5+ 10*F_CPU / (baudrate*smpPerBit) - 1)/10) #define UART_PRESCALE(baudrate, smpPerBit) ((5 + (10*F_CPU) / (baudrate*smpPerBit))/10)
void uart_init(uint32_t baudrate); void uart_init(uint32_t baudrate);
void uart_putc(char c); void uart_putc(char c);
-7
View File
@@ -9,13 +9,6 @@
#ifndef MACHINE_H_ #ifndef MACHINE_H_
#define MACHINE_H_ #define MACHINE_H_
#if ARDUINO_NANO
#define F_CPU (16000000UL) // MHz
#else
#define F_CPU (18432000UL) // MHz #define F_CPU (18432000UL) // MHz
#endif
#endif /* MACHINE_H_ */ #endif /* MACHINE_H_ */
+145 -39
View File
@@ -24,19 +24,35 @@
#include "mcp42x6.h" #include "mcp42x6.h"
#define PRINT(a,...) printf(a, ##__VA_ARGS__) #define PRINT(a,...) printf(a, ##__VA_ARGS__)
#define PRINT_PROMPT putchar(0x0D);putchar(0x0A);putchar(':'); #define PRINT_DEBUG(a,...) \
#define USART_BAUDRATE 9600UL if (g_debug) \
{ \
printf(a, ##__VA_ARGS__); \
}
#define PRINT_CRLF putchar(0x0D);putchar(0x0A);
#define PRINT_ANSWER(a,...) PRINT_CRLF; printf(a, ##__VA_ARGS__);
#define PRINT_PROMPT PRINT_CRLF; putchar(':');
#define USART_BAUDRATE (115200UL)
#define TIMER_HW_CLOCK (F_CPU/8) #define TIMER_HW_CLOCK (F_CPU/8)
#define TIMER_IRQ_CLOCK 1000UL #define TIMER_IRQ_CLOCK 1000UL
#define TIMER_HW_RELOAD (0xFFFF-(TIMER_HW_CLOCK/TIMER_IRQ_CLOCK)) #define TIMER_HW_RELOAD (0xFFFF-(TIMER_HW_CLOCK/TIMER_IRQ_CLOCK))
#define TIMER_SW_DELAY_MS(dly) ((dly*TIMER_IRQ_CLOCK)/1000UL) #define TIMER_SW_DELAY_MS(dly) ((dly*TIMER_IRQ_CLOCK)/1000UL)
static const uint16_t POTI_HSYTERSE = 1;
int16_t adc_poti = 0; int16_t adc_poti = 0;
int16_t adc_swin = 0; int16_t adc_swin = 0;
int sw_in_last = 0; int sw_in_last = 0;
size_t cmdStrSize = 0; size_t cmdStrSize = 0;
Fifo messageFifo; Fifo messageFifo;
uint16_t g_power = 0;
int g_debug = 0;
int g_switch = 0;
static const char SW_IDENTIFIER[] = "Hendi-Control";
static const char SW_VERSION[] = "v1.1";
FILE uart_file = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); FILE uart_file = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
@@ -48,8 +64,9 @@ typedef enum _eSwitch
void setSwitch(int on) void setSwitch(int on)
{ {
g_switch = on;
const char *sw_str[2] = {"OFF", "ON"}; const char *sw_str[2] = {"OFF", "ON"};
PRINT("Set switch to %s\n", sw_str[on != 0]); PRINT_DEBUG("Set switch to %s\n", sw_str[on != 0]);
portSet(PwrSwitch_out, on != 0); portSet(PwrSwitch_out, on != 0);
} }
@@ -61,7 +78,8 @@ typedef enum _ePower
void setPower(uint16_t power) void setPower(uint16_t power)
{ {
PRINT("Set Power to %u\n", power); g_power = power;
PRINT_DEBUG("Set Power to %u\n", power);
uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = 010) uint8_t dac_cmd[] = {0x00, 0x00}; // 6.2 Write Volatile Memory (C2:C0 = 010)
size_t res = MCP47x6_write_volatile_dac(power, dac_cmd, sizeof(dac_cmd)); size_t res = MCP47x6_write_volatile_dac(power, dac_cmd, sizeof(dac_cmd));
i2c_send(0x60, I2C_WRITE, dac_cmd, res); i2c_send(0x60, I2C_WRITE, dac_cmd, res);
@@ -97,7 +115,7 @@ int main(void)
port_init(); port_init();
stdout = &uart_file; stdout = &uart_file;
printf("Hendi Control v1.1\n"); printf("%s %s\n", SW_IDENTIFIER, SW_VERSION);
uint8_t dac_cmd[] = {0x00, 0x00, 0x00}; // 6.1 Write Volatile DAC Register (C2:C0 = 00x) uint8_t dac_cmd[] = {0x00, 0x00, 0x00}; // 6.1 Write Volatile DAC Register (C2:C0 = 00x)
size_t res = MCP47x6_write_volatile_mem(0x0000, dac_cmd, sizeof(dac_cmd)); size_t res = MCP47x6_write_volatile_mem(0x0000, dac_cmd, sizeof(dac_cmd));
@@ -124,49 +142,125 @@ int main(void)
case Uart: case Uart:
{ {
// Process Uart message // Process Uart message
cmdStr[cmdStrSize] = 0;
char c = (char)msg.m.uart.data; char c = (char)msg.m.uart.data;
cmdStr[cmdStrSize] = 0;
// Command finished with CR/LF // Command finished with CR/LF
if (c == 0x0A || c == 0x0D) if (c == 0x0D)
{ {
PRINT_PROMPT; char *pArgs = cmdStr;
if (cmdStrSize < 1) cmdStrSize = 0;
while (*pArgs)
{
// Power Control
if (toupper(*pArgs) == 'P')
{
pArgs++;
if ((*pArgs) == '?')
{
PRINT_ANSWER("%04u", g_power);
pArgs++;
}
else
{
if (!isdigit(*pArgs))
{ {
break; break;
} }
uint16_t arg = (uint16_t)strtol(pArgs, &pArgs, 10);
if (state == StateNormal || state == StateRemote) if (state == StateRemote)
{ {
// Power Control
if (toupper(cmdStr[0]) == 'P')
{
uint16_t arg = (uint16_t)strtol(cmdStr+1, (char **)NULL, 10);
setPower(arg); setPower(arg);
timer_start(TIMER_TIMEOUT, TIMER_SW_DELAY_MS(5000)); }
state_next = StateRemote; }
} }
// Switch Control // Switch Control
if (toupper(cmdStr[0]) == 'S') else if (toupper(*pArgs) == 'S')
{ {
uint16_t arg = (uint16_t)strtol(cmdStr+1, (char **)NULL, 10); pArgs++;
setSwitch(arg); if ((*pArgs) == '?')
timer_start(TIMER_TIMEOUT, TIMER_SW_DELAY_MS(5000));
state_next = StateRemote;
}
// Switch Control
if (toupper(cmdStr[0]) == 'X')
{ {
timer_stop(TIMER_TIMEOUT); PRINT_ANSWER("%u", g_switch);
setPower(PowerLow); pArgs++;
setSwitch(SwitchOff);
}
}
cmdStrSize = 0;
} }
else else
{
if (!isdigit(*pArgs))
{
break;
}
uint16_t arg = (uint16_t)strtol(pArgs, &pArgs, 10);
if (state == StateRemote)
{
setSwitch(arg);
}
}
}
// Enter remote
else if (toupper(*pArgs) == 'R')
{
pArgs++;
if (state == StateNormal)
{
setPower(PowerLow);
setSwitch(SwitchOff);
state_next = StateRemote;
}
}
// Exit remote
else if (toupper(*pArgs) == 'X')
{
pArgs++;
if (state == StateRemote)
{
setPower(PowerLow);
setSwitch(SwitchOff);
state_next = StateNormal;
}
}
// Debug Control
else if (toupper(*pArgs) == 'D')
{
pArgs++;
if (!isdigit(*pArgs))
{
break;
}
g_debug = (uint16_t)strtol(pArgs, &pArgs, 10);
}
// SW identifier
else if (toupper(*pArgs) == 'I')
{
pArgs++;
PRINT_ANSWER("%s", SW_IDENTIFIER);
}
// Version
else if (toupper(*pArgs) == 'V')
{
pArgs++;
PRINT_ANSWER("%s", SW_VERSION);
}
// no match
else
{
pArgs++;
}
} // while (*pArgs)
timer_start(TIMER_TIMEOUT, TIMER_SW_DELAY_MS(10000));
PRINT_PROMPT;
}
else
{
if ((c != 0x0A) && (c != 0x0D))
{ {
if (cmdStrSize < (sizeof(cmdStr)-1)) if (cmdStrSize < (sizeof(cmdStr)-1))
{ {
@@ -174,7 +268,8 @@ int main(void)
} }
putchar(c); putchar(c);
} }
} } // if (c == 0x0D)
} // case Uart:
break; break;
case AdcComplete: case AdcComplete:
@@ -183,7 +278,7 @@ int main(void)
int16_t adc_curr = (int16_t)msg.m.adc.data; int16_t adc_curr = (int16_t)msg.m.adc.data;
if (adc_ch == 0) if (adc_ch == 0)
{ {
if (((adc_curr - adc_poti) < -1) || ((adc_curr - adc_poti) > 1)) if (((adc_curr - adc_poti) <= -(int16_t)POTI_HSYTERSE) || ((adc_curr - adc_poti) >= (int16_t)POTI_HSYTERSE))
{ {
if (state == StateNormal) if (state == StateNormal)
{ {
@@ -206,14 +301,22 @@ int main(void)
{ {
case TIMER_GENERAL: case TIMER_GENERAL:
{ {
uint16_t interval = 1000;
uint16_t pulse = 50;
if (state == StateRemote)
{
interval = 500;
pulse = 50;
}
hb_state = !hb_state; hb_state = !hb_state;
if (hb_state) if (hb_state)
{ {
timer_start(timer_id, TIMER_SW_DELAY_MS(50)); timer_start(timer_id, TIMER_SW_DELAY_MS(pulse));
} }
else else
{ {
timer_start(timer_id, TIMER_SW_DELAY_MS(950)); timer_start(timer_id, TIMER_SW_DELAY_MS((interval-pulse)));
} }
portSet(Led_HB, hb_state); portSet(Led_HB, hb_state);
} }
@@ -221,9 +324,12 @@ int main(void)
case TIMER_TIMEOUT: case TIMER_TIMEOUT:
{ {
PRINT("Timeout!\n"); if (state == StateRemote)
{
PRINT_DEBUG("Remote timeout!\n");
state_next = StateError; state_next = StateError;
} }
}
break; break;
case TIMER_ADC: case TIMER_ADC:
@@ -232,7 +338,7 @@ int main(void)
int sw_in = adc_swin > 512; int sw_in = adc_swin > 512;
if (sw_in != sw_in_last) if (sw_in != sw_in_last)
{ {
PRINT ("PwrSwitch_in = %d\n", sw_in); PRINT_DEBUG ("PwrSwitch_in = %d\n", sw_in);
if (sw_in == 0) if (sw_in == 0)
{ {
if (state == StateError || state == StateRemote) if (state == StateError || state == StateRemote)
@@ -257,7 +363,7 @@ int main(void)
} }
if (state != state_next) if (state != state_next)
{ {
PRINT("State change \"%s\" => \"%s\"\n", state_str[state], state_str[state_next]); PRINT_DEBUG("State change \"%s\" => \"%s\"\n", state_str[state], state_str[state_next]);
if (state_next == StateError) if (state_next == StateError)
{ {
setPower(PowerLow); setPower(PowerLow);
+9 -8
View File
@@ -41,14 +41,14 @@ void uart_init(Fifo *pFifo, uint32_t baudrate)
{ {
g_pFifo = pFifo; g_pFifo = pFifo;
uint16_t prescale8 = UART_PRESCALE(baudrate, 8UL); uint32_t prescale8 = UART_PRESCALE(baudrate, 8UL);
uint16_t prescale16 = UART_PRESCALE(baudrate, 16UL); uint32_t prescale16 = UART_PRESCALE(baudrate, 16UL);
uint32_t baud8 = ((prescale8+1) * 8); uint32_t fcpu8 = (prescale8 * baudrate * 8);
uint32_t baud16 = ((prescale16+1) * 16); uint32_t fcpu16 = (prescale16 * baudrate * 16);
uint32_t err8 = abs(baudrate - baud8); uint32_t err8 = abs(fcpu8 - F_CPU);
uint32_t err16 = abs(baudrate - baud16); uint32_t err16 = abs(fcpu16 - F_CPU);
uint16_t prescale = prescale16; uint16_t prescale = prescale16;
if (err8 < err16) if (err8 < err16)
@@ -60,8 +60,9 @@ void uart_init(Fifo *pFifo, uint32_t baudrate)
} }
// Set baud rate // Set baud rate
UBRR0L = (uint8_t)prescale; uint16_t reg = prescale - 1;
UBRR0H = (uint8_t)(prescale >> 8); UBRR0L = (uint8_t)reg;
UBRR0H = (uint8_t)(reg >> 8);
// Enable receiver and transmitter // Enable receiver and transmitter
UCSR0B = (1<<TXEN0)|(1<<RXEN0); UCSR0B = (1<<TXEN0)|(1<<RXEN0);
+1 -1
View File
@@ -12,7 +12,7 @@
#include "machine.h" #include "machine.h"
#include "fifo.h" #include "fifo.h"
#define UART_PRESCALE(baudrate, smpPerBit) ((5+ 10*F_CPU / (baudrate*smpPerBit) - 1)/10) #define UART_PRESCALE(baudrate, smpPerBit) ((5 + (10*F_CPU) / (baudrate*smpPerBit))/10)
void uart_init(Fifo *pFifo, uint32_t baudrate); void uart_init(Fifo *pFifo, uint32_t baudrate);
void uart_putc(char c); void uart_putc(char c);