349 lines
7.5 KiB
C
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;
|
|
}
|