2023-07-02 17:09:41 +02:00
|
|
|
|
#include <main.h>
|
2025-01-28 19:01:22 +01:00
|
|
|
|
#include <math.h>
|
2023-07-02 17:09:41 +02:00
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include <stm32g4xx_hal_conf.h>
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
#include "si5351.h"
|
2023-07-02 17:09:41 +02:00
|
|
|
|
#include "squeow.h"
|
2025-01-28 19:01:22 +01:00
|
|
|
|
#include "squeow_ui.h"
|
2023-07-02 17:09:41 +02:00
|
|
|
|
|
|
|
|
|
|
/* SQUEOW
|
|
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
TIM2 PWM 168000000/4096 = 41015,625 Hz
|
|
|
|
|
|
TIM3 sys_tick 168000000/(16800×100) 100hz
|
2023-07-02 17:09:41 +02:00
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
risoluzione PWM 4096 (12bit)
|
|
|
|
|
|
|
|
|
|
|
|
ADC1 agganciato a TIM2, valore passato attraverso TIM2_IRQHandler a TIM2->CCR1
|
|
|
|
|
|
ADC2 lanciato da software, quando completo adc2_done viene settato in HAL_ADC_ConvCpltCallback
|
2023-07-02 17:09:41 +02:00
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
extern I2C_HandleTypeDef hi2c1;
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
// SYS
|
2025-06-28 00:58:29 +02:00
|
|
|
|
volatile uint8_t sys_tick, sys_tick_prescale;
|
2025-01-28 19:01:22 +01:00
|
|
|
|
|
|
|
|
|
|
// UART
|
|
|
|
|
|
uint8_t UART_RX_buf[UART_RX_BUF_SIZE];
|
|
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
uint8_t UART_TX_buf[UART_TX_BUF_SIZE];
|
|
|
|
|
|
uint8_t UART_TX_buf_lenght;
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
// SYNTH
|
|
|
|
|
|
uint32_t freq;
|
|
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
// ADC2 (16 o 32?) per usare buffer da 32 settare WORD nel canale DMA
|
|
|
|
|
|
uint32_t adc2_valori[4];
|
|
|
|
|
|
uint8_t adc2_done, blocco, blocco_fatto, codice_allarme;
|
2025-01-28 19:01:22 +01:00
|
|
|
|
|
2023-07-02 17:09:41 +02:00
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
// VU
|
|
|
|
|
|
uint8_t analog_wd_status;
|
2023-07-02 17:09:41 +02:00
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
// ###################################
|
|
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
int serial_write(char *ptr, size_t len) {
|
|
|
|
|
|
// todo sia dma che it corrompono (vedi sotto, static)
|
|
|
|
|
|
HAL_UART_Transmit_DMA(&huart1, ptr, len);
|
|
|
|
|
|
// HAL_UART_Transmit_IT(&huart1, ptr, len);
|
|
|
|
|
|
// HAL_UART_Transmit(&huart1, ptr, len, 1000);
|
|
|
|
|
|
// uart_sent = 0;
|
|
|
|
|
|
UART_TX_buf_lenght = 0;
|
|
|
|
|
|
return len;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
void squeow_init(void) {
|
|
|
|
|
|
freq = DEFAULT_SYNTH_FREQUENCY;
|
2025-06-28 00:58:29 +02:00
|
|
|
|
blocco = 0;
|
|
|
|
|
|
adc2_valori[0] = 0;
|
|
|
|
|
|
adc2_valori[1] = 0;
|
|
|
|
|
|
adc2_valori[2] = 0;
|
|
|
|
|
|
adc2_valori[3] = 0;
|
|
|
|
|
|
codice_allarme = 0;
|
2023-07-02 17:09:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
uint32_t sat_sub(uint16_t x, uint16_t y) {
|
2023-07-02 17:09:41 +02:00
|
|
|
|
uint16_t res = x - y;
|
|
|
|
|
|
res &= -(res <= x);
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
uint32_t ringbuf_increment(uint32_t *index, uint32_t buff_size_mask) {
|
|
|
|
|
|
(*index)++;
|
|
|
|
|
|
*index &= buff_size_mask;
|
|
|
|
|
|
return *index;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// adc
|
|
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
void adc_rileva_soglie(uint32_t *adc_valori) {
|
|
|
|
|
|
if (!blocco) {
|
|
|
|
|
|
#ifdef SQUEOW_SONDA_CORRENTE
|
|
|
|
|
|
if (adc_valori[SQUEOW_ADC_CORRENTE] > SOGLIA_CORRENTE) {
|
|
|
|
|
|
codice_allarme = SQUEOW_CODICE_CORRENTE;
|
|
|
|
|
|
blocco = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef SQUEOW_SONDA_TEMPERATURA
|
|
|
|
|
|
if (adc_valori[SQUEOW_ADC_TEMPERATURA] > SOGLIA_TEMPERATURA) {
|
|
|
|
|
|
codice_allarme = SQUEOW_CODICE_TEMPERATURA;
|
|
|
|
|
|
blocco = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef SQUEOW_SONDA_DIRETTA
|
|
|
|
|
|
if (adc_valori[SQUEOW_ADC_DIRETTA] > SOGLIA_DIRETTA) {
|
|
|
|
|
|
codice_allarme = SQUEOW_CODICE_DIRETTA;
|
|
|
|
|
|
blocco = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef SQUEOW_SONDA_RIFLESSA
|
|
|
|
|
|
if (adc_valori[SQUEOW_ADC_RIFLESSA] > SOGLIA_RIFLESSA) {
|
|
|
|
|
|
codice_allarme = SQUEOW_CODICE_RIFLESSA;
|
|
|
|
|
|
blocco = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2025-01-28 19:01:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
void processa_blocco(void) {
|
|
|
|
|
|
static uint8_t vecchio_stato_blocco;
|
|
|
|
|
|
static uint16_t timer_blocco;
|
|
|
|
|
|
|
|
|
|
|
|
// è appena stato impostato blocco
|
|
|
|
|
|
if (blocco && !vecchio_stato_blocco) {
|
|
|
|
|
|
// è appena stato impostato blocco
|
|
|
|
|
|
#ifdef SQUEOW_UI_SERIOW
|
|
|
|
|
|
seriow_log('E', "LOCK!");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef SQUEOW_UI_TOSTA
|
|
|
|
|
|
tosta_log('E', "LOCK!");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef MODALITA_BLOCCO_PERMANENTE
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef MODALITA_BLOCCO_BASSA_POTENZA
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef MODALITA_BLOCCO_TEMPORANEO
|
|
|
|
|
|
timer_blocco = 0;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
vecchio_stato_blocco = blocco;
|
|
|
|
|
|
} else if (!blocco && vecchio_stato_blocco) {
|
|
|
|
|
|
// è appena stato disinserito il blocco
|
|
|
|
|
|
#ifdef SQUEOW_UI_SERIOW
|
|
|
|
|
|
seriow_log('I', "UNLOCK");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef SQUEOW_UI_TOSTA
|
|
|
|
|
|
tosta_log('I', "UNLOCK");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
codice_allarme = 0;
|
|
|
|
|
|
led_blocco(codice_allarme);
|
|
|
|
|
|
vecchio_stato_blocco = blocco;
|
|
|
|
|
|
}
|
2025-01-28 19:01:22 +01:00
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
#ifdef MODALITA_BLOCCO_TEMPORANEO
|
|
|
|
|
|
else {
|
|
|
|
|
|
// solo temporaneo
|
|
|
|
|
|
if (timer_blocco > TEMPO_BLOCCO_TEMPORANEO) {
|
|
|
|
|
|
timer_blocco = 0;
|
|
|
|
|
|
blocco = 0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
timer_blocco++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
2025-01-28 19:01:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// synth
|
|
|
|
|
|
|
|
|
|
|
|
void squeow_synth_init(void) {
|
2025-06-28 00:58:29 +02:00
|
|
|
|
// occhio che blocca!
|
|
|
|
|
|
#ifdef SQUEOW_UI_SERIOW
|
|
|
|
|
|
seriow_log('I', "synth init");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SQUEOW_UI_TOSTA
|
|
|
|
|
|
tosta_log('I', "synth init");
|
|
|
|
|
|
#endif
|
2025-01-28 19:01:22 +01:00
|
|
|
|
si5351_initialize();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-28 00:58:29 +02:00
|
|
|
|
void squeow_synth_set(uint32_t freq) {
|
|
|
|
|
|
#ifdef SQUEOW_UI_SERIOW
|
|
|
|
|
|
// seriow_log('I', "synth set freq");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SQUEOW_UI_TOSTA
|
|
|
|
|
|
// tosta_log('I', "synth set freq");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
si5351_set_frequency(freq, 0);
|
|
|
|
|
|
si5351_set_frequency(freq, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void squeow_synth_on(void) {
|
2025-06-28 00:58:29 +02:00
|
|
|
|
#ifdef SQUEOW_UI_SERIOW
|
|
|
|
|
|
seriow_log('I', "synth on");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SQUEOW_UI_TOSTA
|
|
|
|
|
|
tosta_log('I', "synth on");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
si5351_on_clk(0);
|
|
|
|
|
|
si5351_on_clk(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void squeow_synth_off(void) {
|
2025-06-28 00:58:29 +02:00
|
|
|
|
#ifdef SQUEOW_UI_SERIOW
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SQUEOW_UI_TOSTA
|
|
|
|
|
|
tosta_log('I', "synth off");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2025-01-28 19:01:22 +01:00
|
|
|
|
si5351_off_clk(0);
|
|
|
|
|
|
si5351_off_clk(1);
|
2023-07-02 17:09:41 +02:00
|
|
|
|
}
|
2025-06-28 00:58:29 +02:00
|
|
|
|
|
|
|
|
|
|
void i2c_write8(I2C_HandleTypeDef handler, uint8_t address, uint8_t reg, uint8_t value) {
|
|
|
|
|
|
while (HAL_I2C_IsDeviceReady(&handler, (uint16_t)(address << 1), 3, 100) != HAL_OK) {
|
|
|
|
|
|
}
|
|
|
|
|
|
HAL_I2C_Mem_Write(&handler, (uint8_t)(address << 1), (uint8_t)reg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)(&value), 1, 100);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t i2c_read8(I2C_HandleTypeDef handler, uint8_t address, uint8_t reg, uint8_t *value) {
|
|
|
|
|
|
HAL_StatusTypeDef status = HAL_OK;
|
|
|
|
|
|
while (HAL_I2C_IsDeviceReady(&handler, (uint16_t)(address << 1), 3, 100) != HAL_OK) {
|
|
|
|
|
|
}
|
|
|
|
|
|
status = HAL_I2C_Mem_Read(&handler, // i2c handle
|
|
|
|
|
|
(uint8_t)(address << 1), // i2c address, left aligned
|
|
|
|
|
|
(uint8_t)reg, // register address
|
|
|
|
|
|
I2C_MEMADD_SIZE_8BIT, // 8bit register addresses
|
|
|
|
|
|
(uint8_t *)(&value), // write returned data to this variable
|
|
|
|
|
|
1, // how many bytes to expect returned
|
|
|
|
|
|
100); // timeout
|
|
|
|
|
|
return status;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void si5351_write8(uint8_t reg, uint8_t value) { i2c_write8(hi2c1, SI5351_ADDRESS, reg, value); }
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t si5351_read8(uint8_t reg, uint8_t *value) { return i2c_read8(hi2c1, SI5351_ADDRESS, reg, value); }
|