Files
fun_gen_amp_test/app/core/app.c
2023-10-01 10:30:58 +02:00

349 lines
7.5 KiB
C

#include "main.h"
#include "tim.h"
#include "dac.h"
#include "st7565.h"
#include "font_gfx.h"
#include "bitmap_fonts.h"
#include "bottom_button.h"
#include "printf.h"
#include "mcu_cs.h"
#include "mcp41x.h"
#include "ad9833.h"
#include "ad5303.h"
#define MAX_VOLT 330
#define MAX_REF 256
typedef enum
{
FREQ,
WAVE,
ONOFF,
GAIN,
POT,
REF,
OFFS,
ZERO,
OPT_MAX
} option_t;
typedef enum
{
SIN,
TRI,
SQR
} wave_t;
st7565_handle_t hst7565;
GFX_display_t disp;
mcp41x_handle_t hmcp41;
MCU_cs_t hmcp41_cs;
ad9833_handle_t had9833;
MCU_cs_t had9833_cs;
ad5303_handle_t hdac;
MCU_cs_t hdac_cs;
uint32_t last_tick;
option_t option;
uint8_t on_off_s[2][4] = {"OFF", "ON"};
uint8_t wave_s[3][4] = {"SIN", "TRI", "SQR"};
uint32_t var[OPT_MAX];
void draw_string(void);
void update_display(void);
void encoderHandler(void);
void changeValue(int8_t inc);
void setup(void)
{
var[FREQ] = 1;
var[POT] = 255;
var[REF] = 197;
var[ONOFF] = 1;
hst7565.hspi = &hspi3;
hst7565.cs_port = ST7565_CS_GPIO_Port;
hst7565.cs_pin = ST7565_CS_Pin;
hst7565.a0_port = ST7565_A0_GPIO_Port;
hst7565.a0_pin = ST7565_A0_Pin;
hst7565.rst_port = ST7565_RST_GPIO_Port;
hst7565.rst_pin = ST7565_RST_Pin;
ST7565_Init(&hst7565, &disp);
mcu_cs_init(&hmcp41_cs, AMP1_CS_GPIO_Port, AMP1_CS_Pin, GPIO_PIN_SET);
mcp41x_init(&hmcp41, &hspi2, &hmcp41_cs.super, MCP41X_10K);
mcu_cs_init(&had9833_cs, DDS1_CS_GPIO_Port, DDS1_CS_Pin, GPIO_PIN_SET);
ad9833_init(&had9833, &hspi2, &had9833_cs.super);
mcu_cs_init(&hdac_cs, OFFS1_CS_GPIO_Port, OFFS1_CS_Pin, GPIO_PIN_SET);
ad5303_init(&hdac, &hspi2, &hdac_cs.super, AD_8BIT);
bottomButtonInit();
DISP_clearScreen(&disp);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"FUN GEN TEST", 24, 24, BM_NORMAL);
ST7565_DisplayAll(&hst7565);
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
HAL_DAC_Start(&hdac1, DAC1_CHANNEL_1);
for (option_t opt = 0; opt < OPT_MAX; opt++)
{
option = opt;
changeValue(0);
}
HAL_Delay(1000);
DISP_clearScreen(&disp);
draw_string();
last_tick = HAL_GetTick();
}
void loop(void)
{
bottomButtonsHandler();
encoderHandler();
if (HAL_GetTick() - last_tick > 100)
{
last_tick = HAL_GetTick();
ST7565_DisplayAll(&hst7565);
update_display();
}
}
void draw_string(void)
{
// frequenncy
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"FREQ:", 8, 0, BM_NORMAL);
// wave type
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"WAVE:", 8, 8, BM_NORMAL);
// dds on off
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"DDS:", 8, 16, BM_NORMAL);
// gain switch
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"GAIN:", 8, 24, BM_NORMAL);
// potentiometr
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"POT:", 8, 32, BM_NORMAL);
// reference voltage
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"REF:", 8, 40, BM_NORMAL);
// dac1 - offset
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"OFFS:", 8, 48, BM_NORMAL);
// dac2 - zeroing
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"ZERO:", 8, 56, BM_NORMAL);
for (option_t opt = FREQ; opt < OPT_MAX; opt++)
{
option = opt;
update_display();
}
option = OFFS;
}
void update_display(void)
{
uint8_t data[16];
uint32_t temp;
DISP_clearRegion(&disp, 0, 0, 8, 64);
switch (option)
{
case FREQ:
snprintf((char *)data, 8, "%04uk", var[FREQ]);
DISP_writeString(&disp, &font5x7Info, data, 48, 0, BM_NORMAL);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 0, BM_NORMAL);
break;
case WAVE:
DISP_writeString(&disp, &font5x7Info, wave_s[var[WAVE]], 48, 8, BM_NORMAL);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 8, BM_NORMAL);
break;
case ONOFF:
DISP_clearRegion(&disp, 48, 16, 24, 8);
DISP_writeString(&disp, &font5x7Info, on_off_s[var[ONOFF]], 48, 16, BM_NORMAL);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 16, BM_NORMAL);
break;
case GAIN:
DISP_clearRegion(&disp, 48, 24, 24, 8);
DISP_writeString(&disp, &font5x7Info, on_off_s[var[GAIN]], 48, 24, BM_NORMAL);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 24, BM_NORMAL);
break;
case POT:
snprintf((char *)data, 8, "%03u", var[POT]);
DISP_writeString(&disp, &font5x7Info, data, 48, 32, BM_NORMAL);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 32, BM_NORMAL);
break;
case REF:
temp = (MAX_VOLT * var[REF] + 127) / UINT8_MAX;
snprintf((char *)data, 16, "%03u (%01d.%02d)", var[REF], temp / 100, temp % 100);
DISP_writeString(&disp, &font5x7Info, data, 48, 40, BM_NORMAL);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 40, BM_NORMAL);
break;
case OFFS:
temp = (MAX_REF * var[REF] + 127) / UINT8_MAX;
snprintf((char *)data, 16, "%03u (%01d.%02d)", var[REF], temp / 100, temp % 100);
// snprintf((char *)data, 8, "%03u", var[OFFS]);
DISP_writeString(&disp, &font5x7Info, data, 48, 48, BM_NORMAL);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 48, BM_NORMAL);
break;
case ZERO:
temp = (MAX_REF * var[REF] + 127) / UINT8_MAX;
snprintf((char *)data, 16, "%03u (%01d.%02d)", var[REF], temp / 100, temp % 100);
// snprintf((char *)data, 8, "%03u", var[ZERO]);
DISP_writeString(&disp, &font5x7Info, data, 48, 56, BM_NORMAL);
DISP_writeString(&disp, &font5x7Info, (uint8_t *)"*", 0, 56, BM_NORMAL);
break;
default:
break;
}
}
void pushedDispBtnEvent(ButtonKey_t *key)
{
switch (key->instance)
{
case BTN_BOT_1:
option = (option - 1) & (OPT_MAX - 1);
break;
case BTN_BOT_2:
option = (option + 1) & (OPT_MAX - 1);
break;
default:
break;
}
}
void changeValue(int8_t inc)
{
inc = inc / 2;
switch (option)
{
case FREQ:
{
if ((var[FREQ] <= 1 && inc < 0) || (var[FREQ] >= 1000 && inc > 0))
{
break;
}
var[FREQ] += inc;
ad9833_setFrequency(&had9833, CHAN_0, var[FREQ] * 1000);
break;
}
case WAVE:
{
if (inc > 0 && var[WAVE] == 2)
{
var[WAVE] = 0;
}
else if (inc < 0 && var[WAVE] == 0)
{
var[WAVE] = 2;
}
else
{
var[WAVE] += inc;
}
switch (var[WAVE])
{
case SIN:
ad9833_setMode(&had9833, MODE_SINE);
break;
case TRI:
ad9833_setMode(&had9833, MODE_TRIANGLE);
break;
case SQR:
ad9833_setMode(&had9833, MODE_SQUARE1);
break;
default:
break;
}
break;
}
case ONOFF:
{
var[ONOFF] ^= 1;
if (var[ONOFF])
{
HAL_GPIO_WritePin(LED_CH1_GPIO_Port, LED_CH1_Pin, GPIO_PIN_RESET);
switch (var[WAVE])
{
case SIN:
ad9833_setMode(&had9833, MODE_SINE);
break;
case TRI:
ad9833_setMode(&had9833, MODE_TRIANGLE);
break;
case SQR:
ad9833_setMode(&had9833, MODE_SQUARE1);
break;
default:
break;
}
}
else
{
HAL_GPIO_WritePin(LED_CH1_GPIO_Port, LED_CH1_Pin, GPIO_PIN_SET);
ad9833_setMode(&had9833, MODE_OFF);
}
break;
}
case GAIN:
{
var[GAIN] ^= 1;
if (var[GAIN])
{
HAL_GPIO_WritePin(GAIN1_GPIO_Port, GAIN1_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GAIN1_GPIO_Port, GAIN1_Pin, GPIO_PIN_RESET);
}
break;
}
case POT:
{
var[POT] = (var[POT] + inc) & UINT8_MAX;
mcp41x_setValue(&hmcp41, var[POT]);
break;
}
case REF:
{
var[REF] = (var[REF] + inc) & UINT8_MAX;
HAL_DAC_SetValue(&hdac1, DAC1_CHANNEL_1, DAC_ALIGN_8B_R, var[REF]);
break;
}
case OFFS:
{
var[OFFS] = (var[OFFS] + inc) & UINT8_MAX;
ad5303_set_value(&hdac, var[OFFS], AD_DAC2);
break;
}
case ZERO:
{
var[ZERO] = (var[ZERO] + inc) & UINT8_MAX;
ad5303_set_value(&hdac, var[ZERO], AD_DAC1);
break;
}
default:
break;
}
}
void encoderHandler(void)
{
static uint8_t cnt;
if (htim3.Instance->CNT == cnt || htim3.Instance->CNT % 2 == 1)
{
return;
}
changeValue(htim3.Instance->CNT - cnt);
cnt = (uint8_t)htim3.Instance->CNT;
}